1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.conn;
29
30 import java.io.IOException;
31 import java.net.ConnectException;
32 import java.net.InetAddress;
33 import java.net.InetSocketAddress;
34 import java.net.Socket;
35 import java.net.UnknownHostException;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.http.HttpHost;
40 import org.apache.http.annotation.ThreadSafe;
41 import org.apache.http.client.protocol.ClientContext;
42 import org.apache.http.conn.ClientConnectionOperator;
43 import org.apache.http.conn.ConnectTimeoutException;
44 import org.apache.http.conn.DnsResolver;
45 import org.apache.http.conn.HttpHostConnectException;
46 import org.apache.http.conn.HttpInetSocketAddress;
47 import org.apache.http.conn.OperatedClientConnection;
48 import org.apache.http.conn.scheme.Scheme;
49 import org.apache.http.conn.scheme.SchemeLayeredSocketFactory;
50 import org.apache.http.conn.scheme.SchemeRegistry;
51 import org.apache.http.conn.scheme.SchemeSocketFactory;
52 import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
53 import org.apache.http.params.HttpConnectionParams;
54 import org.apache.http.params.HttpParams;
55 import org.apache.http.protocol.HttpContext;
56 import org.apache.http.util.Args;
57 import org.apache.http.util.Asserts;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 @Deprecated
91 @ThreadSafe
92 public class DefaultClientConnectionOperator implements ClientConnectionOperator {
93
94 private final Log log = LogFactory.getLog(getClass());
95
96
97 protected final SchemeRegistry schemeRegistry;
98
99
100 protected final DnsResolver dnsResolver;
101
102
103
104
105
106
107
108
109 public DefaultClientConnectionOperator(final SchemeRegistry schemes) {
110 Args.notNull(schemes, "Scheme registry");
111 this.schemeRegistry = schemes;
112 this.dnsResolver = new SystemDefaultDnsResolver();
113 }
114
115
116
117
118
119
120
121
122
123
124 public DefaultClientConnectionOperator(final SchemeRegistry schemes,final DnsResolver dnsResolver) {
125 Args.notNull(schemes, "Scheme registry");
126
127 Args.notNull(dnsResolver, "DNS resolver");
128
129 this.schemeRegistry = schemes;
130 this.dnsResolver = dnsResolver;
131 }
132
133 public OperatedClientConnection createConnection() {
134 return new DefaultClientConnection();
135 }
136
137 private SchemeRegistry getSchemeRegistry(final HttpContext context) {
138 SchemeRegistry reg = (SchemeRegistry) context.getAttribute(
139 ClientContext.SCHEME_REGISTRY);
140 if (reg == null) {
141 reg = this.schemeRegistry;
142 }
143 return reg;
144 }
145
146 public void openConnection(
147 final OperatedClientConnection conn,
148 final HttpHost target,
149 final InetAddress local,
150 final HttpContext context,
151 final HttpParams params) throws IOException {
152 Args.notNull(conn, "Connection");
153 Args.notNull(target, "Target host");
154 Args.notNull(params, "HTTP parameters");
155 Asserts.check(!conn.isOpen(), "Connection must not be open");
156
157 final SchemeRegistry registry = getSchemeRegistry(context);
158 final Scheme schm = registry.getScheme(target.getSchemeName());
159 final SchemeSocketFactory sf = schm.getSchemeSocketFactory();
160
161 final InetAddress[] addresses = resolveHostname(target.getHostName());
162 final int port = schm.resolvePort(target.getPort());
163 for (int i = 0; i < addresses.length; i++) {
164 final InetAddress address = addresses[i];
165 final boolean last = i == addresses.length - 1;
166
167 Socket sock = sf.createSocket(params);
168 conn.opening(sock, target);
169
170 final InetSocketAddress remoteAddress = new HttpInetSocketAddress(target, address, port);
171 InetSocketAddress localAddress = null;
172 if (local != null) {
173 localAddress = new InetSocketAddress(local, 0);
174 }
175 if (this.log.isDebugEnabled()) {
176 this.log.debug("Connecting to " + remoteAddress);
177 }
178 try {
179 final Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params);
180 if (sock != connsock) {
181 sock = connsock;
182 conn.opening(sock, target);
183 }
184 prepareSocket(sock, context, params);
185 conn.openCompleted(sf.isSecure(sock), params);
186 return;
187 } catch (final ConnectException ex) {
188 if (last) {
189 throw new HttpHostConnectException(target, ex);
190 }
191 } catch (final ConnectTimeoutException ex) {
192 if (last) {
193 throw ex;
194 }
195 }
196 if (this.log.isDebugEnabled()) {
197 this.log.debug("Connect to " + remoteAddress + " timed out. " +
198 "Connection will be retried using another IP address");
199 }
200 }
201 }
202
203 public void updateSecureConnection(
204 final OperatedClientConnection conn,
205 final HttpHost target,
206 final HttpContext context,
207 final HttpParams params) throws IOException {
208 Args.notNull(conn, "Connection");
209 Args.notNull(target, "Target host");
210 Args.notNull(params, "Parameters");
211 Asserts.check(conn.isOpen(), "Connection must be open");
212
213 final SchemeRegistry registry = getSchemeRegistry(context);
214 final Scheme schm = registry.getScheme(target.getSchemeName());
215 Asserts.check(schm.getSchemeSocketFactory() instanceof LayeredConnectionSocketFactory,
216 "Socket factory must implement SchemeLayeredSocketFactory");
217 final SchemeLayeredSocketFactory lsf = (SchemeLayeredSocketFactory) schm.getSchemeSocketFactory();
218 Socket sock;
219 try {
220 sock = lsf.createLayeredSocket(
221 conn.getSocket(), target.getHostName(), target.getPort(), params);
222 } catch (final ConnectException ex) {
223 throw new HttpHostConnectException(target, ex);
224 }
225 prepareSocket(sock, context, params);
226 conn.update(sock, target, lsf.isSecure(sock), params);
227 }
228
229
230
231
232
233
234
235
236
237
238 protected void prepareSocket(
239 final Socket sock,
240 final HttpContext context,
241 final HttpParams params) throws IOException {
242 sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
243 sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
244
245 final int linger = HttpConnectionParams.getLinger(params);
246 if (linger >= 0) {
247 sock.setSoLinger(linger > 0, linger);
248 }
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265 protected InetAddress[] resolveHostname(final String host) throws UnknownHostException {
266 return dnsResolver.resolve(host);
267 }
268
269 }
270