ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/corbaservices/uk/org/iscream/cms/corbaservices/MiniWebServer.java
Revision: 1.8
Committed: Sat May 18 18:15:56 2002 UTC (22 years ago) by tdb
Branch: MAIN
Changes since 1.7: +21 -2 lines
Log Message:
i-scream is now licensed under the GPL. I've added the GPL headers to every
source file, and put a full copy of the license in the appropriate places.
I think I've covered everything. This is going to be a mad commit ;)

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * Copyright (C) 2000-2002 i-scream
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 //---PACKAGE DECLARATION---
21 package uk.org.iscream.cms.corbaservices;
22
23 //---IMPORTS---
24 import java.net.*;
25 import java.io.*;
26 import java.util.*;
27
28 /**
29 * MiniWebServer
30 *
31 * This provides a very basic webserver for serving IOR files.
32 * This could easily serve other text files, but not binaries.
33 *
34 * @author $Author: tdb $
35 * @version $Id: MiniWebServer.java,v 1.7 2002/04/05 11:54:35 tdb Exp $
36 */
37 public class MiniWebServer extends Thread {
38
39 //---FINAL ATTRIBUTES---
40
41 /**
42 * The current CVS revision of this class
43 */
44 public static final String REVISION = "$Revision: 1.7 $";
45
46 //---STATIC METHODS---
47
48 //---CONSTRUCTORS---
49
50 /**
51 * Construct a new MiniWebServer
52 *
53 * @param port The port to bind to
54 * @param okUrlsConfig The URL list config file
55 * @param webDir The web directory
56 */
57 public MiniWebServer(int port, String okUrlsConfig, String webDir) {
58 _port = port;
59 _okUrlsConfig = okUrlsConfig;
60 _webDir = webDir;
61 }
62
63 //---PUBLIC METHODS---
64
65 /**
66 * Main thread of execution. Keeps looping spawning off
67 * Handler's to deal with each client. This should keep
68 * going, and extra care has been taking with error
69 * catching.
70 */
71 public void run() {
72 // carry on forever
73 while(true) {
74 boolean run = true;
75 ServerSocket serverSocket = null;
76 try {
77 serverSocket = new ServerSocket(_port);
78 } catch (IOException e) {
79 run = false;
80 System.out.println(e);
81 e.printStackTrace();
82 }
83 while(run) {
84 try {
85 // get a new client and give it to a Handler
86 Socket socket = serverSocket.accept();
87 Handler handler = new Handler(socket);
88 handler.start();
89 } catch (IOException e) {
90 run=false;
91 System.out.println(e);
92 e.printStackTrace();
93 }
94 }
95 }
96 }
97
98 //---PRIVATE METHODS---
99
100 /**
101 * Reads a file in given an URL. Very basic, and has only
102 * been tested to work for URL's in the / directory.
103 *
104 * @param url The URL given to the webserver
105 * @return A String containing data from the file
106 */
107 private String readUrl(String url) {
108 // trim off the initial /
109 if(url.startsWith("/")) {
110 url = url.substring(1);
111 }
112 try {
113 // need to prefix with web directory
114 File file = new File(_webDir+"/"+url);
115 if(file.exists() && file.canRead()) {
116 // read in all the data
117 String data = "";
118 BufferedReader reader = new BufferedReader(new FileReader(file));
119 while(reader.ready()) {
120 String line = reader.readLine();
121 if(line != null) {
122 data += line + "\n";
123 }
124 }
125 return data;
126 }
127 else {
128 // return null if we can't read it
129 return null;
130 }
131 } catch (IOException e) {
132 System.out.println(e);
133 e.printStackTrace();
134 return null;
135 }
136 }
137
138 /**
139 * Checks if an URL is allowed. Failure of this method
140 * indicates a client should be sent a 403.
141 *
142 * @param url the url to check
143 * @return whether the url is permitted
144 */
145 private boolean okUrl(String url) {
146 // recheck the list - this means the list can be
147 // changed on the fly :)
148 readOkUrls();
149 Iterator i = _okUrls.iterator();
150 while(i.hasNext()) {
151 if(url.equals((String)i.next())) {
152 // matched url against our list
153 return true;
154 }
155 }
156 return false;
157 }
158
159 /**
160 * Reads the list of URLs into a list.
161 */
162 private void readOkUrls() {
163 File file = new File(_okUrlsConfig);
164 long lastMod = file.lastModified();
165 // only want to re-read the list if it's changed
166 if(lastMod > _okUrlsConfigStamp) {
167 _okUrlsConfigStamp = lastMod;
168 _okUrls = new LinkedList();
169 if(file.exists() && file.canRead()) {
170 try {
171 BufferedReader reader = new BufferedReader(new FileReader(file));
172 while(reader.ready()) {
173 String line = reader.readLine();
174 // ignore comments
175 if(!line.startsWith("#")) {
176 _okUrls.add(line);
177 }
178 }
179 } catch(IOException e) {
180 System.out.println(e);
181 e.printStackTrace();
182 }
183 }
184 }
185 }
186
187 //---ACCESSOR/MUTATOR METHODS---
188
189 //---ATTRIBUTES---
190
191 /**
192 * The port we're bound to.
193 */
194 private int _port;
195
196 /**
197 * List of URLs that are permitted
198 */
199 private LinkedList _okUrls;
200
201 /**
202 * Config file for the URL list
203 */
204 private String _okUrlsConfig;
205
206 /**
207 * Timestamp of the URL config file
208 */
209 private long _okUrlsConfigStamp = 0;
210
211 /**
212 * Web directory
213 */
214 private String _webDir;
215
216 //---STATIC ATTRIBUTES---
217
218 //---INNER CLASSES---
219
220 /**
221 * A Handler to deal with each client. This is an inner
222 * class because I felt like trying it out :)
223 */
224 private class Handler extends Thread {
225
226 /**
227 * Construct a new Handler
228 *
229 * @param socket The socket connected to the client
230 */
231 public Handler(Socket socket) {
232 _socket = socket;
233 }
234
235 /**
236 * Start the Handler running. This will read the URL
237 * from the client, and respond accordinly.
238 *
239 * This does not try to deal with bad data
240 */
241 public void run() {
242 BufferedReader reader = null;
243 PrintWriter writer = null;
244 try {
245 // setup the reader and writer
246 reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
247 writer = new PrintWriter(_socket.getOutputStream(), true);
248 String line= "";
249 String url = "";
250 // keep reading from the client until it sends no more...
251 do {
252 line = reader.readLine();
253 // ah, this contains the URL
254 if(line.startsWith("GET ")) {
255 // strip off "GET "
256 url = line.substring(4);
257 // strip off anything past the URL
258 if(url.lastIndexOf(' ') != -1) {
259 url = url.substring(0, url.lastIndexOf(' '));
260 }
261 }
262 } while(!line.equals(""));
263 // check the URL is allowed
264 if(okUrl(url)) {
265 // read the file
266 String data = readUrl(url);
267 // check the file could be read, null means it couldn't
268 if(data != null) {
269 writer.println(data);
270 }
271 else {
272 // oh dear, couldn't find it, send a 404
273 writer.println("HTTP/1.1 404 Not Found\n");
274 writer.println("404 Not Found");
275 }
276 }
277 else {
278 // oh dear, not allowed, send a 403
279 writer.println("HTTP/1.1 403 Permission Denied\n");
280 writer.println("403 Permission Denied");
281 }
282 } catch(IOException e) {
283 System.out.println(e);
284 e.printStackTrace();
285 }
286 // clean up and close
287 try {
288 reader.close();
289 writer.close();
290 _socket.close();
291 } catch(IOException e) {
292 System.out.println(e);
293 e.printStackTrace();
294 }
295 }
296
297 /**
298 * The socket connected to the client
299 */
300 private Socket _socket;
301 }
302
303 }