1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java $ 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * $Revision: 652193 $ 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * $Date: 2008-04-29 17:10:36 -0700 (Tue, 29 Apr 2008) $ 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ==================================================================== 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Licensed to the Apache Software Foundation (ASF) under one 8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * or more contributor license agreements. See the NOTICE file 909cda4fad9681e8500485ef0b71974d16c28fcc3Elliott Hughes * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 * ==================================================================== 24 * 25 * This software consists of voluntary contributions made by many 26 * individuals on behalf of the Apache Software Foundation. For more 27 * information on the Apache Software Foundation, please see 28 * <http://www.apache.org/>. 29 * 30 */ 31 32package org.apache.http.impl.conn; 33 34import java.io.IOException; 35import java.net.ConnectException; 36import java.net.Socket; 37import java.net.InetAddress; 38 39import java.net.SocketException; 40import org.apache.http.HttpHost; 41import org.apache.http.params.HttpParams; 42import org.apache.http.params.HttpConnectionParams; 43import org.apache.http.protocol.HttpContext; 44 45import org.apache.http.conn.HttpHostConnectException; 46import org.apache.http.conn.OperatedClientConnection; 47import org.apache.http.conn.ClientConnectionOperator; 48import org.apache.http.conn.ConnectTimeoutException; 49import org.apache.http.conn.scheme.LayeredSocketFactory; 50import org.apache.http.conn.scheme.PlainSocketFactory; 51import org.apache.http.conn.scheme.Scheme; 52import org.apache.http.conn.scheme.SchemeRegistry; 53import org.apache.http.conn.scheme.SocketFactory; 54 55 56/** 57 * Default implementation of a 58 * {@link ClientConnectionOperator ClientConnectionOperator}. 59 * It uses a {@link SchemeRegistry SchemeRegistry} to look up 60 * {@link SocketFactory SocketFactory} objects. 61 * 62 * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> 63 * 64 * 65 * <!-- empty lines to avoid svn diff problems --> 66 * @version $Revision: 652193 $ $Date: 2008-04-29 17:10:36 -0700 (Tue, 29 Apr 2008) $ 67 * 68 * @since 4.0 69 * 70 * @deprecated Please use {@link java.net.URL#openConnection} instead. 71 * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 72 * for further details. 73 */ 74@Deprecated 75public class DefaultClientConnectionOperator 76 implements ClientConnectionOperator { 77 78 private static final PlainSocketFactory staticPlainSocketFactory = new PlainSocketFactory(); 79 80 /** The scheme registry for looking up socket factories. */ 81 protected SchemeRegistry schemeRegistry; 82 83 84 /** 85 * Creates a new client connection operator for the given scheme registry. 86 * 87 * @param schemes the scheme registry 88 */ 89 public DefaultClientConnectionOperator(SchemeRegistry schemes) { 90 if (schemes == null) { 91 throw new IllegalArgumentException 92 ("Scheme registry must not be null."); 93 } 94 schemeRegistry = schemes; 95 } 96 97 98 // non-javadoc, see interface ClientConnectionOperator 99 public OperatedClientConnection createConnection() { 100 return new DefaultClientConnection(); 101 } 102 103 104 // non-javadoc, see interface ClientConnectionOperator 105 public void openConnection(OperatedClientConnection conn, 106 HttpHost target, 107 InetAddress local, 108 HttpContext context, 109 HttpParams params) 110 throws IOException { 111 112 if (conn == null) { 113 throw new IllegalArgumentException 114 ("Connection must not be null."); 115 } 116 if (target == null) { 117 throw new IllegalArgumentException 118 ("Target host must not be null."); 119 } 120 // local address may be null 121 //@@@ is context allowed to be null? 122 if (params == null) { 123 throw new IllegalArgumentException 124 ("Parameters must not be null."); 125 } 126 if (conn.isOpen()) { 127 throw new IllegalArgumentException 128 ("Connection must not be open."); 129 } 130 131 final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); 132 final SocketFactory sf = schm.getSocketFactory(); 133 final SocketFactory plain_sf; 134 final LayeredSocketFactory layered_sf; 135 if (sf instanceof LayeredSocketFactory) { 136 plain_sf = staticPlainSocketFactory; 137 layered_sf = (LayeredSocketFactory)sf; 138 } else { 139 plain_sf = sf; 140 layered_sf = null; 141 } 142 InetAddress[] addresses = InetAddress.getAllByName(target.getHostName()); 143 144 for (int i = 0; i < addresses.length; ++i) { 145 Socket sock = plain_sf.createSocket(); 146 conn.opening(sock, target); 147 148 try { 149 Socket connsock = plain_sf.connectSocket(sock, 150 addresses[i].getHostAddress(), 151 schm.resolvePort(target.getPort()), 152 local, 0, params); 153 if (sock != connsock) { 154 sock = connsock; 155 conn.opening(sock, target); 156 } 157 /* 158 * prepareSocket is called on the just connected 159 * socket before the creation of the layered socket to 160 * ensure that desired socket options such as 161 * TCP_NODELAY, SO_RCVTIMEO, SO_LINGER will be set 162 * before any I/O is performed on the socket. This 163 * happens in the common case as 164 * SSLSocketFactory.createSocket performs hostname 165 * verification which requires that SSL handshaking be 166 * performed. 167 */ 168 prepareSocket(sock, context, params); 169 if (layered_sf != null) { 170 Socket layeredsock = layered_sf.createSocket(sock, 171 target.getHostName(), 172 schm.resolvePort(target.getPort()), 173 true); 174 if (layeredsock != sock) { 175 conn.opening(layeredsock, target); 176 } 177 conn.openCompleted(sf.isSecure(layeredsock), params); 178 } else { 179 conn.openCompleted(sf.isSecure(sock), params); 180 } 181 break; 182 // BEGIN android-changed 183 // catch SocketException to cover any kind of connect failure 184 } catch (SocketException ex) { 185 if (i == addresses.length - 1) { 186 ConnectException cause = ex instanceof ConnectException 187 ? (ConnectException) ex : new ConnectException(ex.getMessage(), ex); 188 throw new HttpHostConnectException(target, cause); 189 } 190 // END android-changed 191 } catch (ConnectTimeoutException ex) { 192 if (i == addresses.length - 1) { 193 throw ex; 194 } 195 } 196 } 197 } // openConnection 198 199 200 // non-javadoc, see interface ClientConnectionOperator 201 public void updateSecureConnection(OperatedClientConnection conn, 202 HttpHost target, 203 HttpContext context, 204 HttpParams params) 205 throws IOException { 206 207 208 if (conn == null) { 209 throw new IllegalArgumentException 210 ("Connection must not be null."); 211 } 212 if (target == null) { 213 throw new IllegalArgumentException 214 ("Target host must not be null."); 215 } 216 //@@@ is context allowed to be null? 217 if (params == null) { 218 throw new IllegalArgumentException 219 ("Parameters must not be null."); 220 } 221 if (!conn.isOpen()) { 222 throw new IllegalArgumentException 223 ("Connection must be open."); 224 } 225 226 final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); 227 if (!(schm.getSocketFactory() instanceof LayeredSocketFactory)) { 228 throw new IllegalArgumentException 229 ("Target scheme (" + schm.getName() + 230 ") must have layered socket factory."); 231 } 232 233 final LayeredSocketFactory lsf = (LayeredSocketFactory) schm.getSocketFactory(); 234 final Socket sock; 235 try { 236 sock = lsf.createSocket 237 (conn.getSocket(), target.getHostName(), schm.resolvePort(target.getPort()), true); 238 } catch (ConnectException ex) { 239 throw new HttpHostConnectException(target, ex); 240 } 241 prepareSocket(sock, context, params); 242 conn.update(sock, target, lsf.isSecure(sock), params); 243 //@@@ error handling: close the layered socket in case of exception? 244 245 } // updateSecureConnection 246 247 248 /** 249 * Performs standard initializations on a newly created socket. 250 * 251 * @param sock the socket to prepare 252 * @param context the context for the connection 253 * @param params the parameters from which to prepare the socket 254 * 255 * @throws IOException in case of an IO problem 256 */ 257 protected void prepareSocket(Socket sock, HttpContext context, 258 HttpParams params) 259 throws IOException { 260 261 // context currently not used, but derived classes may need it 262 //@@@ is context allowed to be null? 263 264 sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); 265 sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); 266 267 int linger = HttpConnectionParams.getLinger(params); 268 if (linger >= 0) { 269 sock.setSoLinger(linger > 0, linger); 270 } 271 272 } // prepareSocket 273 274 275} // class DefaultClientConnectionOperator 276