Home | History | Annotate | Download | only in conn
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/DefaultClientConnection.java $
      3  * $Revision: 673450 $
      4  * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 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.conn;
     33 
     34 
     35 import java.io.IOException;
     36 import java.net.Socket;
     37 
     38 import org.apache.commons.logging.Log;
     39 import org.apache.commons.logging.LogFactory;
     40 import org.apache.http.Header;
     41 import org.apache.http.HttpException;
     42 import org.apache.http.HttpHost;
     43 import org.apache.http.HttpRequest;
     44 import org.apache.http.HttpResponse;
     45 import org.apache.http.HttpResponseFactory;
     46 import org.apache.http.params.HttpParams;
     47 import org.apache.http.impl.SocketHttpClientConnection;
     48 import org.apache.http.io.HttpMessageParser;
     49 import org.apache.http.io.SessionInputBuffer;
     50 import org.apache.http.io.SessionOutputBuffer;
     51 
     52 import org.apache.http.conn.OperatedClientConnection;
     53 
     54 
     55 /**
     56  * Default implementation of an operated client connection.
     57  *
     58  * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
     59  *
     60  *
     61  * <!-- empty lines to avoid svn diff problems -->
     62  * @version   $Revision: 673450 $ $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $
     63  *
     64  * @since 4.0
     65  */
     66 public class DefaultClientConnection extends SocketHttpClientConnection
     67     implements OperatedClientConnection {
     68 
     69     private final Log log = LogFactory.getLog(getClass());
     70     private final Log headerLog = LogFactory.getLog("org.apache.http.headers");
     71     private final Log wireLog = LogFactory.getLog("org.apache.http.wire");
     72 
     73     /** The unconnected socket */
     74     private volatile Socket socket;
     75 
     76     /** The target host of this connection. */
     77     private HttpHost targetHost;
     78 
     79     /** Whether this connection is secure. */
     80     private boolean connSecure;
     81 
     82     /** True if this connection was shutdown. */
     83     private volatile boolean shutdown;
     84 
     85     public DefaultClientConnection() {
     86         super();
     87     }
     88 
     89 
     90     // non-javadoc, see interface OperatedClientConnection
     91     public final HttpHost getTargetHost() {
     92         return this.targetHost;
     93     }
     94 
     95 
     96     // non-javadoc, see interface OperatedClientConnection
     97     public final boolean isSecure() {
     98         return this.connSecure;
     99     }
    100 
    101 
    102     @Override
    103     public final Socket getSocket() {
    104         return this.socket;
    105     }
    106 
    107 
    108     public void opening(Socket sock, HttpHost target) throws IOException {
    109         assertNotOpen();
    110         this.socket = sock;
    111         this.targetHost = target;
    112 
    113         // Check for shutdown after assigning socket, so that
    114         if (this.shutdown) {
    115             sock.close(); // allow this to throw...
    116             // ...but if it doesn't, explicitly throw one ourselves.
    117             throw new IOException("Connection already shutdown");
    118         }
    119     }
    120 
    121 
    122     public void openCompleted(boolean secure, HttpParams params) throws IOException {
    123         assertNotOpen();
    124         if (params == null) {
    125             throw new IllegalArgumentException
    126                 ("Parameters must not be null.");
    127         }
    128         this.connSecure = secure;
    129         bind(this.socket, params);
    130     }
    131 
    132     /**
    133      * Force-closes this connection.
    134      * If the connection is still in the process of being open (the method
    135      * {@link #opening opening} was already called but
    136      * {@link #openCompleted openCompleted} was not), the associated
    137      * socket that is being connected to a remote address will be closed.
    138      * That will interrupt a thread that is blocked on connecting
    139      * the socket.
    140      * If the connection is not yet open, this will prevent the connection
    141      * from being opened.
    142      *
    143      * @throws IOException      in case of a problem
    144      */
    145     @Override
    146     public void shutdown() throws IOException {
    147         log.debug("Connection shut down");
    148         shutdown = true;
    149 
    150         super.shutdown();
    151         Socket sock = this.socket; // copy volatile attribute
    152         if (sock != null)
    153             sock.close();
    154 
    155     } // shutdown
    156 
    157 
    158     @Override
    159     public void close() throws IOException {
    160         log.debug("Connection closed");
    161         super.close();
    162     }
    163 
    164 
    165     @Override
    166     protected SessionInputBuffer createSessionInputBuffer(
    167             final Socket socket,
    168             int buffersize,
    169             final HttpParams params) throws IOException {
    170         SessionInputBuffer inbuffer = super.createSessionInputBuffer(
    171                 socket,
    172                 buffersize,
    173                 params);
    174         if (wireLog.isDebugEnabled()) {
    175             inbuffer = new LoggingSessionInputBuffer(inbuffer, new Wire(wireLog));
    176         }
    177         return inbuffer;
    178     }
    179 
    180 
    181     @Override
    182     protected SessionOutputBuffer createSessionOutputBuffer(
    183             final Socket socket,
    184             int buffersize,
    185             final HttpParams params) throws IOException {
    186         SessionOutputBuffer outbuffer = super.createSessionOutputBuffer(
    187                 socket,
    188                 buffersize,
    189                 params);
    190         if (wireLog.isDebugEnabled()) {
    191             outbuffer = new LoggingSessionOutputBuffer(outbuffer, new Wire(wireLog));
    192         }
    193         return outbuffer;
    194     }
    195 
    196 
    197     @Override
    198     protected HttpMessageParser createResponseParser(
    199             final SessionInputBuffer buffer,
    200             final HttpResponseFactory responseFactory,
    201             final HttpParams params) {
    202         // override in derived class to specify a line parser
    203         return new DefaultResponseParser
    204             (buffer, null, responseFactory, params);
    205     }
    206 
    207 
    208     // non-javadoc, see interface OperatedClientConnection
    209     public void update(Socket sock, HttpHost target,
    210                        boolean secure, HttpParams params)
    211         throws IOException {
    212 
    213         assertOpen();
    214         if (target == null) {
    215             throw new IllegalArgumentException
    216                 ("Target host must not be null.");
    217         }
    218         if (params == null) {
    219             throw new IllegalArgumentException
    220                 ("Parameters must not be null.");
    221         }
    222 
    223         if (sock != null) {
    224             this.socket = sock;
    225             bind(sock, params);
    226         }
    227         targetHost = target;
    228         connSecure = secure;
    229 
    230     } // update
    231 
    232 
    233     @Override
    234     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
    235         HttpResponse response = super.receiveResponseHeader();
    236         if (headerLog.isDebugEnabled()) {
    237             headerLog.debug("<< " + response.getStatusLine().toString());
    238             Header[] headers = response.getAllHeaders();
    239             for (Header header : headers) {
    240                 headerLog.debug("<< " + header.toString());
    241             }
    242         }
    243         return response;
    244     }
    245 
    246 
    247     @Override
    248     public void sendRequestHeader(HttpRequest request) throws HttpException, IOException {
    249         super.sendRequestHeader(request);
    250         if (headerLog.isDebugEnabled()) {
    251             headerLog.debug(">> " + request.getRequestLine().toString());
    252             Header[] headers = request.getAllHeaders();
    253             for (Header header : headers) {
    254                 headerLog.debug(">> " + header.toString());
    255             }
    256         }
    257     }
    258 
    259 } // class DefaultClientConnection
    260