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