Home » HttpComponents-Core-4.0.1 » org.apache.http.protocol » [javadoc | source]

    1   /*
    2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0.1/httpcore/src/main/java/org/apache/http/protocol/HttpService.java $
    3    * $Revision: 744532 $
    4    * $Date: 2009-02-14 18:12:18 +0100 (Sat, 14 Feb 2009) $
    5    *
    6    * ====================================================================
    7    * Licensed to the Apache Software Foundation (ASF) under one
    8    * or more contributor license agreements.  See the NOTICE file
    9    * distributed with this work for additional information
   10    * regarding copyright ownership.  The ASF licenses this file
   11    * to you under the Apache License, Version 2.0 (the
   12    * "License"); you may not use this file except in compliance
   13    * with 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,
   18    * software distributed under the License is distributed on an
   19    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   20    * KIND, either express or implied.  See the License for the
   21    * specific language governing permissions and limitations
   22    * under the License.
   23    * ====================================================================
   24    *
   25    * This software consists of voluntary contributions made by many
   26    * individuals on behalf of the Apache Software Foundation.  For more
   27    * information on the Apache Software Foundation, please see
   28    * <http://www.apache.org/>.
   29    *
   30    */
   31   
   32   package org.apache.http.protocol;
   33   
   34   import java.io.IOException;
   35   
   36   import org.apache.http.ConnectionReuseStrategy;
   37   import org.apache.http.HttpEntity;
   38   import org.apache.http.HttpEntityEnclosingRequest;
   39   import org.apache.http.HttpException;
   40   import org.apache.http.HttpRequest;
   41   import org.apache.http.HttpResponse;
   42   import org.apache.http.HttpResponseFactory;
   43   import org.apache.http.HttpServerConnection;
   44   import org.apache.http.HttpStatus;
   45   import org.apache.http.HttpVersion;
   46   import org.apache.http.MethodNotSupportedException;
   47   import org.apache.http.ProtocolException;
   48   import org.apache.http.ProtocolVersion;
   49   import org.apache.http.UnsupportedHttpVersionException;
   50   import org.apache.http.entity.ByteArrayEntity;
   51   import org.apache.http.params.HttpParams;
   52   import org.apache.http.params.DefaultedHttpParams;
   53   import org.apache.http.util.EncodingUtils;
   54   
   55   /**
   56    * HttpService is a server side HTTP protocol handler based in the blocking 
   57    * I/O model that implements the essential requirements of the HTTP protocol 
   58    * for the server side message processing as described by RFC 2616. 
   59    * <br>
   60    * HttpService relies on {@link HttpProcessor} to generate mandatory protocol 
   61    * headers for all outgoing messages and apply common, cross-cutting message 
   62    * transformations to all incoming and outgoing messages, whereas individual 
   63    * {@link HttpRequestHandler}s are expected to take care of application specific 
   64    * content generation and processing.
   65    * <br>
   66    * HttpService relies on {@link HttpRequestHandler} to resolve matching request 
   67    * handler for a particular request URI of an incoming HTTP request.
   68    * <br>
   69    * HttpService can use optional {@link HttpExpectationVerifier} to ensure that 
   70    * incoming requests meet server's expectations.
   71    *
   72    *
   73    * @version $Revision: 744532 $
   74    *
   75    * @since 4.0
   76    */
   77   public class HttpService {
   78   
   79       private HttpParams params = null;
   80       private HttpProcessor processor = null;
   81       private HttpRequestHandlerResolver handlerResolver = null;
   82       private ConnectionReuseStrategy connStrategy = null;
   83       private HttpResponseFactory responseFactory = null;
   84       private HttpExpectationVerifier expectationVerifier = null;
   85       
   86       /**
   87        * Create a new HTTP service.
   88        *
   89        * @param proc             the processor to use on requests and responses
   90        * @param connStrategy     the connection reuse strategy
   91        * @param responseFactory  the response factory
   92        */
   93       public HttpService(
   94               final HttpProcessor proc,
   95               final ConnectionReuseStrategy connStrategy,
   96               final HttpResponseFactory responseFactory) {
   97           super();
   98           setHttpProcessor(proc);
   99           setConnReuseStrategy(connStrategy);
  100           setResponseFactory(responseFactory);
  101       }
  102       
  103       public void setHttpProcessor(final HttpProcessor processor) {
  104           if (processor == null) {
  105               throw new IllegalArgumentException("HTTP processor may not be null");
  106           }
  107           this.processor = processor;
  108       }
  109   
  110       public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) {
  111           if (connStrategy == null) {
  112               throw new IllegalArgumentException("Connection reuse strategy may not be null");
  113           }
  114           this.connStrategy = connStrategy;
  115       }
  116   
  117       public void setResponseFactory(final HttpResponseFactory responseFactory) {
  118           if (responseFactory == null) {
  119               throw new IllegalArgumentException("Response factory may not be null");
  120           }
  121           this.responseFactory = responseFactory;
  122       }
  123       
  124       public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
  125           this.handlerResolver = handlerResolver;
  126       }
  127   
  128       public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
  129           this.expectationVerifier = expectationVerifier;
  130       }
  131   
  132       public HttpParams getParams() {
  133           return this.params;
  134       }
  135       
  136       public void setParams(final HttpParams params) {
  137           this.params = params;
  138       }
  139       
  140       /**
  141        * Handles receives one HTTP request over the given connection within the 
  142        * given execution context and sends a response back to the client.
  143        * 
  144        * @param conn the active connection to the client
  145        * @param context the actual execution context.
  146        * @throws IOException in case of an I/O error.
  147        * @throws HttpException in case of HTTP protocol violation or a processing 
  148        *   problem.
  149        */
  150       public void handleRequest(
  151               final HttpServerConnection conn, 
  152               final HttpContext context) throws IOException, HttpException { 
  153           
  154           context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
  155   
  156           HttpResponse response = null;
  157           
  158           try {
  159   
  160               HttpRequest request = conn.receiveRequestHeader();
  161               request.setParams(
  162                       new DefaultedHttpParams(request.getParams(), this.params));
  163               
  164               ProtocolVersion ver =
  165                   request.getRequestLine().getProtocolVersion();
  166               if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
  167                   // Downgrade protocol version if greater than HTTP/1.1 
  168                   ver = HttpVersion.HTTP_1_1;
  169               }
  170   
  171               if (request instanceof HttpEntityEnclosingRequest) {
  172   
  173                   if (((HttpEntityEnclosingRequest) request).expectContinue()) {
  174                       response = this.responseFactory.newHttpResponse(ver, 
  175                               HttpStatus.SC_CONTINUE, context);
  176                       response.setParams(
  177                               new DefaultedHttpParams(response.getParams(), this.params));
  178                       
  179                       if (this.expectationVerifier != null) {
  180                           try {
  181                               this.expectationVerifier.verify(request, response, context);
  182                           } catch (HttpException ex) {
  183                               response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 
  184                                       HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
  185                               response.setParams(
  186                                       new DefaultedHttpParams(response.getParams(), this.params));
  187                               handleException(ex, response);
  188                           }
  189                       }
  190                       if (response.getStatusLine().getStatusCode() < 200) {
  191                           // Send 1xx response indicating the server expections
  192                           // have been met
  193                           conn.sendResponseHeader(response);
  194                           conn.flush();
  195                           response = null;
  196                           conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
  197                       }
  198                   } else {
  199                       conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
  200                   }
  201               }
  202   
  203               if (response == null) {
  204                   response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK, context);
  205                   response.setParams(
  206                           new DefaultedHttpParams(response.getParams(), this.params));
  207   
  208                   context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
  209                   context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
  210   
  211                   this.processor.process(request, context);
  212                   doService(request, response, context);
  213               }
  214               
  215               // Make sure the request content is fully consumed
  216               if (request instanceof HttpEntityEnclosingRequest) {
  217                   HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
  218                   if (entity != null) {
  219                       entity.consumeContent();
  220                   }
  221               }
  222               
  223           } catch (HttpException ex) {
  224               response = this.responseFactory.newHttpResponse
  225                   (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR,
  226                    context);
  227               response.setParams(
  228                       new DefaultedHttpParams(response.getParams(), this.params));
  229               handleException(ex, response);
  230           }
  231           
  232           this.processor.process(response, context);
  233           conn.sendResponseHeader(response);
  234           conn.sendResponseEntity(response);
  235           conn.flush();
  236           
  237           if (!this.connStrategy.keepAlive(response, context)) {
  238               conn.close();
  239           }
  240       }
  241   
  242       /**
  243        * Handles the given exception and generates an HTTP response to be sent 
  244        * back to the client to inform about the exceptional condition encountered
  245        * in the course of the request processing.
  246        * 
  247        * @param ex the exception.
  248        * @param response the HTTP response.
  249        */
  250       protected void handleException(final HttpException ex, final HttpResponse response) {
  251           if (ex instanceof MethodNotSupportedException) {
  252               response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
  253           } else if (ex instanceof UnsupportedHttpVersionException) {
  254               response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED);
  255           } else if (ex instanceof ProtocolException) {
  256               response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
  257           } else {
  258               response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
  259           }
  260           byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
  261           ByteArrayEntity entity = new ByteArrayEntity(msg);
  262           entity.setContentType("text/plain; charset=US-ASCII");
  263           response.setEntity(entity);
  264       }
  265       
  266       /**
  267        * The default implementation of this method attempts to resolve an 
  268        * {@link HttpRequestHandler} for the request URI of the given request
  269        * and, if found, executes its
  270        * {@link HttpRequestHandler#handle(HttpRequest, HttpResponse, HttpContext)}
  271        * method.
  272        * <p>
  273        * Super-classes can override this method in order to provide a custom
  274        * implementation of the request processing logic.
  275        * 
  276        * @param request the HTTP request.
  277        * @param response the HTTP response.
  278        * @param context the execution context.
  279        * @throws IOException in case of an I/O error.
  280        * @throws HttpException in case of HTTP protocol violation or a processing 
  281        *   problem.
  282        */
  283       protected void doService(
  284               final HttpRequest request, 
  285               final HttpResponse response,
  286               final HttpContext context) throws HttpException, IOException {
  287           HttpRequestHandler handler = null;
  288           if (this.handlerResolver != null) {
  289               String requestURI = request.getRequestLine().getUri();
  290               handler = this.handlerResolver.lookup(requestURI);
  291           }
  292           if (handler != null) {
  293               handler.handle(request, response, context);
  294           } else {
  295               response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
  296           }
  297       }
  298       
  299   }

Home » HttpComponents-Core-4.0.1 » org.apache.http.protocol » [javadoc | source]