4 import java.lang.reflect.*;
6 import java.util.function.*;
9 import java.nio.channels.*;
11 public class Bootstrap {
12 private static InetSocketAddress resolveinaddr(String spec) {
13 int p = spec.indexOf(':');
18 if(spec.charAt(0) == '[') {
19 p = spec.indexOf(']');
20 if((p < 0) || (spec.charAt(p + 1) != ':'))
21 throw(new IllegalArgumentException("invalid address syntax: " + spec));
22 host = InetAddress.getByName(spec.substring(1, p));
25 host = InetAddress.getByName(spec.substring(0, p));
27 } catch(UnknownHostException e) {
28 throw(new IllegalArgumentException("could not resolve inet host: " + spec, e));
31 return(new InetSocketAddress(host, Integer.parseInt(spec.substring(p + 1))));
32 } catch(NumberFormatException e) {
33 throw(new IllegalArgumentException("not a valid port number: " + spec.substring(p + 1), e));
37 return(new InetSocketAddress(Integer.parseInt(spec)));
38 } catch(NumberFormatException e) {
39 throw(new IllegalArgumentException("not a valid port number: " + spec, e));
44 private static ServerSocketChannel tcplisten(String spec) {
47 bind = resolveinaddr(spec);
48 } catch(IllegalArgumentException e) {
49 System.err.println("scgi-jagi: " + e.getMessage());
54 ServerSocketChannel sk = ServerSocketChannel.open();
57 } catch(IOException e) {
58 System.err.println("scgi-jagi: could not create TCP socket: " + e.getMessage());
64 private static ServerSocketChannel getstdin() {
67 stdin = System.inheritedChannel();
68 } catch(IOException e) {
69 System.err.println("scgi-jagi: could not get stdin channel: " + e.getMessage());
73 if(!(stdin instanceof ServerSocketChannel)) {
74 System.err.println("scgi-jagi: stdin is not a listening socket");
78 return((ServerSocketChannel)stdin);
81 private static Function gethandler(ClassLoader loader, String nm, String... args) {
84 cl = loader.loadClass(nm);
85 } catch(ClassNotFoundException e) {
87 cl = loader.loadClass(nm + ".Bootstrap");
88 } catch(ClassNotFoundException e2) {
89 System.err.println("scgi-jagi: could not find handler class or package: " + nm);
96 wmain = cl.getDeclaredMethod("wmain", String[].class);
97 int mod = wmain.getModifiers();
98 if(((mod & Modifier.STATIC) == 0) || ((mod & Modifier.PUBLIC) == 0))
99 throw(new NoSuchMethodException());
100 } catch(NoSuchMethodException e) {
101 System.err.println("scgi-jagi: could not find wmain method in " + cl.getName());
107 handler = wmain.invoke(null, new Object[] {args});
108 } catch(IllegalAccessException e) {
109 System.err.println("scgi-jagi: could not call wmain in " + cl.getName());
112 } catch(InvocationTargetException e) {
113 System.err.println("scgi-jagi: wmain in " + cl.getName() + " failed");
114 e.printStackTrace(System.err);
118 if(!(handler instanceof Function)) {
119 System.err.println("scgi-jagi: wmain in " + cl.getName() + " returned " + ((handler == null) ? "null" : ("a " + handler.getClass())));
123 return((Function)handler);
126 private static void usage(PrintStream out) {
127 out.println("usage: jagi.jar [-h] [-T [HOST:]PORT] HANDLER-CLASS [ARGS...]");
130 public static void main(String[] args) {
131 PosixArgs opt = PosixArgs.getopt(args, "hT:");
137 String tcpspec = null;
138 ClassLoader loader = Bootstrap.class.getClassLoader();
139 for(char c : opt.parsed()) {
150 if(opt.rest.length < 1) {
155 Function handler = gethandler(loader, opt.rest[0], Arrays.copyOfRange(opt.rest, 1, opt.rest.length));
156 ServerSocketChannel sk;
157 if(tcpspec != null) {
158 sk = tcplisten(tcpspec);
162 Runnable server = new EventServer(sk, handler);
165 } catch(Throwable e) {
166 System.err.println("scgi-jagi: server exited abnormally");