Source code: Freenet/contrib/fproxy/HttpHandler.java
1 package Freenet.contrib.fproxy;
2 import Freenet.*;
3 import Freenet.client.*;
4 import Freenet.support.*;
5 import java.io.*;
6 import java.net.*;
7 import java.util.*;
8
9 /*
10 This code is part of fproxy, an HTTP proxy server for Freenet.
11 It is distributed under the GNU Public Licence (GPL) version 2. See
12 http://www.gnu.org/ for further details of the GPL.
13 */
14
15
16 /**
17 * Thread to handle incoming HTTP connections for the ProxyServer
18 *
19 * @author <a href="http://www.doc.ic.ac.uk/~twh1/">Theodore Hong</a>
20 **/
21
22 public class HttpHandler extends Thread
23 {
24 // local variables
25 protected static final char[] lf = {'\012'};
26
27 private ProxyServer ps;
28 private Socket s;
29 private InputStream in;
30 private OutputStream out;
31 private static long ids=0;
32 private long id;
33
34
35 /**
36 * Creates a new HttpHandler communicating on Socket s for ProxyServer ps
37 **/
38 public HttpHandler(Socket s, ProxyServer ps) throws IOException {
39 this.ps = ps;
40 this.s = s;
41 this.in = s.getInputStream();
42 this.out = s.getOutputStream();
43 this.id = ++ids;
44
45 Logger.log("HttpHandler.java#"+id, "New HttpHandler with "+s.getInetAddress(), Logger.NORMAL);
46 }
47
48
49 /**
50 * Main routine to process an HTTP request
51 **/
52 public void run() {
53 try {
54 // wait for request to arrive
55 while (in.available() == 0) {
56 try {
57 Thread.sleep(50);
58 } catch (InterruptedException e) {}
59 }
60
61 // read key
62 PushbackInputStream pstream = new PushbackInputStream(in);
63 String line = readTo(pstream, lf);
64 StringTokenizer st = new StringTokenizer (line, " ");
65 st.nextToken();
66 String key = st.nextToken();
67
68 // strip extraneous prefixes
69 String[] prefixes = {"http://", "/"};
70 for (int x = 0; x < prefixes.length; x++) {
71 if (key.startsWith(prefixes[x])) {
72 key = key.substring(prefixes[x].length());
73 break;
74 }
75 }
76
77 // send response header
78 Logger.log("HttpHandler.java#"+id, "Sending HTTP response header", Logger.NORMAL);
79 PrintWriter pw = new PrintWriter (out);
80 pw.print ("HTTP/1.0 200 OK\015\012");
81 pw.print ("Connection: close\015\012");
82 // for now, we'll send this instead of ProxyClient
83 pw.print("Content-type: text/plain\015\012\015\012");
84 pw.flush();
85
86 Logger.log("HttpHandler.java#"+id, "Transferring log messages to HTTP stream", Logger.NORMAL);
87 Logger.logto(out);
88
89 /*
90 HTTP/1.1 200 OK
91 Date: Wed, 05 Apr 2000 00:56:37 GMT
92 Server: Apache/1.3.12 (Unix)
93 Last-Modified: Mon, 03 Apr 2000 12:20:42 GMT
94 ETag: "f7a42-36cc-38e88c9a"
95 Accept-Ranges: bytes
96 Content-Length: 14028
97 Connection: close
98 Content-Type: text/html
99 */
100
101 // do freenet request
102 // note: ProxyClient will eventually send Content-type and terminate the headers
103 Logger.log("HttpHandler.java#"+id, "Requesting key: "+key+"\n", Logger.NORMAL);
104 ProxyClient pc = new ProxyClient (0, ps.serverAddress, ps.hopsToLive, out);
105 pc.request (key);
106
107 // wait for request to complete
108 Logger.logto(ps.Lout);
109 Logger.log("HttpHandler.java#"+id, "Waiting for request to complete", Logger.NORMAL);
110 if (pc.rc.ch != null) {
111 try {
112 // join ProxyClient.RequestClient.ConnectionHandler thread
113 pc.rc.ch.join();
114 }
115 catch (InterruptedException e) {}
116 }
117
118 // cleanup
119 Logger.log("HttpHandler.java#"+id, "Request done", Logger.NORMAL);
120 in.close();
121 out.close();
122 s.close();
123
124 Logger.log("HttpHandler.java#"+id, "Connection closed", Logger.DEBUGGING);
125
126 // just exit if there are any io/socket errors
127 } catch (EOFException e) {
128 } catch (IOException e) {
129 }
130 }
131
132
133 /**
134 * Utility function to return String from InputStream until one of
135 * the characters in tms is about to be read.
136 **/
137 protected String readTo(PushbackInputStream i, char[] tms)
138 throws IOException, EOFException
139 {
140 StringBuffer tmp = new StringBuffer();
141 char r=' ';
142 int ir;
143 while (true) {
144 ir = i.read();
145 if (ir == -1)
146 throw new EOFException();
147 r = (char) ir;
148 if (r == -1)
149 throw new EOFException();
150 boolean b = false;
151 for (int x=0; x<tms.length; x++) {
152 if (tms[x] == r) {
153 b=true;
154 break;
155 }
156 }
157 if (b)
158 break;
159 tmp.append(r);
160 }
161 if (ir != -1)
162 i.unread((int) r);
163 return tmp.toString();
164 }
165 }