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             final int buffersize,
187             final HttpParams params) throws IOException {
188         SessionInputBuffer inbuffer = super.createSessionInputBuffer(
189                 socket,
190                 buffersize > 0 ? buffersize : 8192,
191                 params);
192         if (wireLog.isDebugEnabled()) {
193             inbuffer = new LoggingSessionInputBuffer(
194                     inbuffer,
195                     new Wire(wireLog),
196                     HttpProtocolParams.getHttpElementCharset(params));
197         }
198         return inbuffer;
199     }
200 
201     @Override
202     protected SessionOutputBuffer createSessionOutputBuffer(
203             final Socket socket,
204             final int buffersize,
205             final HttpParams params) throws IOException {
206         SessionOutputBuffer outbuffer = super.createSessionOutputBuffer(
207                 socket,
208                 buffersize > 0 ? buffersize : 8192,
209                 params);
210         if (wireLog.isDebugEnabled()) {
211             outbuffer = new LoggingSessionOutputBuffer(
212                     outbuffer,
213                     new Wire(wireLog),
214                     HttpProtocolParams.getHttpElementCharset(params));
215         }
216         return outbuffer;
217     }
218 
219     @Override
220     protected HttpMessageParser<HttpResponse> createResponseParser(
221             final SessionInputBuffer buffer,
222             final HttpResponseFactory responseFactory,
223             final HttpParams params) {
224         // override in derived class to specify a line parser
225         return new DefaultHttpResponseParser
226             (buffer, null, responseFactory, params);
227     }
228 
229     public void bind(final Socket socket) throws IOException {
230         bind(socket, new BasicHttpParams());
231     }
232 
233     public void update(final Socket sock, final HttpHost target,
234                        final boolean secure, final HttpParams params)
235         throws IOException {
236 
237         assertOpen();
238         Args.notNull(target, "Target host");
239         Args.notNull(params, "Parameters");
240 
241         if (sock != null) {
242             this.socket = sock;
243             bind(sock, params);
244         }
245         targetHost = target;
246         connSecure = secure;
247     }
248 
249     @Override
250     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
251         final HttpResponse response = super.receiveResponseHeader();
252         if (log.isDebugEnabled()) {
253             log.debug("Receiving response: " + response.getStatusLine());
254         }
255         if (headerLog.isDebugEnabled()) {
256             headerLog.debug("<< " + response.getStatusLine().toString());
257             final Header[] headers = response.getAllHeaders();
258             for (final Header header : headers) {
259                 headerLog.debug("<< " + header.toString());
260             }
261         }
262         return response;
263     }
264 
265     @Override
266     public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
267         if (log.isDebugEnabled()) {
268             log.debug("Sending request: " + request.getRequestLine());
269         }
270         super.sendRequestHeader(request);
271         if (headerLog.isDebugEnabled()) {
272             headerLog.debug(">> " + request.getRequestLine().toString());
273             final Header[] headers = request.getAllHeaders();
274             for (final Header header : headers) {
275                 headerLog.debug(">> " + header.toString());
276             }
277         }
278     }
279 
280     public Object getAttribute(final String id) {
281         return this.attributes.get(id);
282     }
283 
284     public Object removeAttribute(final String id) {
285         return this.attributes.remove(id);
286     }
287 
288     public void setAttribute(final String id, final Object obj) {
289         this.attributes.put(id, obj);
290     }
291 
292 }