1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.apache.commons.httpclient.server;
33
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.OutputStream;
37 import java.io.UnsupportedEncodingException;
38 import java.net.Socket;
39
40 import org.apache.commons.httpclient.HttpParser;
41 import org.apache.commons.httpclient.HttpStatus;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45 /***
46 * A connection to the SimpleHttpServer.
47 *
48 * @author Christian Kohlschuetter
49 */
50 public class SimpleHttpServerConnection implements Runnable {
51
52 private static final Log LOG = LogFactory.getLog(SimpleHttpServerConnection.class);
53 private static final String HTTP_ELEMENT_CHARSET = "US-ASCII";
54
55 private SimpleHttpServer server;
56 private Socket socket;
57 private InputStream in;
58 private OutputStream out;
59
60 private int requestNo = 0;
61
62 private boolean keepAlive = false;
63
64 public SimpleHttpServerConnection(SimpleHttpServer server, Socket socket) throws IOException {
65 this.server = server;
66 this.socket = socket;
67 this.in = socket.getInputStream();
68 this.out = socket.getOutputStream();
69 }
70
71 public void destroy() {
72 try {
73 if (socket != null) {
74 in.close();
75 out.close();
76 socket.close();
77 socket = null;
78 }
79 } catch (IOException e) {
80
81 }
82 server.removeConnection(this);
83 }
84
85 public void run() {
86 requestNo = 0;
87 try {
88 do {
89 keepAlive = false;
90
91 ++this.requestNo;
92 readRequest();
93 } while (keepAlive);
94 } catch (IOException e) {
95 LOG.error("I/O error: " + e.getMessage());
96 } finally {
97 destroy();
98 }
99 }
100
101 /***
102 * Requests to close connection after processing this request.
103 */
104 public void connectionClose() {
105 keepAlive = false;
106 }
107
108 /***
109 * Requests to keep the connection alive after processing this request
110 * (must be re-issued for every request if permanent keep-alive is
111 * desired).
112 *
113 */
114 public void connectionKeepAlive() {
115 keepAlive = true;
116 }
117
118 /***
119 * Returns the ResponseWriter used to write the output to the socket.
120 *
121 * @return This connection's ResponseWriter
122 */
123 public ResponseWriter getWriter() {
124 try {
125 return new ResponseWriter(out);
126 } catch (UnsupportedEncodingException e) {
127 throw new RuntimeException(e.toString());
128 }
129 }
130
131 /***
132 * Returns the number of requests processed (including the current one) for
133 * this connection.
134 *
135 * @return
136 */
137 public int getRequestNumber() {
138 return requestNo;
139 }
140
141 private void readRequest() throws IOException {
142 String line;
143 do {
144 line = HttpParser.readLine(in, HTTP_ELEMENT_CHARSET);
145 } while (line != null && line.length() == 0);
146
147 if (line == null) {
148 connectionClose();
149 return;
150 }
151
152 SimpleRequest request = null;
153 try {
154 request = new SimpleRequest(
155 RequestLine.parseLine(line),
156 HttpParser.parseHeaders(in, HTTP_ELEMENT_CHARSET),
157 null);
158 } catch (IOException e) {
159 connectionClose();
160 SimpleResponse response = ErrorResponse.getInstance().
161 getResponse(HttpStatus.SC_BAD_REQUEST);
162 server.writeResponse(this, response);
163 return;
164 }
165 server.processRequest(this, request);
166 out.flush();
167 }
168
169 public InputStream getInputStream() {
170 return in;
171 }
172
173 public OutputStream getOutputStream() {
174 return out;
175 }
176
177 public boolean isKeepAlive() {
178 return this.keepAlive;
179 }
180
181 }
182