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 package org.apache.http.protocol;
29
30 import java.io.IOException;
31
32 import org.apache.http.ConnectionReuseStrategy;
33 import org.apache.http.HttpEntity;
34 import org.apache.http.HttpEntityEnclosingRequest;
35 import org.apache.http.HttpException;
36 import org.apache.http.HttpRequest;
37 import org.apache.http.HttpResponse;
38 import org.apache.http.HttpResponseFactory;
39 import org.apache.http.HttpServerConnection;
40 import org.apache.http.HttpStatus;
41 import org.apache.http.HttpVersion;
42 import org.apache.http.MethodNotSupportedException;
43 import org.apache.http.ProtocolException;
44 import org.apache.http.UnsupportedHttpVersionException;
45 import org.apache.http.annotation.Contract;
46 import org.apache.http.annotation.ThreadingBehavior;
47 import org.apache.http.entity.ByteArrayEntity;
48 import org.apache.http.impl.DefaultConnectionReuseStrategy;
49 import org.apache.http.impl.DefaultHttpResponseFactory;
50 import org.apache.http.params.HttpParams;
51 import org.apache.http.util.Args;
52 import org.apache.http.util.EncodingUtils;
53 import org.apache.http.util.EntityUtils;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 @SuppressWarnings("deprecation")
75 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
76 public class HttpService {
77
78
79
80
81 private volatile HttpParams params = null;
82 private volatile HttpProcessor processor = null;
83 private volatile HttpRequestHandlerMapper handlerMapper = null;
84 private volatile ConnectionReuseStrategy connStrategy = null;
85 private volatile HttpResponseFactory responseFactory = null;
86 private volatile HttpExpectationVerifier expectationVerifier = null;
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 @Deprecated
103 public HttpService(
104 final HttpProcessor processor,
105 final ConnectionReuseStrategy connStrategy,
106 final HttpResponseFactory responseFactory,
107 final HttpRequestHandlerResolver handlerResolver,
108 final HttpExpectationVerifier expectationVerifier,
109 final HttpParams params) {
110 this(processor,
111 connStrategy,
112 responseFactory,
113 new HttpRequestHandlerResolverAdapter(handlerResolver),
114 expectationVerifier);
115 this.params = params;
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 @Deprecated
132 public HttpService(
133 final HttpProcessor processor,
134 final ConnectionReuseStrategy connStrategy,
135 final HttpResponseFactory responseFactory,
136 final HttpRequestHandlerResolver handlerResolver,
137 final HttpParams params) {
138 this(processor,
139 connStrategy,
140 responseFactory,
141 new HttpRequestHandlerResolverAdapter(handlerResolver),
142 null);
143 this.params = params;
144 }
145
146
147
148
149
150
151
152
153
154
155
156 @Deprecated
157 public HttpService(
158 final HttpProcessor proc,
159 final ConnectionReuseStrategy connStrategy,
160 final HttpResponseFactory responseFactory) {
161 super();
162 setHttpProcessor(proc);
163 setConnReuseStrategy(connStrategy);
164 setResponseFactory(responseFactory);
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 public HttpService(
181 final HttpProcessor processor,
182 final ConnectionReuseStrategy connStrategy,
183 final HttpResponseFactory responseFactory,
184 final HttpRequestHandlerMapper handlerMapper,
185 final HttpExpectationVerifier expectationVerifier) {
186 super();
187 this.processor = Args.notNull(processor, "HTTP processor");
188 this.connStrategy = connStrategy != null ? connStrategy :
189 DefaultConnectionReuseStrategy.INSTANCE;
190 this.responseFactory = responseFactory != null ? responseFactory :
191 DefaultHttpResponseFactory.INSTANCE;
192 this.handlerMapper = handlerMapper;
193 this.expectationVerifier = expectationVerifier;
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208 public HttpService(
209 final HttpProcessor processor,
210 final ConnectionReuseStrategy connStrategy,
211 final HttpResponseFactory responseFactory,
212 final HttpRequestHandlerMapper handlerMapper) {
213 this(processor, connStrategy, responseFactory, handlerMapper, null);
214 }
215
216
217
218
219
220
221
222
223
224 public HttpService(
225 final HttpProcessor processor, final HttpRequestHandlerMapper handlerMapper) {
226 this(processor, null, null, handlerMapper, null);
227 }
228
229
230
231
232 @Deprecated
233 public void setHttpProcessor(final HttpProcessor processor) {
234 Args.notNull(processor, "HTTP processor");
235 this.processor = processor;
236 }
237
238
239
240
241 @Deprecated
242 public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) {
243 Args.notNull(connStrategy, "Connection reuse strategy");
244 this.connStrategy = connStrategy;
245 }
246
247
248
249
250 @Deprecated
251 public void setResponseFactory(final HttpResponseFactory responseFactory) {
252 Args.notNull(responseFactory, "Response factory");
253 this.responseFactory = responseFactory;
254 }
255
256
257
258
259 @Deprecated
260 public void setParams(final HttpParams params) {
261 this.params = params;
262 }
263
264
265
266
267 @Deprecated
268 public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
269 this.handlerMapper = new HttpRequestHandlerResolverAdapter(handlerResolver);
270 }
271
272
273
274
275 @Deprecated
276 public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
277 this.expectationVerifier = expectationVerifier;
278 }
279
280
281
282
283 @Deprecated
284 public HttpParams getParams() {
285 return this.params;
286 }
287
288
289
290
291
292
293
294
295
296
297
298 public void handleRequest(
299 final HttpServerConnection conn,
300 final HttpContext context) throws IOException, HttpException {
301
302 context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
303
304 HttpRequest request = null;
305 HttpResponse response = null;
306
307 try {
308 request = conn.receiveRequestHeader();
309 if (request instanceof HttpEntityEnclosingRequest) {
310
311 if (((HttpEntityEnclosingRequest) request).expectContinue()) {
312 response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
313 HttpStatus.SC_CONTINUE, context);
314 if (this.expectationVerifier != null) {
315 try {
316 this.expectationVerifier.verify(request, response, context);
317 } catch (final HttpException ex) {
318 response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0,
319 HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
320 handleException(ex, response);
321 }
322 }
323 if (response.getStatusLine().getStatusCode() < 200) {
324
325
326 conn.sendResponseHeader(response);
327 conn.flush();
328 response = null;
329 conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
330 }
331 } else {
332 conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
333 }
334 }
335
336 context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
337
338 if (response == null) {
339 response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1,
340 HttpStatus.SC_OK, context);
341 this.processor.process(request, context);
342 doService(request, response, context);
343 }
344
345
346 if (request instanceof HttpEntityEnclosingRequest) {
347 final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
348 EntityUtils.consume(entity);
349 }
350
351 } catch (final HttpException ex) {
352 response = this.responseFactory.newHttpResponse
353 (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR,
354 context);
355 handleException(ex, response);
356 }
357
358 context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
359
360 this.processor.process(response, context);
361 conn.sendResponseHeader(response);
362 if (canResponseHaveBody(request, response)) {
363 conn.sendResponseEntity(response);
364 }
365 conn.flush();
366
367 if (!this.connStrategy.keepAlive(response, context)) {
368 conn.close();
369 }
370 }
371
372 private boolean canResponseHaveBody(final HttpRequest request, final HttpResponse response) {
373 if (request != null && "HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
374 return false;
375 }
376 final int status = response.getStatusLine().getStatusCode();
377 return status >= HttpStatus.SC_OK
378 && status != HttpStatus.SC_NO_CONTENT
379 && status != HttpStatus.SC_NOT_MODIFIED
380 && status != HttpStatus.SC_RESET_CONTENT;
381 }
382
383
384
385
386
387
388
389
390
391 protected void handleException(final HttpException ex, final HttpResponse response) {
392 if (ex instanceof MethodNotSupportedException) {
393 response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
394 } else if (ex instanceof UnsupportedHttpVersionException) {
395 response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED);
396 } else if (ex instanceof ProtocolException) {
397 response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
398 } else {
399 response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
400 }
401 String message = ex.getMessage();
402 if (message == null) {
403 message = ex.toString();
404 }
405 final byte[] msg = EncodingUtils.getAsciiBytes(message);
406 final ByteArrayEntityy.html#ByteArrayEntity">ByteArrayEntity entity = new ByteArrayEntity(msg);
407 entity.setContentType("text/plain; charset=US-ASCII");
408 response.setEntity(entity);
409 }
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428 protected void doService(
429 final HttpRequest request,
430 final HttpResponse response,
431 final HttpContext context) throws HttpException, IOException {
432 HttpRequestHandler handler = null;
433 if (this.handlerMapper != null) {
434 handler = this.handlerMapper.lookup(request);
435 }
436 if (handler != null) {
437 handler.handle(request, response, context);
438 } else {
439 response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
440 }
441 }
442
443
444
445
446
447
448 @Deprecated
449 private static class HttpRequestHandlerResolverAdapter implements HttpRequestHandlerMapper {
450
451 private final HttpRequestHandlerResolver resolver;
452
453 public HttpRequestHandlerResolverAdapter(final HttpRequestHandlerResolver resolver) {
454 this.resolver = resolver;
455 }
456
457 @Override
458 public HttpRequestHandler lookup(final HttpRequest request) {
459 return resolver.lookup(request.getRequestLine().getUri());
460 }
461
462 }
463
464 }