You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-cvs@jakarta.apache.org by ce...@apache.org on 2001/05/19 22:42:50 UTC

cvs commit: jakarta-log4j/contribs/VolkerMentzner HTTPRequestHandler.java Log4jRequestHandler.java PluggableHTTPServer.java RootRequestHandler.java UserDialogRequestHandler.java mail-03-05-2001

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:V.Mentzner@psi-bt.de">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:V.Mentzner@psi-bt.de">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:V.Mentzner@psi-bt.de">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:V.Mentzner@psi-bt.de">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:V.Mentzner@psi-bt.de">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: cgu@qos.ch 
  From: "Mentzner, Volker" <V....@PSI-BT.de> 
  To: "'cgu@qos.ch'" <cg...@qos.ch> 
  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: log4j-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-cvs-help@jakarta.apache.org