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;
29  
30  import java.io.IOException;
31  import java.net.InetAddress;
32  import java.net.InetSocketAddress;
33  import java.net.Socket;
34  import java.net.SocketAddress;
35  import java.net.SocketException;
36  
37  import org.apache.http.HttpInetConnection;
38  import org.apache.http.annotation.NotThreadSafe;
39  import org.apache.http.impl.io.SocketInputBuffer;
40  import org.apache.http.impl.io.SocketOutputBuffer;
41  import org.apache.http.io.SessionInputBuffer;
42  import org.apache.http.io.SessionOutputBuffer;
43  import org.apache.http.params.CoreConnectionPNames;
44  import org.apache.http.params.HttpParams;
45  import org.apache.http.util.Args;
46  import org.apache.http.util.Asserts;
47  
48  /**
49   * Implementation of a server-side HTTP connection that can be bound to a
50   * network Socket in order to receive and transmit data.
51   *
52   * @since 4.0
53   *
54   * @deprecated (4.3) use {@link DefaultBHttpServerConnection}
55   */
56  @NotThreadSafe
57  @Deprecated
58  public class SocketHttpServerConnection extends
59          AbstractHttpServerConnection implements HttpInetConnection {
60  
61      private volatile boolean open;
62      private volatile Socket socket = null;
63  
64      public SocketHttpServerConnection() {
65          super();
66      }
67  
68      protected void assertNotOpen() {
69          Asserts.check(!this.open, "Connection is already open");
70      }
71  
72      @Override
73      protected void assertOpen() {
74          Asserts.check(this.open, "Connection is not open");
75      }
76  
77      /**
78       * Creates an instance of {@link SocketInputBuffer} to be used for
79       * receiving data from the given {@link Socket}.
80       * <p>
81       * This method can be overridden in a super class in order to provide
82       * a custom implementation of {@link SessionInputBuffer} interface.
83       *
84       * @see SocketInputBuffer#SocketInputBuffer(Socket, int, HttpParams)
85       *
86       * @param socket the socket.
87       * @param buffersize the buffer size.
88       * @param params HTTP parameters.
89       * @return session input buffer.
90       * @throws IOException in case of an I/O error.
91       */
92      protected SessionInputBuffer createSessionInputBuffer(
93              final Socket socket,
94              final int buffersize,
95              final HttpParams params) throws IOException {
96          return new SocketInputBuffer(socket, buffersize, params);
97      }
98  
99      /**
100      * Creates an instance of {@link SessionOutputBuffer} to be used for
101      * sending data to the given {@link Socket}.
102      * <p>
103      * This method can be overridden in a super class in order to provide
104      * a custom implementation of {@link SocketOutputBuffer} interface.
105      *
106      * @see SocketOutputBuffer#SocketOutputBuffer(Socket, int, HttpParams)
107      *
108      * @param socket the socket.
109      * @param buffersize the buffer size.
110      * @param params HTTP parameters.
111      * @return session output buffer.
112      * @throws IOException in case of an I/O error.
113      */
114     protected SessionOutputBuffer createSessionOutputBuffer(
115             final Socket socket,
116             final int buffersize,
117             final HttpParams params) throws IOException {
118         return new SocketOutputBuffer(socket, buffersize, params);
119     }
120 
121     /**
122      * Binds this connection to the given {@link Socket}. This socket will be
123      * used by the connection to send and receive data.
124      * <p>
125      * This method will invoke {@link #createSessionInputBuffer(Socket, int, HttpParams)}
126      * and {@link #createSessionOutputBuffer(Socket, int, HttpParams)} methods
127      * to create session input / output buffers bound to this socket and then
128      * will invoke {@link #init(SessionInputBuffer, SessionOutputBuffer, HttpParams)}
129      * method to pass references to those buffers to the underlying HTTP message
130      * parser and formatter.
131      * <p>
132      * After this method's execution the connection status will be reported
133      * as open and the {@link #isOpen()} will return <code>true</code>.
134      *
135      * @param socket the socket.
136      * @param params HTTP parameters.
137      * @throws IOException in case of an I/O error.
138      */
139     protected void bind(final Socket socket, final HttpParams params) throws IOException {
140         Args.notNull(socket, "Socket");
141         Args.notNull(params, "HTTP parameters");
142         this.socket = socket;
143 
144         final int buffersize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
145         init(
146                 createSessionInputBuffer(socket, buffersize, params),
147                 createSessionOutputBuffer(socket, buffersize, params),
148                 params);
149 
150         this.open = true;
151     }
152 
153     protected Socket getSocket() {
154         return this.socket;
155     }
156 
157     public boolean isOpen() {
158         return this.open;
159     }
160 
161     public InetAddress getLocalAddress() {
162         if (this.socket != null) {
163             return this.socket.getLocalAddress();
164         } else {
165             return null;
166         }
167     }
168 
169     public int getLocalPort() {
170         if (this.socket != null) {
171             return this.socket.getLocalPort();
172         } else {
173             return -1;
174         }
175     }
176 
177     public InetAddress getRemoteAddress() {
178         if (this.socket != null) {
179             return this.socket.getInetAddress();
180         } else {
181             return null;
182         }
183     }
184 
185     public int getRemotePort() {
186         if (this.socket != null) {
187             return this.socket.getPort();
188         } else {
189             return -1;
190         }
191     }
192 
193     public void setSocketTimeout(final int timeout) {
194         assertOpen();
195         if (this.socket != null) {
196             try {
197                 this.socket.setSoTimeout(timeout);
198             } catch (final SocketException ignore) {
199                 // It is not quite clear from the Sun's documentation if there are any
200                 // other legitimate cases for a socket exception to be thrown when setting
201                 // SO_TIMEOUT besides the socket being already closed
202             }
203         }
204     }
205 
206     public int getSocketTimeout() {
207         if (this.socket != null) {
208             try {
209                 return this.socket.getSoTimeout();
210             } catch (final SocketException ignore) {
211                 return -1;
212             }
213         } else {
214             return -1;
215         }
216     }
217 
218     public void shutdown() throws IOException {
219         this.open = false;
220         final Socket tmpsocket = this.socket;
221         if (tmpsocket != null) {
222             tmpsocket.close();
223         }
224     }
225 
226     public void close() throws IOException {
227         if (!this.open) {
228             return;
229         }
230         this.open = false;
231         this.open = false;
232         final Socket sock = this.socket;
233         try {
234             doFlush();
235             try {
236                 try {
237                     sock.shutdownOutput();
238                 } catch (final IOException ignore) {
239                 }
240                 try {
241                     sock.shutdownInput();
242                 } catch (final IOException ignore) {
243                 }
244             } catch (final UnsupportedOperationException ignore) {
245                 // if one isn't supported, the other one isn't either
246             }
247         } finally {
248             sock.close();
249         }
250     }
251 
252     private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
253         if (socketAddress instanceof InetSocketAddress) {
254             final InetSocketAddress addr = ((InetSocketAddress) socketAddress);
255             buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
256                 addr.getAddress())
257             .append(':')
258             .append(addr.getPort());
259         } else {
260             buffer.append(socketAddress);
261         }
262     }
263 
264     @Override
265     public String toString() {
266         if (this.socket != null) {
267             final StringBuilder buffer = new StringBuilder();
268             final SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
269             final SocketAddress localAddress = this.socket.getLocalSocketAddress();
270             if (remoteAddress != null && localAddress != null) {
271                 formatAddress(buffer, localAddress);
272                 buffer.append("<->");
273                 formatAddress(buffer, remoteAddress);
274             }
275             return buffer.toString();
276         } else {
277             return super.toString();
278         }
279     }
280 
281 }