1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java $ 3 * $Revision: 652193 $ 4 * $Date: 2008-04-29 17:10:36 -0700 (Tue, 29 Apr 2008) $ 5 * 6 * ==================================================================== 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * 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 32 package org.apache.http.impl.conn; 33 34 import java.io.IOException; 35 import java.net.ConnectException; 36 import java.net.Socket; 37 import java.net.InetAddress; 38 39 import java.net.SocketException; 40 import org.apache.http.HttpHost; 41 import org.apache.http.params.HttpParams; 42 import org.apache.http.params.HttpConnectionParams; 43 import org.apache.http.protocol.HttpContext; 44 45 import org.apache.http.conn.HttpHostConnectException; 46 import org.apache.http.conn.OperatedClientConnection; 47 import org.apache.http.conn.ClientConnectionOperator; 48 import org.apache.http.conn.ConnectTimeoutException; 49 import org.apache.http.conn.scheme.LayeredSocketFactory; 50 import org.apache.http.conn.scheme.PlainSocketFactory; 51 import org.apache.http.conn.scheme.Scheme; 52 import org.apache.http.conn.scheme.SchemeRegistry; 53 import 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 75 public 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 final ConnectException cause; 187 if (ex instanceof ConnectException) { 188 cause = (ConnectException) ex; 189 } else { 190 cause = new ConnectException(ex.getMessage()); 191 cause.initCause(ex); 192 } 193 throw new HttpHostConnectException(target, cause); 194 } 195 // END android-changed 196 } catch (ConnectTimeoutException ex) { 197 if (i == addresses.length - 1) { 198 throw ex; 199 } 200 } 201 } 202 } // openConnection 203 204 205 // non-javadoc, see interface ClientConnectionOperator 206 public void updateSecureConnection(OperatedClientConnection conn, 207 HttpHost target, 208 HttpContext context, 209 HttpParams params) 210 throws IOException { 211 212 213 if (conn == null) { 214 throw new IllegalArgumentException 215 ("Connection must not be null."); 216 } 217 if (target == null) { 218 throw new IllegalArgumentException 219 ("Target host must not be null."); 220 } 221 //@@@ is context allowed to be null? 222 if (params == null) { 223 throw new IllegalArgumentException 224 ("Parameters must not be null."); 225 } 226 if (!conn.isOpen()) { 227 throw new IllegalArgumentException 228 ("Connection must be open."); 229 } 230 231 final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); 232 if (!(schm.getSocketFactory() instanceof LayeredSocketFactory)) { 233 throw new IllegalArgumentException 234 ("Target scheme (" + schm.getName() + 235 ") must have layered socket factory."); 236 } 237 238 final LayeredSocketFactory lsf = (LayeredSocketFactory) schm.getSocketFactory(); 239 final Socket sock; 240 try { 241 sock = lsf.createSocket 242 (conn.getSocket(), target.getHostName(), schm.resolvePort(target.getPort()), true); 243 } catch (ConnectException ex) { 244 throw new HttpHostConnectException(target, ex); 245 } 246 prepareSocket(sock, context, params); 247 conn.update(sock, target, lsf.isSecure(sock), params); 248 //@@@ error handling: close the layered socket in case of exception? 249 250 } // updateSecureConnection 251 252 253 /** 254 * Performs standard initializations on a newly created socket. 255 * 256 * @param sock the socket to prepare 257 * @param context the context for the connection 258 * @param params the parameters from which to prepare the socket 259 * 260 * @throws IOException in case of an IO problem 261 */ 262 protected void prepareSocket(Socket sock, HttpContext context, 263 HttpParams params) 264 throws IOException { 265 266 // context currently not used, but derived classes may need it 267 //@@@ is context allowed to be null? 268 269 sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); 270 sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); 271 272 int linger = HttpConnectionParams.getLinger(params); 273 if (linger >= 0) { 274 sock.setSoLinger(linger > 0, linger); 275 } 276 277 } // prepareSocket 278 279 280 } // class DefaultClientConnectionOperator 281