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.Contract;
41 import org.apache.http.annotation.ThreadingBehavior;
42 import org.apache.http.client.protocol.ClientContext;
43 import org.apache.http.conn.ClientConnectionOperator;
44 import org.apache.http.conn.ConnectTimeoutException;
45 import org.apache.http.conn.DnsResolver;
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.params.HttpConnectionParams;
53 import org.apache.http.params.HttpParams;
54 import org.apache.http.protocol.HttpContext;
55 import org.apache.http.util.Args;
56 import org.apache.http.util.Asserts;
57
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 @Deprecated
90 @Contract(threading = ThreadingBehavior.SAFE_CONDITIONAL)
91 public class DefaultClientConnectionOperator implements ClientConnectionOperator {
92
93 private final Log log = LogFactory.getLog(getClass());
94
95
96 protected final SchemeRegistry schemeRegistry;
97
98
99 protected final DnsResolver dnsResolver;
100
101
102
103
104
105
106
107
108 public DefaultClientConnectionOperator(final SchemeRegistry schemes) {
109 Args.notNull(schemes, "Scheme registry");
110 this.schemeRegistry = schemes;
111 this.dnsResolver = new SystemDefaultDnsResolver();
112 }
113
114
115
116
117
118
119
120
121
122
123 public DefaultClientConnectionOperator(final SchemeRegistry schemes,final DnsResolver dnsResolver) {
124 Args.notNull(schemes, "Scheme registry");
125
126 Args.notNull(dnsResolver, "DNS resolver");
127
128 this.schemeRegistry = schemes;
129 this.dnsResolver = dnsResolver;
130 }
131
132 @Override
133 public OperatedClientConnection createConnection() {
134 return new DefaultClientConnection();
135 }
136
137 private SchemeRegistry getSchemeRegistry(final HttpContext context) {
138 SchemeRegistry/../../../org/apache/http/conn/scheme/SchemeRegistry.html#SchemeRegistry">SchemeRegistry reg = (SchemeRegistry) context.getAttribute(
139 ClientContext.SCHEME_REGISTRY);
140 if (reg == null) {
141 reg = this.schemeRegistry;
142 }
143 return reg;
144 }
145
146 @Override
147 public void openConnection(
148 final OperatedClientConnection conn,
149 final HttpHost target,
150 final InetAddress local,
151 final HttpContext context,
152 final HttpParams params) throws IOException {
153 Args.notNull(conn, "Connection");
154 Args.notNull(target, "Target host");
155 Args.notNull(params, "HTTP parameters");
156 Asserts.check(!conn.isOpen(), "Connection must not be open");
157
158 final SchemeRegistry registry = getSchemeRegistry(context);
159 final Scheme schm = registry.getScheme(target.getSchemeName());
160 final SchemeSocketFactory sf = schm.getSchemeSocketFactory();
161
162 final InetAddress[] addresses = resolveHostname(target.getHostName());
163 final int port = schm.resolvePort(target.getPort());
164 for (int i = 0; i < addresses.length; i++) {
165 final InetAddress address = addresses[i];
166 final boolean last = i == addresses.length - 1;
167
168 Socket sock = sf.createSocket(params);
169 conn.opening(sock, target);
170
171 final InetSocketAddress remoteAddress = new HttpInetSocketAddress(target, address, port);
172 InetSocketAddress localAddress = null;
173 if (local != null) {
174 localAddress = new InetSocketAddress(local, 0);
175 }
176 if (this.log.isDebugEnabled()) {
177 this.log.debug("Connecting to " + remoteAddress);
178 }
179 try {
180 final Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params);
181 if (sock != connsock) {
182 sock = connsock;
183 conn.opening(sock, target);
184 }
185 prepareSocket(sock, context, params);
186 conn.openCompleted(sf.isSecure(sock), params);
187 return;
188 } catch (final ConnectException ex) {
189 if (last) {
190 throw ex;
191 }
192 } catch (final ConnectTimeoutException ex) {
193 if (last) {
194 throw ex;
195 }
196 }
197 if (this.log.isDebugEnabled()) {
198 this.log.debug("Connect to " + remoteAddress + " timed out. " +
199 "Connection will be retried using another IP address");
200 }
201 }
202 }
203
204 @Override
205 public void updateSecureConnection(
206 final OperatedClientConnection conn,
207 final HttpHost target,
208 final HttpContext context,
209 final HttpParams params) throws IOException {
210 Args.notNull(conn, "Connection");
211 Args.notNull(target, "Target host");
212 Args.notNull(params, "Parameters");
213 Asserts.check(conn.isOpen(), "Connection must be open");
214
215 final SchemeRegistry registry = getSchemeRegistry(context);
216 final Scheme schm = registry.getScheme(target.getSchemeName());
217 Asserts.check(schm.getSchemeSocketFactory() instanceof SchemeLayeredSocketFactory,
218 "Socket factory must implement SchemeLayeredSocketFactory");
219 final SchemeLayeredSocketFactoryg/apache/http/conn/scheme/SchemeLayeredSocketFactory.html#SchemeLayeredSocketFactory">SchemeLayeredSocketFactory lsf = (SchemeLayeredSocketFactory) schm.getSchemeSocketFactory();
220 final Socket sock = lsf.createLayeredSocket(
221 conn.getSocket(), target.getHostName(), schm.resolvePort(target.getPort()), params);
222 prepareSocket(sock, context, params);
223 conn.update(sock, target, lsf.isSecure(sock), params);
224 }
225
226
227
228
229
230
231
232
233
234
235 protected void prepareSocket(
236 final Socket sock,
237 final HttpContext context,
238 final HttpParams params) throws IOException {
239 sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
240 sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
241
242 final int linger = HttpConnectionParams.getLinger(params);
243 if (linger >= 0) {
244 sock.setSoLinger(linger > 0, linger);
245 }
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 protected InetAddress[] resolveHostname(final String host) throws UnknownHostException {
263 return dnsResolver.resolve(host);
264 }
265
266 }
267