/** * 'handler' can be of any type that implements 'exportedInterface', but only methods declared by * the interface (and its superinterfaces) will be invocable. */ public <T> InAppServer( String name, String portFilename, InetAddress inetAddress, Class<T> exportedInterface, T handler) { this.fullName = name + "Server"; this.exportedInterface = exportedInterface; this.handler = handler; // In the absence of authentication, we shouldn't risk starting a server as root. if (System.getProperty("user.name").equals("root")) { Log.warn( "InAppServer: refusing to start unauthenticated server \"" + fullName + "\" as root!"); return; } try { File portFile = FileUtilities.fileFromString(portFilename); secretFile = new File(portFile.getPath() + ".secret"); Thread serverThread = new Thread(new ConnectionAccepter(portFile, inetAddress), fullName); // If there are no other threads left, the InApp server shouldn't keep us alive. serverThread.setDaemon(true); serverThread.start(); } catch (Throwable th) { Log.warn("InAppServer: couldn't start \"" + fullName + "\".", th); } writeNewSecret(); }
private void closeClientSocket() { try { client.close(); } catch (IOException ex) { Log.warn(Thread.currentThread().getName() + ": failed to close client socket.", ex); } }
private void writeHostAndPortToFile(File portFile) { String host = socket.getInetAddress().getHostName(); int port = socket.getLocalPort(); // The motivation for the Log.warn would be better satisfied by Bug 38. Log.warn("echo " + host + ":" + port + " > " + portFile); StringUtilities.writeFile(portFile, host + ":" + port + "\n"); }
private void acceptConnections() { for (; ; ) { try { String handlerName = fullName + "-Handler-" + Thread.activeCount(); new Thread(new ClientHandler(socket.accept()), handlerName).start(); } catch (Exception ex) { Log.warn(fullName + ": exception accepting connection.", ex); } } }
private void handleRequest() throws IOException { String line = in.readLine(); if (line == null || line.length() == 0) { Log.warn(Thread.currentThread().getName() + ": ignoring empty request."); return; } if (handleCommand(line, out) == false) { out.println( Thread.currentThread().getName() + ": didn't understand request \"" + line + "\"."); } }
private boolean authenticateClient() throws IOException { String line = in.readLine(); if (line == null || line.equals(secret) == false) { Log.warn( Thread.currentThread().getName() + ": failed authentication attempt with \"" + line + "\"."); out.println("Authentication failed"); return false; } writeNewSecret(); out.println("Authentication OK"); return true; }
private void handleClient() { try { this.in = new BufferedReader(new InputStreamReader(client.getInputStream())); this.out = new PrintWriter(new OutputStreamWriter(client.getOutputStream())); if (authenticateClient()) { handleRequest(); } out.flush(); out.close(); in.close(); } catch (Exception ex) { Log.warn(Thread.currentThread().getName() + ": failure handling client request.", ex); } finally { closeClientSocket(); } }
public boolean handleCommand(String line, PrintWriter out) { String[] split = line.split("[\t ]"); String commandName = split[0]; try { Method[] methods = exportedInterface.getMethods(); for (Method method : methods) { if (method.getName().equals(commandName) && method.getReturnType() == void.class) { return invokeMethod(line, out, method, split); } } throw new NoSuchMethodException(); } catch (NoSuchMethodException nsmex) { out.println(fullName + ": didn't understand request \"" + line + "\"."); } catch (Exception ex) { Log.warn(fullName + ": exception thrown while handling command \"" + line + "\".", ex); out.println(fullName + ": request denied \"" + line + "\" (" + ex.toString() + ")."); } finally { out.flush(); out.close(); } return false; }