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 */ DefaultClientConnectionOperator(SchemeRegistry schemes)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 createConnection()99 public OperatedClientConnection createConnection() { 100 return new DefaultClientConnection(); 101 } 102 103 104 // non-javadoc, see interface ClientConnectionOperator openConnection(OperatedClientConnection conn, HttpHost target, InetAddress local, HttpContext context, HttpParams params)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 updateSecureConnection(OperatedClientConnection conn, HttpHost target, HttpContext context, HttpParams params)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 */ prepareSocket(Socket sock, HttpContext context, HttpParams params)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