View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.impl.conn;
29  
30  import java.io.IOException;
31  import java.io.InterruptedIOException;
32  import java.net.Socket;
33  import java.util.HashMap;
34  import java.util.Map;
35  
36  import javax.net.ssl.SSLSession;
37  import javax.net.ssl.SSLSocket;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.http.Header;
42  import org.apache.http.HttpException;
43  import org.apache.http.HttpHost;
44  import org.apache.http.HttpRequest;
45  import org.apache.http.HttpResponse;
46  import org.apache.http.HttpResponseFactory;
47  import org.apache.http.annotation.NotThreadSafe;
48  import org.apache.http.conn.OperatedClientConnection;
49  import org.apache.http.conn.ManagedHttpClientConnection;
50  import org.apache.http.impl.SocketHttpClientConnection;
51  import org.apache.http.io.HttpMessageParser;
52  import org.apache.http.io.SessionInputBuffer;
53  import org.apache.http.io.SessionOutputBuffer;
54  import org.apache.http.params.BasicHttpParams;
55  import org.apache.http.params.HttpParams;
56  import org.apache.http.params.HttpProtocolParams;
57  import org.apache.http.protocol.HttpContext;
58  import org.apache.http.util.Args;
59  
60  /**
61   * Default implementation of an operated client connection.
62   *
63   * @since 4.0
64   *
65   * @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}.
66   */
67  @NotThreadSafe // connSecure, targetHost
68  @Deprecated
69  public class DefaultClientConnection extends SocketHttpClientConnection
70      implements OperatedClientConnection, ManagedHttpClientConnection, HttpContext {
71  
72      private final Log log = LogFactory.getLog(getClass());
73      private final Log headerLog = LogFactory.getLog("org.apache.http.headers");
74      private final Log wireLog = LogFactory.getLog("org.apache.http.wire");
75  
76      /** The unconnected socket */
77      private volatile Socket socket;
78  
79      /** The target host of this connection. */
80      private HttpHost targetHost;
81  
82      /** Whether this connection is secure. */
83      private boolean connSecure;
84  
85      /** True if this connection was shutdown. */
86      private volatile boolean shutdown;
87  
88      /** connection specific attributes */
89      private final Map<String, Object> attributes;
90  
91      public DefaultClientConnection() {
92          super();
93          this.attributes = new HashMap<String, Object>();
94      }
95  
96      public String getId() {
97          return null;
98      }
99  
100     public final HttpHost getTargetHost() {
101         return this.targetHost;
102     }
103 
104     public final boolean isSecure() {
105         return this.connSecure;
106     }
107 
108     @Override
109     public final Socket getSocket() {
110         return this.socket;
111     }
112 
113     public SSLSession getSSLSession() {
114         if (this.socket instanceof SSLSocket) {
115             return ((SSLSocket) this.socket).getSession();
116         } else {
117             return null;
118         }
119     }
120 
121     public void opening(final Socket sock, final HttpHost target) throws IOException {
122         assertNotOpen();
123         this.socket = sock;
124         this.targetHost = target;
125 
126         // Check for shutdown after assigning socket, so that
127         if (this.shutdown) {
128             sock.close(); // allow this to throw...
129             // ...but if it doesn't, explicitly throw one ourselves.
130             throw new InterruptedIOException("Connection already shutdown");
131         }
132     }
133 
134     public void openCompleted(final boolean secure, final HttpParams params) throws IOException {
135         Args.notNull(params, "Parameters");
136         assertNotOpen();
137         this.connSecure = secure;
138         bind(this.socket, params);
139     }
140 
141     /**
142      * Force-closes this connection.
143      * If the connection is still in the process of being open (the method
144      * {@link #opening opening} was already called but
145      * {@link #openCompleted openCompleted} was not), the associated
146      * socket that is being connected to a remote address will be closed.
147      * That will interrupt a thread that is blocked on connecting
148      * the socket.
149      * If the connection is not yet open, this will prevent the connection
150      * from being opened.
151      *
152      * @throws IOException      in case of a problem
153      */
154     @Override
155     public void shutdown() throws IOException {
156         shutdown = true;
157         try {
158             super.shutdown();
159             if (log.isDebugEnabled()) {
160                 log.debug("Connection " + this + " shut down");
161             }
162             final Socket sock = this.socket; // copy volatile attribute
163             if (sock != null) {
164                 sock.close();
165             }
166         } catch (final IOException ex) {
167             log.debug("I/O error shutting down connection", ex);
168         }
169     }
170 
171     @Override
172     public void close() throws IOException {
173         try {
174             super.close();
175             if (log.isDebugEnabled()) {
176                 log.debug("Connection " + this + " closed");
177             }
178         } catch (final IOException ex) {
179             log.debug("I/O error closing connection", ex);
180         }
181     }
182 
183     @Override
184     protected SessionInputBuffer createSessionInputBuffer(
185             final Socket socket,
186             int buffersize,
187             final HttpParams params) throws IOException {
188         if (buffersize == -1) {
189             buffersize = 8192;
190         }
191         SessionInputBuffer inbuffer = super.createSessionInputBuffer(
192                 socket,
193                 buffersize,
194                 params);
195         if (wireLog.isDebugEnabled()) {
196             inbuffer = new LoggingSessionInputBuffer(
197                     inbuffer,
198                     new Wire(wireLog),
199                     HttpProtocolParams.getHttpElementCharset(params));
200         }
201         return inbuffer;
202     }
203 
204     @Override
205     protected SessionOutputBuffer createSessionOutputBuffer(
206             final Socket socket,
207             int buffersize,
208             final HttpParams params) throws IOException {
209         if (buffersize == -1) {
210             buffersize = 8192;
211         }
212         SessionOutputBuffer outbuffer = super.createSessionOutputBuffer(
213                 socket,
214                 buffersize,
215                 params);
216         if (wireLog.isDebugEnabled()) {
217             outbuffer = new LoggingSessionOutputBuffer(
218                     outbuffer,
219                     new Wire(wireLog),
220                     HttpProtocolParams.getHttpElementCharset(params));
221         }
222         return outbuffer;
223     }
224 
225     @Override
226     protected HttpMessageParser<HttpResponse> createResponseParser(
227             final SessionInputBuffer buffer,
228             final HttpResponseFactory responseFactory,
229             final HttpParams params) {
230         // override in derived class to specify a line parser
231         return new DefaultHttpResponseParser
232             (buffer, null, responseFactory, params);
233     }
234 
235     public void bind(final Socket socket) throws IOException {
236         bind(socket, new BasicHttpParams());
237     }
238 
239     public void update(final Socket sock, final HttpHost target,
240                        final boolean secure, final HttpParams params)
241         throws IOException {
242 
243         assertOpen();
244         Args.notNull(target, "Target host");
245         Args.notNull(params, "Parameters");
246 
247         if (sock != null) {
248             this.socket = sock;
249             bind(sock, params);
250         }
251         targetHost = target;
252         connSecure = secure;
253     }
254 
255     @Override
256     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
257         final HttpResponse response = super.receiveResponseHeader();
258         if (log.isDebugEnabled()) {
259             log.debug("Receiving response: " + response.getStatusLine());
260         }
261         if (headerLog.isDebugEnabled()) {
262             headerLog.debug("<< " + response.getStatusLine().toString());
263             final Header[] headers = response.getAllHeaders();
264             for (final Header header : headers) {
265                 headerLog.debug("<< " + header.toString());
266             }
267         }
268         return response;
269     }
270 
271     @Override
272     public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
273         if (log.isDebugEnabled()) {
274             log.debug("Sending request: " + request.getRequestLine());
275         }
276         super.sendRequestHeader(request);
277         if (headerLog.isDebugEnabled()) {
278             headerLog.debug(">> " + request.getRequestLine().toString());
279             final Header[] headers = request.getAllHeaders();
280             for (final Header header : headers) {
281                 headerLog.debug(">> " + header.toString());
282             }
283         }
284     }
285 
286     public Object getAttribute(final String id) {
287         return this.attributes.get(id);
288     }
289 
290     public Object removeAttribute(final String id) {
291         return this.attributes.remove(id);
292     }
293 
294     public void setAttribute(final String id, final Object obj) {
295         this.attributes.put(id, obj);
296     }
297 
298 }