1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.latka.http;
18
19 import java.net.URL;
20 import java.io.ByteArrayInputStream;
21 import java.io.InputStream;
22 import java.io.IOException;
23 import java.util.List;
24 import java.util.LinkedList;
25
26 import org.apache.commons.httpclient.HostConfiguration;
27 import org.apache.commons.httpclient.UsernamePasswordCredentials;
28 import org.apache.commons.httpclient.HttpClient;
29 import org.apache.commons.httpclient.HttpException;
30 import org.apache.commons.httpclient.HttpMethod;
31 import org.apache.commons.httpclient.HttpState;
32 import org.apache.commons.httpclient.HttpMethodBase;
33 import org.apache.commons.httpclient.methods.PostMethod;
34
35 import org.apache.log4j.Category;
36
37
38
39
40
41
42
43
44
45
46
47
48 public class RequestImpl implements Request {
49
50
51 public static final int HTTP_PORT = 80;
52
53
54 public static final int HTTPS_PORT = 443;
55
56 protected String _host = null;
57
58 protected int _port = -1;
59
60 protected int _method = -1;
61
62 protected SessionImpl _session = null;
63
64 protected Credentials _credentials = null;
65
66 protected HttpMethod _httpMethod = null;
67
68 protected URL _targetURL = null;
69
70 protected String _query = null;
71
72 protected long _requestTiming = -1;
73
74 protected String _label = null;
75
76 protected RequestHeaders _requestHeaders = new RequestHeadersImpl();
77
78 protected Parameters _parameters = new ParametersImpl();
79
80 protected String _requestBody = null;
81
82
83 protected boolean _followRedirects = true;
84
85 protected HttpClient _httpClient = new HttpClient();
86
87 private Proxy _proxy = null;
88
89 protected static final Category _log =
90 Category.getInstance(RequestImpl.class);
91
92
93
94
95 private static final String HTTP_10 = "1.0";
96
97
98
99 private static final String HTTP_11 = "1.1";
100
101 protected String _httpVersion = HTTP_11;
102
103 protected List _visitedURLs = new LinkedList();
104
105
106
107
108
109
110
111
112
113
114 protected RequestImpl(URL url, int httpMethod, HttpState state,
115 SessionImpl session) {
116 this(null, url, httpMethod, state, session, true);
117 }
118
119
120
121
122
123
124
125
126
127
128
129 protected RequestImpl(String label, URL url, int httpMethod,
130 HttpState state, SessionImpl session, boolean followRedirects) {
131
132 _followRedirects = followRedirects;
133 _method = httpMethod;
134 _httpClient.setState(state);
135
136 _label = label;
137 _query = url.getQuery();
138
139 _session = session;
140 _targetURL = url;
141 _httpMethod = MethodFactory.getInstance(httpMethod, url);
142 if (_query != null) {
143 _httpMethod.setQueryString(_query);
144 }
145 _httpMethod.setFollowRedirects(followRedirects);
146 }
147
148
149
150
151
152
153
154
155 protected HttpMethod getHttpMethod() {
156 return _httpMethod;
157 }
158
159
160
161
162
163
164 public RequestHeaders getHeaders() {
165 return _requestHeaders;
166 }
167
168
169
170
171
172
173 public void setHeaders(RequestHeaders requestHeaders) {
174 _requestHeaders = requestHeaders;
175 }
176
177
178
179
180
181
182 public Parameters getParameters() {
183 return _parameters;
184 }
185
186
187
188
189
190 public void setRequestBody(String body) {
191 _requestBody = body;
192 }
193
194
195
196
197
198
199 public void setParameters(Parameters parameters) {
200 _parameters = parameters;
201 }
202
203
204
205
206
207
208 public void setCredentials(Credentials credentials) {
209
210
211 UsernamePasswordCredentials creds = new UsernamePasswordCredentials(
212 credentials.getUserName(), credentials.getPassword());
213 _session._state.setCredentials(null, creds);
214 _credentials = credentials;
215 }
216
217 public Credentials getCredentials() {
218 return _credentials;
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232 protected Response executeRequestPerHost() throws IOException {
233
234
235 List headers = _requestHeaders.getHeaders();
236 for (int i = 0; i < headers.size(); ++i) {
237 String[] header = (String[]) headers.get(i);
238 _httpMethod.addRequestHeader(header[0], header[1]);
239 }
240
241 if (_requestBody != null) {
242 InputStream is = new ByteArrayInputStream(
243 _requestBody.getBytes("ISO-8859-1"));
244 ((PostMethod) _httpMethod).setRequestBody(is);
245 } else {
246 List parameters = _parameters.getParameters();
247 for (int i = 0; i < parameters.size(); ++i) {
248 String[] parameter = (String[]) parameters.get(i);
249 addHttpClientParameter(parameter[0], parameter[1]);
250 }
251 }
252
253
254 long startDate = System.currentTimeMillis();
255
256 Response response = null;
257 try {
258
259 openConnection();
260
261 _log.debug("executing request");
262
263 _httpClient.executeMethod(_httpMethod);
264
265 _log.debug("request executed");
266
267 response = new ResponseImpl(this);
268
269
270
271 String sideEffectOnly = response.getResource();
272
273
274
275
276
277
278
279
280 _session.setReferer(new URL(_targetURL.getProtocol(), _host, _port,
281 _httpMethod.getPath()));
282
283 } catch (HttpException e) {
284 throw new IOException(e.toString());
285 } catch (IOException e) {
286
287 throw e;
288 } finally {
289 try {
290 closeConnection();
291
292 } catch (Exception e) {
293 e.printStackTrace();
294 }
295 }
296
297
298 _requestTiming = System.currentTimeMillis() - startDate;
299
300 if (_log.isInfoEnabled()) {
301 _log.info("response obtained (response logging disabled because "
302 + "some responses are binary)");
303 }
304
305 return response;
306 }
307
308
309
310
311
312
313
314
315 public Response execute() throws IOException {
316 Response response = executeRequestPerHost();
317
318 if (followRedirects() == false) {
319 return response;
320 }
321
322 Request lastRequest = this;
323
324
325 while (response.getStatusCode() == 301 || response.getStatusCode() == 302) {
326
327 URL url = new URL(response.getHeader("location"));
328
329 if (_visitedURLs.contains(url.toString())) {
330 return response;
331 }
332
333 Request request = _session.createRequest(lastRequest.getLabel(), url,
334 lastRequest.getMethod(), lastRequest.getVersion(), true, getProxy());
335 request.setParameters(lastRequest.getParameters());
336 request.setHeaders(lastRequest.getHeaders());
337 Credentials credentials = lastRequest.getCredentials();
338 if (credentials != null) {
339 request.setCredentials(credentials);
340 }
341 response = request.execute();
342 _visitedURLs.add(url.toString());
343 lastRequest = request;
344 }
345
346 return response;
347 }
348
349
350
351
352
353
354 public URL getURL() {
355 return _targetURL;
356 }
357
358
359
360
361
362
363 public String getLabel() {
364 return _label;
365 }
366
367
368
369
370
371
372
373 public void addParameter(String name, String value) {
374 _parameters.addParameter(name, value);
375 }
376
377
378
379
380
381
382
383 protected void addHttpClientParameter(String name, String value) {
384 if (name == null) {
385 throw new NullPointerException("name parameter is null");
386 }
387
388 if (value == null) {
389 throw new NullPointerException("value parameter is null");
390 }
391 _log.info("adding parameter, name: " + name + ", value: " + value);
392
393 if (_httpMethod instanceof PostMethod) {
394
395 ((PostMethod) _httpMethod).addParameter(name, value);
396 } else {
397 StringBuffer query = new StringBuffer();
398
399
400 if (_query == null || _query.equals("")) {
401 query.append(name);
402 query.append("=");
403 query.append(value);
404 } else {
405 query.append(_query);
406 query.append("&");
407 query.append(name);
408 query.append("=");
409 query.append(value);
410 }
411 _query = query.toString();
412 ((HttpMethod) _httpMethod).setQueryString(_query);
413 }
414 }
415
416
417
418
419
420
421
422 public void addHeader(String headerName, String headerValue) {
423 _requestHeaders.addHeader(headerName, headerValue);
424 }
425
426
427
428
429
430
431 public Session getSession() {
432 return _session;
433 }
434
435
436
437
438
439 public int getRequestTiming() {
440 return (int) _requestTiming;
441 }
442
443
444
445
446
447
448
449
450 protected void openConnection() throws IOException {
451 _log.debug("Opening connection");
452
453 URL url = getURL();
454 String protocol = url.getProtocol();
455 String host = url.getHost();
456 int port = url.getPort();
457
458
459
460 if (port == -1) {
461 if (protocol.equals("http")) {
462 port = HTTP_PORT;
463 } else if (protocol.equals("https")) {
464 port = HTTPS_PORT;
465 } else {
466 throw new IllegalArgumentException("Unsupported Protocol");
467 }
468 }
469
470
471 _host = host;
472 _port = port;
473
474 HostConfiguration hostConfiguration = _httpClient.getHostConfiguration();
475 hostConfiguration.setHost(host, port, protocol);
476 if (getProxy() != null) {
477 hostConfiguration.setProxy(getProxy().getHost(), getProxy().getPort());
478 }
479
480 _log.debug("connection open");
481 }
482
483
484
485
486
487 protected void closeConnection() throws IOException {
488 _log.debug("closing connection");
489 _httpMethod.releaseConnection();
490 _log.debug("connection closed");
491 }
492
493
494
495
496
497
498 public boolean followRedirects() {
499 return _followRedirects;
500 }
501
502
503
504
505
506
507
508 public int getMethod() {
509 return _method;
510 }
511
512
513
514
515 public Proxy getProxy() {
516 return _proxy;
517 }
518
519
520
521
522 public void setProxy(Proxy proxy) {
523 _proxy = proxy;
524 }
525
526
527
528
529
530
531
532
533 public void setVersion(String version) {
534 ((HttpMethodBase) _httpMethod).setHttp11(!HTTP_10.equals(version));
535 _httpVersion = version;
536 }
537
538
539
540
541
542
543 public String getVersion() {
544 return _httpVersion;
545 }
546 }