ceki 01/05/19 13:42:50 Added: contribs/VolkerMentzner HTTPRequestHandler.java Log4jRequestHandler.java PluggableHTTPServer.java RootRequestHandler.java UserDialogRequestHandler.java mail-03-05-2001 Log: Added Volker Metzner's pluggable server. Revision Changes Path 1.1 jakarta-log4j/contribs/VolkerMentzner/HTTPRequestHandler.java Index: HTTPRequestHandler.java =================================================================== package com.psibt.framework.net; import java.io.*; import java.net.*; /** * This interface defines all methods that have to be implemented for a HTTPRequestHandler for the * PluggableHTTPServer. * * @author <a HREF="mailto:[EMAIL PROTECTED]">Volker Mentzner</a> */ public interface HTTPRequestHandler { /** * Gets the title for html page */ public String getTitle(); /** * Sets the title for html page */ public void setTitle(String title); /** * Gets the description for html page */ public String getDescription(); /** * Sets the description for html page */ public void setDescription(String description); /** * Gets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler. * So the root path handler will return "/" (without brackets) because it handles the path * "http://servername/" or a handler for "http://servername/somepath/" will return "/somepath/" * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path! */ public String getHandledPath(); /** * Sets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler. * So set the path to "/" for the root path handler because it handles the path * "http://servername/" or set it to "/somepath/" for a handler for "http://servername/somepath/". * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path! */ public void setHandledPath(String path); /** * Handles the given request and writes the reply to the given out-stream. Every handler has to check * the request for the right path info. * * @param request - client browser request * @param out - Out stream for sending data to client browser * @return if the request was handled by this handler : true, else : false */ public boolean handleRequest(String request, Writer out); } 1.1 jakarta-log4j/contribs/VolkerMentzner/Log4jRequestHandler.java Index: Log4jRequestHandler.java =================================================================== package com.psibt.framework.net; import java.io.*; import java.net.*; import java.util.*; import org.apache.log4j.*; /** * This class implements a RequestHandler for log4j configuration. It serves the "/log4j/" path * in the PluggableHTTPServer. If this path is requested a list of all current log4j categories * with their current priorities is created. All priority settings can be changed by the user * and can be submitted and taken over. * * @author <a HREF="mailto:[EMAIL PROTECTED]">Volker Mentzner</a> */ public class Log4jRequestHandler extends RootRequestHandler { private Priority[] prios = Priority.getAllPossiblePriorities(); /** * Creates a new Log4jRequestHandler object */ public Log4jRequestHandler() { this.setTitle("log4j"); this.setDescription("log4j configuration"); this.setHandledPath("/log4j/"); } /** * Handles the given request and writes the reply to the given out-stream. * * @param request - client browser request * @param out - Out stream for sending data to client browser * @return if the request was handled by this handler : true, else : false */ public boolean handleRequest(String request, Writer out) { String path = ""; String query = null; String name; try { // check request url URL url = new URL("http://localhost"+request); path = url.getPath(); query = url.getQuery(); if (path.startsWith(this.getHandledPath()) == false) { return false; } out.write("HTTP/1.0 200 OK\r\n"); out.write("Content-type: text/html\r\n\r\n"); out.write("<HTML><HEAD><TITLE>" + this.getTitle() + "</TITLE></HEAD>\r\n"); out.write("<BODY><H1>log4j</H1>\r\n"); out.write(this.getDescription() + "<br><br>\r\n"); // handle a request with query if ((query != null) && (query.length() >= 0)) { StringTokenizer st = new StringTokenizer(query, "&"); String cmd; String catname; String catval; int idx; while (st.hasMoreTokens()) { cmd = st.nextToken(); idx = cmd.indexOf("="); catname = cmd.substring(0, idx); catval = cmd.substring(idx+1, cmd.length()); if (catname.equalsIgnoreCase("root")) Category.getRoot().setPriority(Priority.toPriority(catval)); else Category.getInstance(catname).setPriority(Priority.toPriority(catval)); } } // output category information in a form with a simple table out.write("<form name=\"Formular\" ACTION=\""+this.getHandledPath()+"\" METHOD=\"PUT\">"); out.write("<table cellpadding=4>\r\n"); out.write(" <tr>\r\n"); out.write(" <td><b>Category</b></td>\r\n"); out.write(" <td><b>Priority</b></td>\r\n"); out.write(" <td><b>Appender</b></td>\r\n"); out.write(" </tr>\r\n"); // output for root category Category cat = Category.getRoot(); out.write(" <tr><td>root</td>\r\n"); out.write(" <td>\r\n"); out.write(" <select size=1 name=\""+ cat.getName() +"\">"); for (int i = 0; i < prios.length; i++) { if (cat.getChainedPriority().toString().equals(prios[i].toString())) out.write("<option selected>"+prios[i].toString()); else out.write("<option>"+prios[i].toString()); } out.write("</select>\r\n"); out.write(" </td>\r\n"); out.write(" <td>\r\n"); for (Enumeration apds = cat.getAllAppenders(); apds.hasMoreElements();) { Appender apd = (Appender)apds.nextElement(); name = apd.getName(); if (name == null) name = "<i>(no name)</i>"; out.write(name); if (apd instanceof AppenderSkeleton) { try { AppenderSkeleton apskel = (AppenderSkeleton)apd; out.write(" [" + apskel.getThreshold().toString() + "]"); } catch (Exception ex) { } } if (apds.hasMoreElements()) out.write(", "); } out.write(" </td>\r\n"); out.write(" </tr>\r\n"); // output for all other categories for (Enumeration en = Category.getCurrentCategories(); en.hasMoreElements();) { cat = (Category)en.nextElement(); out.write(" <tr>\r\n"); out.write(" <td>" + cat.getName() + "</td>\r\n"); out.write(" <td>\r\n"); out.write(" <select size=1 name=\""+ cat.getName() +"\">"); for (int i = 0; i < prios.length; i++) { if (cat.getChainedPriority().toString().equals(prios[i].toString())) out.write("<option selected>"+prios[i].toString()); else out.write("<option>"+prios[i].toString()); } out.write("</select>\r\n"); out.write(" </td>\r\n"); out.write(" <td>\r\n"); for (Enumeration apds = cat.getAllAppenders(); apds.hasMoreElements();) { Appender apd = (Appender)apds.nextElement(); name = apd.getName(); if (name == null) name = "<i>(no name)</i>"; out.write(name); if (apd instanceof AppenderSkeleton) { try { AppenderSkeleton apskel = (AppenderSkeleton)apd; out.write(" [" + apskel.getThreshold().toString() + "]"); } catch (Exception ex) { } } if (apds.hasMoreElements()) out.write(", "); } out.write(" </td>\r\n"); out.write(" </tr>\r\n"); } out.write("</table>\r\n"); out.write("<input type=submit value=\"Submit\">"); out.write("</form>"); out.write("</BODY></HTML>\r\n"); out.flush(); return true; } catch (Exception ex) { return false; } } } 1.1 jakarta-log4j/contribs/VolkerMentzner/PluggableHTTPServer.java Index: PluggableHTTPServer.java =================================================================== package com.psibt.framework.net; import java.net.*; import java.io.*; import java.util.*; import org.apache.log4j.*; /** * This class implements a HTTP-server frame. All HTTP-requests are handled by HTTPRequestHandler * classes which implement the <code>HTTPRequestHandler</code> interface. Every RequestHandler has * to be registered in the PluggableHTTPServer with the <code>addRequestHandler</code> method. * A new thread is created for each connection to handle the request. If all reply data are sent * to the client the connection is closed and the thread ends. * An example how to use the PluggableHTTPServer class can be found in the <code>main</code> method * at the end of the source file. * * @author <a HREF="mailto:[EMAIL PROTECTED]">Volker Mentzner</a> */ public class PluggableHTTPServer implements Runnable { public static final int DEFAULT_PORT = 80; static Category cat = Category.getInstance("PluggableHTTPServer"); private int port; private Vector handler; private ServerSocket server; /** * Creates a new server object on the given TCP port. * If the port is occupied by another process a IOException (java.net.BindException) is thrown. * * @param port - TCP port number to listen on for requests */ public PluggableHTTPServer(int port) throws IOException { this.port = port; this.handler = new Vector(); cat.setPriority(Priority.ERROR); server = new ServerSocket(this.port); } /** * Creates a new server object on the default TCP port 80 * If the port is occupied by another process a IOException (java.net.BindException) is thrown. */ public PluggableHTTPServer() throws IOException { this(DEFAULT_PORT); } /** * Registers the given HTTPRequestHandler * * @param h - the HTTPRequestHandler to register */ public void addRequestHandler(HTTPRequestHandler h) { handler.add(h); } /** * Unregisters the given HTTPRequestHandler * * @param h - the HTTPRequestHandler to unregister */ public void removeRequestHandler(HTTPRequestHandler h) { handler.remove(h); } /** * Sends the HTTP message 404 - File Not Found * see RFC2616 for details * * @param out - Out stream for sending data to client browser */ public static void replyNotFound(Writer out) { try { out.write("HTTP/1.0 404 Not Found\r\n"); out.write("<HTML><HEAD><TITLE>Not Found</TITLE></HEAD>\r\n"); out.write("<BODY><H1>Not Found</H1>\r\n"); out.write("</BODY></HTML>\r\n"); out.flush(); } // end try catch (IOException e) { } } /** * Sends the HTTP message 405 - Method Not Allowed * see RFC2616 for details * * @param out - Out stream for sending data to client browser */ public static void replyMethodNotAllowed(Writer out) { try { out.write("HTTP/1.1 405 Method Not Allowed\r\n"); out.write("Allow: GET, PUT\r\n"); out.write("<HTML><HEAD><TITLE>Method Not Allowed</TITLE></HEAD>\r\n"); out.write("<BODY><H1>Method Not Allowed</H1>\r\n"); out.write("</BODY></HTML>\r\n"); out.flush(); } // end try catch (IOException e) { } } /** * Creates the ReplyHTML data for the root page * * @param index - index of the RootRequestHandler */ public void autoCreateRootPage(int index) { if (handler.get(index) instanceof RootRequestHandler) { RootRequestHandler r = (RootRequestHandler)handler.get(index); String html = "<HTML><HEAD><TITLE>"+r.getTitle()+"</TITLE></HEAD>\r\n"; html = html + "<BODY><H1>"+r.getDescription()+"</H1>\r\n"; for (int i = 0; i < handler.size(); i++) { html = html + "<a href=\"" + ((HTTPRequestHandler)handler.get(i)).getHandledPath(); html = html + "\">" + ((HTTPRequestHandler)handler.get(i)).getDescription() + "</a><br>"; } html = html + "</BODY></HTML>\r\n"; r.setReplyHTML(html); } } /** * Main loop of the PluggableHTTPServer */ public void run() { while (true) { try { Socket s = server.accept(); Thread t = new ServerThread(s); t.start(); } catch (IOException e) { } } } /** * This class handles the incomming connection for one request. */ class ServerThread extends Thread { private Socket connection; ServerThread(Socket s) { this.connection = s; } /** * Serves the HTTP request. */ public void run() { try { Writer out = new BufferedWriter( new OutputStreamWriter( connection.getOutputStream(), "ASCII" ) ); Reader in = new InputStreamReader( new BufferedInputStream( connection.getInputStream() ) ); // read the first line only; that's all we need StringBuffer req = new StringBuffer(80); while (true) { int c = in.read(); if (c == '\r' || c == '\n' || c == -1) break; req.append((char) c); } String get = req.toString(); cat.debug(get); StringTokenizer st = new StringTokenizer(get); String method = st.nextToken(); String request = st.nextToken(); String version = st.nextToken(); if (method.equalsIgnoreCase("GET")) { boolean served = false; for (int i = 0; i < handler.size(); i++) { if (handler.get(i) instanceof HTTPRequestHandler) { if (((HTTPRequestHandler)handler.get(i)).handleRequest(request, out)) { served = true; break; } } } if (!served) PluggableHTTPServer.replyNotFound(out); } else { PluggableHTTPServer.replyMethodNotAllowed(out); } } // end try catch (IOException e) { } finally { try { if (connection != null) connection.close(); } catch (IOException e) {} } } // end run } // end class ServerThread /** * Demo how to use the PluggableHTTPServer. */ public static void main(String[] args) { int thePort; // create some logging stuff BasicConfigurator.configure(); Category cat1 = Category.getInstance("cat1"); cat1.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%m%n"))); Category cat2 = Category.getInstance("cat2"); cat2.setPriority(Priority.INFO); cat2.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%c - %m%n"))); // set TCP port number try { thePort = Integer.parseInt(args[1]); } catch (Exception e) { thePort = PluggableHTTPServer.DEFAULT_PORT; } PluggableHTTPServer server = null; while (server == null) { try { server = new PluggableHTTPServer(thePort); server.addRequestHandler(new RootRequestHandler()); server.addRequestHandler(new Log4jRequestHandler()); server.addRequestHandler(new UserDialogRequestHandler()); server.autoCreateRootPage(0); Thread t = new Thread(server); t.start(); } catch (IOException e) { server = null; thePort++; } } } // end main } 1.1 jakarta-log4j/contribs/VolkerMentzner/RootRequestHandler.java Index: RootRequestHandler.java =================================================================== package com.psibt.framework.net; import java.io.*; import java.net.*; import java.util.*; /** * This class implements a RequestHandler for the root path "/" in the PluggableHTTPServer. * A simple HTML message will be replied to the client. * * @author <a HREF="mailto:[EMAIL PROTECTED]">Volker Mentzner</a> */ public class RootRequestHandler implements HTTPRequestHandler { private String title; private String description; private String handledPath; private String ReplyType = "Content-type: text/html\r\n\r\n"; private String ReplyHTML = "<HTML><HEAD><TITLE>Root</TITLE></HEAD>\r\n" + "<BODY><H1>Root</H1>\r\n" + "</BODY></HTML>\r\n"; /** * Creates a new RootRequestHandler object */ public RootRequestHandler() { this.setTitle("root page"); this.setDescription("root page"); this.setHandledPath("/"); } /** * Gets the content type of the reply HTTP message * * @return content type as String */ public String getReplyType() { return this.ReplyType; } /** * Sets the content type of the reply HTTP message * * @param ReplyType - content type as String */ public void setReplyType(String ReplyType) { this.ReplyType = ReplyType; } /** * Gets the HTML data of the reply HTTP message * * @return HTML message as String */ public String getReplyHTML() { return this.ReplyHTML; } /** * Sets the HTML data of the reply HTTP message * * @param ReplyHTML - HTML message as String */ public void setReplyHTML(String ReplyHTML) { this.ReplyHTML = ReplyHTML; } /** * Gets the title for html page */ public String getTitle() { return this.title; } /** * Sets the title for html page */ public void setTitle(String title) { this.title = title; } /** * Gets the description for html page */ public String getDescription() { return this.description; } /** * Sets the description for html page */ public void setDescription(String description) { this.description = description; } /** * Gets the server path * * @return the server path */ public String getHandledPath() { return this.handledPath; } /** * Sets the server path * * @param path - the server path */ public void setHandledPath(String path) { this.handledPath = path; } /** * Handles the given request and writes the reply to the given out-stream. * * @param request - client browser request * @param out - Out stream for sending data to client browser * @return if the request was handled by this handler : true, else : false */ public boolean handleRequest(String request, Writer out) { String path = ""; String query = null; try { URL url = new URL("http://localhost"+request); path = url.getPath(); query = url.getPath(); if (path.equals(handledPath) == false) { return false; } out.write("HTTP/1.0 200 OK\r\n"); if (ReplyType != null) out.write(ReplyType); if (ReplyHTML != null) out.write(ReplyHTML); out.flush(); return true; } catch (Exception ex) { return false; } } } 1.1 jakarta-log4j/contribs/VolkerMentzner/UserDialogRequestHandler.java Index: UserDialogRequestHandler.java =================================================================== /** * Title: PSI Java Framework: UserDialogRequestHandler<p> * Copyright: PSI-BT AG<p> * History: * Date Author What's new * 16.04.2001 VMentzner Created */ package com.psibt.framework.net; /** * This class implements a RequestHandler for the path "/userdialog/" in the PluggableHTTPServer. * A simple input form is presented in the browser where you can enter a message. This message will be sent * to the PluggableHTTPServer and shown in a JOptionPane MessageDialog. * * @author <a HREF="mailto:[EMAIL PROTECTED]">Volker Mentzner</a> */ public class UserDialogRequestHandler extends RootRequestHandler { private Component parentComponent; /** * Creates a new UserDialogRequestHandler object */ public UserDialogRequestHandler() { this(null); } /** * Creates a new UserDialogRequestHandler object with a parentComponent reference */ public UserDialogRequestHandler(Component parentComponent) { this.setTitle("user dialog"); this.setDescription("show user dialog"); this.setHandledPath("/userdialog/"); this.parentComponent = parentComponent; } /** * Handles the given request and writes the reply to the given out-stream. * * @param request - client browser request * @param out - Out stream for sending data to client browser * @return if the request was handled by this handler : true, else : false */ public boolean handleRequest(String request, Writer out) { String path = ""; String query = null; try { URL url = new URL("http://localhost"+request); path = url.getPath(); query = url.getQuery(); if (path.startsWith(this.getHandledPath()) == false) { return false; } out.write("HTTP/1.0 200 OK\r\n"); out.write("Content-type: text/html\r\n\r\n"); out.write("<HTML><HEAD><TITLE>" + this.getTitle() + "</TITLE></HEAD>\r\n"); out.write("<BODY><H1>" + this.getDescription() + "</H1>\r\n"); if ((query != null) && (query.length() >= 0)) { int idx = query.indexOf("="); String message = query.substring(idx+1, query.length()); // replace '+' by space message = message.replace('+', ' '); // replace hex strings starting with '%' by their values idx = message.indexOf("%"); while (idx >= 0) { String sl = message.substring(0, idx); String sm = message.substring(idx+1, idx+3); String sr = message.substring(idx+3, message.length()); try { int i = Integer.parseInt(sm, 16); sm = String.valueOf((char)i); } catch (Exception ex) { sm = ""; } message = sl + sm + sr; idx = message.indexOf("%"); } // show message in a new thread if ((message != null) && (message.length() > 0)) { Thread t = new Thread(new DialogThread(parentComponent, message)); t.start(); } } out.write("<form name=\"Formular\" ACTION=\""+this.getHandledPath()+"+\" METHOD=\"PUT\">"); out.write("<table>\r\n"); out.write(" <tr><td>Send message to user</td></tr>\r\n"); out.write(" <tr><td><textarea name=\"message\" rows=10 cols=50></textarea></td></tr>\r\n"); out.write("</table>\r\n"); out.write("<input type=submit value=\"Submit\">"); out.write("</form>"); out.write("</BODY></HTML>\r\n"); out.flush(); return true; } catch (Exception ex) { return false; } } /** * Internal class to start the user dialog in a new thread. This makes the RequestHandler return * immediatly */ class DialogThread implements Runnable { private Component parentComponent; private String message; public DialogThread(Component parentComponent, String message) { this.parentComponent = parentComponent; this.message = message; } public void run() { JOptionPane.showMessageDialog(parentComponent, message); } } } 1.1 jakarta-log4j/contribs/VolkerMentzner/mail-03-05-2001 Index: mail-03-05-2001 =================================================================== Delivered-To: [EMAIL PROTECTED] From: "Mentzner, Volker" <[EMAIL PROTECTED]> To: "'[EMAIL PROTECTED]'" <[EMAIL PROTECTED]> Subject: Remote configuring log4j Date: Thu, 3 May 2001 08:10:25 +0200 X-Mailer: Internet Mail Service (5.5.2653.19) Hi Ceki, I am using log4j in a GUI project. Working at the application I found it useful to remotely configure log4j with my favourite browser. This is reached by using a very small web server (PluggableHTTPServer) with extentions for tasks like configuring log4j. You can easily put this web server in an application, an example can be found in PluggableHTTPServer.main(). Maybe someone else can use this too, so I sent it to you to give it to the contrib dir if you like it. Regards Volker Mentzner <<pluggableServer.zip>> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]