KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > psibt > framework > net > PluggableHTTPServer


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.psibt.framework.net;
17
18 import java.net.*;
19 import java.io.*;
20 import java.util.*;
21 import org.apache.log4j.*;
22
23 /**
24  * This class implements a HTTP-server frame. All HTTP-requests are handled by HTTPRequestHandler
25  * classes which implement the <code>HTTPRequestHandler</code> interface. Every RequestHandler has
26  * to be registered in the PluggableHTTPServer with the <code>addRequestHandler</code> method.
27  * A new thread is created for each connection to handle the request. If all reply data are sent
28  * to the client the connection is closed and the thread ends.
29  * An example how to use the PluggableHTTPServer class can be found in the <code>main</code> method
30  * at the end of the source file.
31  *
32  * @author <a HREF="mailto:V.Mentzner@psi-bt.de">Volker Mentzner</a>
33  */

34 public class PluggableHTTPServer implements Runnable JavaDoc {
35
36   public static final int DEFAULT_PORT = 80;
37   static Category cat = Category.getInstance("PluggableHTTPServer");
38   private int port;
39   private Vector handler;
40   private ServerSocket server;
41
42   /**
43    * Creates a new server object on the given TCP port.
44    * If the port is occupied by another process a IOException (java.net.BindException) is thrown.
45    *
46    * @param port - TCP port number to listen on for requests
47    */

48   public PluggableHTTPServer(int port) throws IOException {
49     this.port = port;
50     this.handler = new Vector();
51     cat.setPriority(Priority.ERROR);
52     server = new ServerSocket(this.port);
53   }
54
55   /**
56    * Creates a new server object on the default TCP port 80
57    * If the port is occupied by another process a IOException (java.net.BindException) is thrown.
58    */

59   public PluggableHTTPServer() throws IOException {
60     this(DEFAULT_PORT);
61   }
62
63   /**
64    * Registers the given HTTPRequestHandler
65    *
66    * @param h - the HTTPRequestHandler to register
67    */

68   public void addRequestHandler(HTTPRequestHandler h) {
69     handler.add(h);
70   }
71
72   /**
73    * Unregisters the given HTTPRequestHandler
74    *
75    * @param h - the HTTPRequestHandler to unregister
76    */

77   public void removeRequestHandler(HTTPRequestHandler h) {
78     handler.remove(h);
79   }
80
81   /**
82    * Sends the HTTP message 404 - File Not Found
83    * see RFC2616 for details
84    *
85    * @param out - Out stream for sending data to client browser
86    */

87   public static void replyNotFound(Writer out) {
88     try {
89       out.write("HTTP/1.0 404 Not Found\r\n");
90       out.write("<HTML><HEAD><TITLE>Not Found</TITLE></HEAD>\r\n");
91       out.write("<BODY><H1>Not Found</H1>\r\n");
92       out.write("</BODY></HTML>\r\n");
93       out.flush();
94     } // end try
95
catch (IOException e) {
96     }
97   }
98
99   /**
100    * Sends the HTTP message 405 - Method Not Allowed
101    * see RFC2616 for details
102    *
103    * @param out - Out stream for sending data to client browser
104    */

105   public static void replyMethodNotAllowed(Writer out) {
106     try {
107       out.write("HTTP/1.1 405 Method Not Allowed\r\n");
108       out.write("Allow: GET, PUT\r\n");
109       out.write("<HTML><HEAD><TITLE>Method Not Allowed</TITLE></HEAD>\r\n");
110       out.write("<BODY><H1>Method Not Allowed</H1>\r\n");
111       out.write("</BODY></HTML>\r\n");
112       out.flush();
113     } // end try
114
catch (IOException e) {
115     }
116   }
117
118   /**
119    * Creates the ReplyHTML data for the root page
120    *
121    * @param index - index of the RootRequestHandler
122    */

123   public void autoCreateRootPage(int index) {
124     if (handler.get(index) instanceof RootRequestHandler) {
125       RootRequestHandler r = (RootRequestHandler)handler.get(index);
126       String JavaDoc html = "<HTML><HEAD><TITLE>"+r.getTitle()+"</TITLE></HEAD>\r\n";
127       html = html + "<BODY><H1>"+r.getDescription()+"</H1>\r\n";
128       for (int i = 0; i < handler.size(); i++) {
129         html = html + "<a HREF=\"" + ((HTTPRequestHandler)handler.get(i)).getHandledPath();
130         html = html + "\">" + ((HTTPRequestHandler)handler.get(i)).getDescription() + "</a><br>";
131       }
132       html = html + "</BODY></HTML>\r\n";
133       r.setReplyHTML(html);
134     }
135   }
136
137   /**
138    * Main loop of the PluggableHTTPServer
139    */

140   public void run() {
141     while (true) {
142       try {
143         Socket s = server.accept();
144         Thread JavaDoc t = new ServerThread(s);
145         t.start();
146       }
147       catch (IOException e) {
148       }
149     }
150   }
151
152   /**
153    * This class handles the incomming connection for one request.
154    */

155   class ServerThread extends Thread JavaDoc {
156
157     private Socket connection;
158
159     ServerThread(Socket s) {
160       this.connection = s;
161     }
162
163     /**
164      * Serves the HTTP request.
165      */

166     public void run() {
167       try {
168         Writer out = new BufferedWriter(
169                       new OutputStreamWriter(
170                        connection.getOutputStream(), "ASCII"
171                       )
172                      );
173         Reader in = new InputStreamReader(
174                      new BufferedInputStream(
175                       connection.getInputStream()
176                      )
177                     );
178
179         // read the first line only; that's all we need
180
StringBuffer JavaDoc req = new StringBuffer JavaDoc(80);
181         while (true) {
182           int c = in.read();
183           if (c == '\r' || c == '\n' || c == -1) break;
184           req.append((char) c);
185         }
186         String JavaDoc get = req.toString();
187         cat.debug(get);
188         StringTokenizer st = new StringTokenizer(get);
189         String JavaDoc method = st.nextToken();
190         String JavaDoc request = st.nextToken();
191         String JavaDoc version = st.nextToken();
192
193         if (method.equalsIgnoreCase("GET")) {
194           boolean served = false;
195           for (int i = 0; i < handler.size(); i++) {
196             if (handler.get(i) instanceof HTTPRequestHandler) {
197               if (((HTTPRequestHandler)handler.get(i)).handleRequest(request, out)) {
198                 served = true;
199                 break;
200               }
201             }
202           }
203           if (!served)
204             PluggableHTTPServer.replyNotFound(out);
205         }
206         else {
207           PluggableHTTPServer.replyMethodNotAllowed(out);
208         }
209       } // end try
210
catch (IOException e) {
211       }
212       finally {
213         try {
214           if (connection != null) connection.close();
215         }
216         catch (IOException e) {}
217       }
218     } // end run
219
} // end class ServerThread
220

221   /**
222    * Demo how to use the PluggableHTTPServer.
223    */

224   public static void main(String JavaDoc[] args) {
225
226     int thePort;
227
228     // create some logging stuff
229
BasicConfigurator.configure();
230     Category cat1 = Category.getInstance("cat1");
231     cat1.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%m%n")));
232     Category cat2 = Category.getInstance("cat2");
233     cat2.setPriority(Priority.INFO);
234     cat2.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%c - %m%n")));
235
236     // set TCP port number
237
try {
238       thePort = Integer.parseInt(args[1]);
239     }
240     catch (Exception JavaDoc e) {
241       thePort = PluggableHTTPServer.DEFAULT_PORT;
242     }
243
244     PluggableHTTPServer server = null;
245     while (server == null) {
246       try {
247         server = new PluggableHTTPServer(thePort);
248         server.addRequestHandler(new RootRequestHandler());
249         server.addRequestHandler(new Log4jRequestHandler());
250         server.addRequestHandler(new UserDialogRequestHandler());
251         server.autoCreateRootPage(0);
252         Thread JavaDoc t = new Thread JavaDoc(server);
253         t.start();
254       } catch (IOException e) {
255         server = null;
256         thePort++;
257       }
258     }
259
260   } // end main
261
}
262
Popular Tags