Home | History | Annotate | Download | only in impl
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java $
      3  * $Revision: 618017 $
      4  * $Date: 2008-02-03 08:42:22 -0800 (Sun, 03 Feb 2008) $
      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.impl;
     33 
     34 import java.io.IOException;
     35 
     36 import org.apache.http.HttpConnectionMetrics;
     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.HttpRequestFactory;
     42 import org.apache.http.HttpResponse;
     43 import org.apache.http.HttpServerConnection;
     44 import org.apache.http.impl.entity.EntityDeserializer;
     45 import org.apache.http.impl.entity.EntitySerializer;
     46 import org.apache.http.impl.entity.LaxContentLengthStrategy;
     47 import org.apache.http.impl.entity.StrictContentLengthStrategy;
     48 import org.apache.http.impl.io.HttpRequestParser;
     49 import org.apache.http.impl.io.HttpResponseWriter;
     50 import org.apache.http.io.HttpMessageParser;
     51 import org.apache.http.io.HttpMessageWriter;
     52 import org.apache.http.io.SessionInputBuffer;
     53 import org.apache.http.io.SessionOutputBuffer;
     54 import org.apache.http.params.HttpParams;
     55 
     56 /**
     57  * Abstract server-side HTTP connection capable of transmitting and receiving data
     58  * using arbitrary {@link SessionInputBuffer} and {@link SessionOutputBuffer}
     59  *
     60  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
     61  *
     62  * @version $Revision: 618017 $
     63  *
     64  * @since 4.0
     65  */
     66 public abstract class AbstractHttpServerConnection implements HttpServerConnection {
     67 
     68     private final EntitySerializer entityserializer;
     69     private final EntityDeserializer entitydeserializer;
     70 
     71     private SessionInputBuffer inbuffer = null;
     72     private SessionOutputBuffer outbuffer = null;
     73     private HttpMessageParser requestParser = null;
     74     private HttpMessageWriter responseWriter = null;
     75     private HttpConnectionMetricsImpl metrics = null;
     76 
     77 
     78 
     79     public AbstractHttpServerConnection() {
     80         super();
     81         this.entityserializer = createEntitySerializer();
     82         this.entitydeserializer = createEntityDeserializer();
     83     }
     84 
     85     protected abstract void assertOpen() throws IllegalStateException;
     86 
     87     protected EntityDeserializer createEntityDeserializer() {
     88         return new EntityDeserializer(new LaxContentLengthStrategy());
     89     }
     90 
     91     protected EntitySerializer createEntitySerializer() {
     92         return new EntitySerializer(new StrictContentLengthStrategy());
     93     }
     94 
     95     protected HttpRequestFactory createHttpRequestFactory() {
     96         return new DefaultHttpRequestFactory();
     97     }
     98 
     99     protected HttpMessageParser createRequestParser(
    100             final SessionInputBuffer buffer,
    101             final HttpRequestFactory requestFactory,
    102             final HttpParams params) {
    103         // override in derived class to specify a line parser
    104         return new HttpRequestParser(buffer, null, requestFactory, params);
    105     }
    106 
    107     protected HttpMessageWriter createResponseWriter(
    108             final SessionOutputBuffer buffer,
    109             final HttpParams params) {
    110         // override in derived class to specify a line formatter
    111         return new HttpResponseWriter(buffer, null, params);
    112     }
    113 
    114 
    115     protected void init(
    116             final SessionInputBuffer inbuffer,
    117             final SessionOutputBuffer outbuffer,
    118             final HttpParams params) {
    119         if (inbuffer == null) {
    120             throw new IllegalArgumentException("Input session buffer may not be null");
    121         }
    122         if (outbuffer == null) {
    123             throw new IllegalArgumentException("Output session buffer may not be null");
    124         }
    125         this.inbuffer = inbuffer;
    126         this.outbuffer = outbuffer;
    127         this.requestParser = createRequestParser(
    128                 inbuffer,
    129                 createHttpRequestFactory(),
    130                 params);
    131         this.responseWriter = createResponseWriter(
    132                 outbuffer, params);
    133         this.metrics = new HttpConnectionMetricsImpl(
    134                 inbuffer.getMetrics(),
    135                 outbuffer.getMetrics());
    136     }
    137 
    138     public HttpRequest receiveRequestHeader()
    139             throws HttpException, IOException {
    140         assertOpen();
    141         HttpRequest request = (HttpRequest) this.requestParser.parse();
    142         this.metrics.incrementRequestCount();
    143         return request;
    144     }
    145 
    146     public void receiveRequestEntity(final HttpEntityEnclosingRequest request)
    147             throws HttpException, IOException {
    148         if (request == null) {
    149             throw new IllegalArgumentException("HTTP request may not be null");
    150         }
    151         assertOpen();
    152         HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, request);
    153         request.setEntity(entity);
    154     }
    155 
    156     protected void doFlush() throws IOException  {
    157         this.outbuffer.flush();
    158     }
    159 
    160     public void flush() throws IOException {
    161         assertOpen();
    162         doFlush();
    163     }
    164 
    165     public void sendResponseHeader(final HttpResponse response)
    166             throws HttpException, IOException {
    167         if (response == null) {
    168             throw new IllegalArgumentException("HTTP response may not be null");
    169         }
    170         assertOpen();
    171         this.responseWriter.write(response);
    172         if (response.getStatusLine().getStatusCode() >= 200) {
    173             this.metrics.incrementResponseCount();
    174         }
    175     }
    176 
    177     public void sendResponseEntity(final HttpResponse response)
    178             throws HttpException, IOException {
    179         if (response.getEntity() == null) {
    180             return;
    181         }
    182         this.entityserializer.serialize(
    183                 this.outbuffer,
    184                 response,
    185                 response.getEntity());
    186     }
    187 
    188     public boolean isStale() {
    189         assertOpen();
    190         try {
    191             this.inbuffer.isDataAvailable(1);
    192             return false;
    193         } catch (IOException ex) {
    194             return true;
    195         }
    196     }
    197 
    198     public HttpConnectionMetrics getMetrics() {
    199         return this.metrics;
    200     }
    201 
    202 }
    203