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.conn.ManagedHttpClientConnection;
48  import org.apache.http.conn.OperatedClientConnection;
49  import org.apache.http.impl.SocketHttpClientConnection;
50  import org.apache.http.io.HttpMessageParser;
51  import org.apache.http.io.SessionInputBuffer;
52  import org.apache.http.io.SessionOutputBuffer;
53  import org.apache.http.params.BasicHttpParams;
54  import org.apache.http.params.HttpParams;
55  import org.apache.http.params.HttpProtocolParams;
56  import org.apache.http.protocol.HttpContext;
57  import org.apache.http.util.Args;
58  
59  /**
60   * Default implementation of an operated client connection.
61   *
62   * @since 4.0
63   *
64   * @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}.
65   */
66  @Deprecated
67  public class DefaultClientConnection extends SocketHttpClientConnection
68      implements OperatedClientConnection, ManagedHttpClientConnection, HttpContext {
69  
70      private final Log log = LogFactory.getLog(getClass());
71      private final Log headerLog = LogFactory.getLog("org.apache.http.headers");
72      private final Log wireLog = LogFactory.getLog("org.apache.http.wire");
73  
74      /** The unconnected socket */
75      private volatile Socket socket;
76  
77      /** The target host of this connection. */
78      private HttpHost targetHost;
79  
80      /** Whether this connection is secure. */
81      private boolean connSecure;
82  
83      /** True if this connection was shutdown. */
84      private volatile boolean shutdown;
85  
86      /** connection specific attributes */
87      private final Map<String, Object> attributes;
88  
89      public DefaultClientConnection() {
90          super();
91          this.attributes = new HashMap<String, Object>();
92      }
93  
94      @Override
95      public String getId() {
96          return null;
97      }
98  
99      @Override
100     public final HttpHost getTargetHost() {
101         return this.targetHost;
102     }
103 
104     @Override
105     public final boolean isSecure() {
106         return this.connSecure;
107     }
108 
109     @Override
110     public final Socket getSocket() {
111         return this.socket;
112     }
113 
114     @Override
115     public SSLSession getSSLSession() {
116         if (this.socket instanceof SSLSocket) {
117             return ((SSLSocket) this.socket).getSession();
118         } else {
119             return null;
120         }
121     }
122 
123     @Override
124     public void opening(final Socket sock, final HttpHost target) throws IOException {
125         assertNotOpen();
126         this.socket = sock;
127         this.targetHost = target;
128 
129         // Check for shutdown after assigning socket, so that
130         if (this.shutdown) {
131             sock.close(); // allow this to throw...
132             // ...but if it doesn't, explicitly throw one ourselves.
133             throw new InterruptedIOException("Connection already shutdown");
134         }
135     }
136 
137     @Override
138     public void openCompleted(final boolean secure, final HttpParams params) throws IOException {
139         Args.notNull(params, "Parameters");
140         assertNotOpen();
141         this.connSecure = secure;
142         bind(this.socket, params);
143     }
144 
145     /**
146      * Force-closes this connection.
147      * If the connection is still in the process of being open (the method
148      * {@link #opening opening} was already called but
149      * {@link #openCompleted openCompleted} was not), the associated
150      * socket that is being connected to a remote address will be closed.
151      * That will interrupt a thread that is blocked on connecting
152      * the socket.
153      * If the connection is not yet open, this will prevent the connection
154      * from being opened.
155      *
156      * @throws IOException      in case of a problem
157      */
158     @Override
159     public void shutdown() throws IOException {
160         shutdown = true;
161         try {
162             super.shutdown();
163             if (log.isDebugEnabled()) {
164                 log.debug("Connection " + this + " shut down");
165             }
166             final Socket sock = this.socket; // copy volatile attribute
167             if (sock != null) {
168                 sock.close();
169             }
170         } catch (final IOException ex) {
171             log.debug("I/O error shutting down connection", ex);
172         }
173     }
174 
175     @Override
176     public void close() throws IOException {
177         try {
178             super.close();
179             if (log.isDebugEnabled()) {
180                 log.debug("Connection " + this + " closed");
181             }
182         } catch (final IOException ex) {
183             log.debug("I/O error closing connection", ex);
184         }
185     }
186 
187     @Override
188     protected SessionInputBuffer createSessionInputBuffer(
189             final Socket socket,
190             final int bufferSize,
191             final HttpParams params) throws IOException {
192         SessionInputBuffer inBuffer = super.createSessionInputBuffer(
193                 socket,
194                 bufferSize > 0 ? bufferSize : 8192,
195                 params);
196         if (wireLog.isDebugEnabled()) {
197             inBuffer = new LoggingSessionInputBuffer(
198                     inBuffer,
199                     new Wire(wireLog),
200                     HttpProtocolParams.getHttpElementCharset(params));
201         }
202         return inBuffer;
203     }
204 
205     @Override
206     protected SessionOutputBuffer createSessionOutputBuffer(
207             final Socket socket,
208             final int bufferSize,
209             final HttpParams params) throws IOException {
210         SessionOutputBuffer outbuffer = super.createSessionOutputBuffer(
211                 socket,
212                 bufferSize > 0 ? bufferSize : 8192,
213                 params);
214         if (wireLog.isDebugEnabled()) {
215             outbuffer = new LoggingSessionOutputBuffer(
216                     outbuffer,
217                     new Wire(wireLog),
218                     HttpProtocolParams.getHttpElementCharset(params));
219         }
220         return outbuffer;
221     }
222 
223     @Override
224     protected HttpMessageParser<HttpResponse> createResponseParser(
225             final SessionInputBuffer buffer,
226             final HttpResponseFactory responseFactory,
227             final HttpParams params) {
228         // override in derived class to specify a line parser
229         return new DefaultHttpResponseParser
230             (buffer, null, responseFactory, params);
231     }
232 
233     @Override
234     public void bind(final Socket socket) throws IOException {
235         bind(socket, new BasicHttpParams());
236     }
237 
238     @Override
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     @Override
287     public Object getAttribute(final String id) {
288         return this.attributes.get(id);
289     }
290 
291     @Override
292     public Object removeAttribute(final String id) {
293         return this.attributes.remove(id);
294     }
295 
296     @Override
297     public void setAttribute(final String id, final Object obj) {
298         this.attributes.put(id, obj);
299     }
300 
301 }