1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/test/org/apache/commons/httpclient/server/HttpServiceHandler.java $
3    * $Revision: 1425331 $
4    * $Date: 2012-12-22 19:29:41 +0100 (Sat, 22 Dec 2012) $
5    *
6    * ====================================================================
7    *
8    *  Licensed to the Apache Software Foundation (ASF) under one or more
9    *  contributor license agreements.  See the NOTICE file distributed with
10   *  this work for additional information regarding copyright ownership.
11   *  The ASF licenses this file to You under the Apache License, Version 2.0
12   *  (the "License"); you may not use this file except in compliance with
13   *  the License.  You may obtain a copy of the License at
14   *
15   *      http://www.apache.org/licenses/LICENSE-2.0
16   *
17   *  Unless required by applicable law or agreed to in writing, software
18   *  distributed under the License is distributed on an "AS IS" BASIS,
19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   *  See the License for the specific language governing permissions and
21   *  limitations under the License.
22   * ====================================================================
23   *
24   * This software consists of voluntary contributions made by many
25   * individuals on behalf of the Apache Software Foundation.  For more
26   * information on the Apache Software Foundation, please see
27   * <http://www.apache.org/>.
28   *
29   */
30  
31  package org.apache.commons.httpclient.server;
32  
33  import java.io.IOException;
34  import java.io.InputStream;
35  
36  import org.apache.commons.httpclient.Header;
37  import org.apache.commons.httpclient.HttpVersion;
38  
39  /***
40   * This request handler provides service interface similar to that of Servlet API.
41   * 
42   * @author Oleg Kalnichevski
43   */
44  public class HttpServiceHandler implements HttpRequestHandler {
45  
46      private HttpService service = null;
47      
48      public HttpServiceHandler(final HttpService service) {
49          super();
50          if (service == null) {
51              throw new IllegalArgumentException("Service may not be null");
52          }
53          this.service = service;
54      }
55      
56      public boolean processRequest(
57          final SimpleHttpServerConnection conn,
58          final SimpleRequest request) throws IOException {
59          if (conn == null) {
60              throw new IllegalArgumentException("Connection may not be null");
61          }
62          if (request == null) {
63              throw new IllegalArgumentException("Request may not be null");
64          }
65          boolean complete = false;
66          SimpleResponse response = new SimpleResponse();
67          this.service.process(request, response);
68          
69          // Nake sure the request if fully consumed
70          request.getBodyBytes();
71          
72          // Ensure there's a content type header
73          if (!response.containsHeader("Content-Type")) {
74              response.addHeader(new Header("Content-Type", "text/plain"));
75          }
76          
77          // Ensure there's a content length or transfer encoding header
78          if (!response.containsHeader("Content-Length") && !response.containsHeader("Transfer-Encoding")) {
79              InputStream content = response.getBody();
80              if (content != null) {
81                  long len = response.getContentLength();
82                  if (len < 0) {
83                      if (response.getHttpVersion().lessEquals(HttpVersion.HTTP_1_0)) {
84                          throw new IOException("Chunked encoding not supported for HTTP version " 
85                                  + response.getHttpVersion());
86                      }
87                      Header header = new Header("Transfer-Encoding", "chunked"); 
88                      response.addHeader(header);                
89                  } else {
90                      Header header = new Header("Content-Length", Long.toString(len)); 
91                      response.setHeader(header);
92                  }
93              } else {
94                  Header header = new Header("Content-Length", "0"); 
95                  response.addHeader(header);
96              }
97          }
98  
99          if (!response.containsHeader("Connection")) {
100             // See if the the client explicitly handles connection persistence
101             Header connheader = request.getFirstHeader("Connection");
102             if (connheader != null) {
103                 if (connheader.getValue().equalsIgnoreCase("keep-alive")) {
104                     Header header = new Header("Connection", "keep-alive"); 
105                     response.addHeader(header);
106                     conn.setKeepAlive(true);
107                 }
108                 if (connheader.getValue().equalsIgnoreCase("close")) {
109                     Header header = new Header("Connection", "close"); 
110                     response.addHeader(header);
111                     conn.setKeepAlive(false);
112                 }
113             } else {
114                 // Use protocol default connection policy
115                 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
116                     conn.setKeepAlive(true);
117                 } else {
118                     conn.setKeepAlive(false);
119                 }
120             }
121         }
122         if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
123             // this is a head request, we don't want to send the actualy content
124             response.setBody(null);
125         }
126         conn.writeResponse(response);
127         return true;
128     }
129     
130 }