Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2010 Google Inc. | 2 * Copyright (c) 2010 Google Inc. |
3 * | 3 * |
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not u se this file except | 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not u se this file except |
5 * in compliance with the License. You may obtain a copy of the License at | 5 * in compliance with the License. You may obtain a copy of the License at |
6 * | 6 * |
7 * http://www.apache.org/licenses/LICENSE-2.0 | 7 * http://www.apache.org/licenses/LICENSE-2.0 |
8 * | 8 * |
9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License | 9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License |
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express | 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express |
(...skipping 22 matching lines...) Expand all Loading... | |
33 import java.util.HashMap; | 33 import java.util.HashMap; |
34 import java.util.List; | 34 import java.util.List; |
35 import java.util.logging.Level; | 35 import java.util.logging.Level; |
36 import java.util.logging.Logger; | 36 import java.util.logging.Logger; |
37 import java.util.zip.GZIPInputStream; | 37 import java.util.zip.GZIPInputStream; |
38 | 38 |
39 /** | 39 /** |
40 * HTTP response. | 40 * HTTP response. |
41 * | 41 * |
42 * <p> | 42 * <p> |
43 * Callers should call {@link #disconnect} when the HTTP response object is no l onger needed. | |
44 * Example usage: | |
45 * </p> | |
46 * | |
47 *<pre> | |
48 HttpResponse response = request.execute(); | |
49 try { | |
50 // process the HTTP response object | |
51 } finally { | |
52 response.disconnect(); | |
yanivi
2012/05/22 15:47:02
Ouch! I see the bug now (I'm pretty sure I saw it
rmistry
2012/05/22 16:25:02
Let me know what you think of what I did in HttpRe
| |
53 } | |
54 *</pre> | |
55 * | |
56 * <p> | |
43 * Implementation is not thread-safe. | 57 * Implementation is not thread-safe. |
44 * </p> | 58 * </p> |
45 * | 59 * |
46 * @since 1.0 | 60 * @since 1.0 |
47 * @author Yaniv Inbar | 61 * @author Yaniv Inbar |
48 */ | 62 */ |
49 public final class HttpResponse { | 63 public final class HttpResponse { |
50 | 64 |
51 /** HTTP response content or {@code null} before {@link #getContent()}. */ | 65 /** HTTP response content or {@code null} before {@link #getContent()}. */ |
52 private InputStream content; | 66 private InputStream content; |
53 | 67 |
54 /** Content encoding or {@code null}. */ | 68 /** Content encoding or {@code null}. */ |
55 private final String contentEncoding; | 69 private final String contentEncoding; |
56 | 70 |
57 /** | 71 /** |
58 * Content length or less than zero if not known. May be reset by {@link #getC ontent} if response | 72 * Content length or less than zero if not known. May be reset by {@link #getC ontent} if response |
59 * had GZip compression. | 73 * had GZip compression. |
60 */ | 74 */ |
61 private long contentLength; | 75 private long contentLength; |
62 | 76 |
63 /** Content type or {@code null} for none. */ | 77 /** Content type or {@code null} for none. */ |
64 private final String contentType; | 78 private final String contentType; |
65 | 79 |
66 /** HTTP headers. */ | 80 /** HTTP headers. */ |
67 private final HttpHeaders headers; | 81 private final HttpHeaders headers; |
68 | 82 |
69 /** Low-level HTTP response. */ | 83 /** Low-level HTTP response. */ |
70 private LowLevelHttpResponse response; | 84 LowLevelHttpResponse response; |
71 | 85 |
72 /** Status code. */ | 86 /** Status code. */ |
73 private final int statusCode; | 87 private final int statusCode; |
74 | 88 |
75 /** Status message or {@code null}. */ | 89 /** Status message or {@code null}. */ |
76 private final String statusMessage; | 90 private final String statusMessage; |
77 | 91 |
78 /** HTTP transport. */ | 92 /** HTTP transport. */ |
79 private final HttpTransport transport; | 93 private final HttpTransport transport; |
80 | 94 |
(...skipping 24 matching lines...) Expand all Loading... | |
105 | 119 |
106 /** | 120 /** |
107 * Determines whether logging should be enabled on this response. | 121 * Determines whether logging should be enabled on this response. |
108 * | 122 * |
109 * <p> | 123 * <p> |
110 * Defaults to {@link HttpRequest#isLoggingEnabled()}. | 124 * Defaults to {@link HttpRequest#isLoggingEnabled()}. |
111 * </p> | 125 * </p> |
112 */ | 126 */ |
113 private boolean loggingEnabled; | 127 private boolean loggingEnabled; |
114 | 128 |
129 /** Signals whether the content has been read from the input stream. */ | |
130 private boolean contentRead; | |
131 | |
115 HttpResponse(HttpRequest request, LowLevelHttpResponse response) { | 132 HttpResponse(HttpRequest request, LowLevelHttpResponse response) { |
116 this.request = request; | 133 this.request = request; |
117 transport = request.getTransport(); | 134 transport = request.getTransport(); |
118 headers = request.getResponseHeaders(); | 135 headers = request.getResponseHeaders(); |
119 contentLoggingLimit = request.getContentLoggingLimit(); | 136 contentLoggingLimit = request.getContentLoggingLimit(); |
120 loggingEnabled = request.isLoggingEnabled(); | 137 loggingEnabled = request.isLoggingEnabled(); |
121 this.response = response; | 138 this.response = response; |
122 contentLength = response.getContentLength(); | 139 contentLength = response.getContentLength(); |
123 contentType = response.getContentType(); | 140 contentType = response.getContentType(); |
124 contentEncoding = response.getContentEncoding(); | 141 contentEncoding = response.getContentEncoding(); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 | 393 |
377 /** | 394 /** |
378 * Returns the content of the HTTP response. | 395 * Returns the content of the HTTP response. |
379 * <p> | 396 * <p> |
380 * The result is cached, so subsequent calls will be fast. | 397 * The result is cached, so subsequent calls will be fast. |
381 * | 398 * |
382 * @return input stream content of the HTTP response or {@code null} for none | 399 * @return input stream content of the HTTP response or {@code null} for none |
383 * @throws IOException I/O exception | 400 * @throws IOException I/O exception |
384 */ | 401 */ |
385 public InputStream getContent() throws IOException { | 402 public InputStream getContent() throws IOException { |
386 LowLevelHttpResponse response = this.response; | 403 if (contentRead) { |
yanivi
2012/05/22 15:47:02
[optional] a bit more elegant to do:
if (!content
rmistry
2012/05/22 16:25:02
Done.
| |
387 if (response == null) { | |
388 return content; | 404 return content; |
389 } | 405 } |
390 InputStream content = this.response.getContent(); | 406 InputStream content = this.response.getContent(); |
391 this.response = null; | |
392 if (content != null) { | 407 if (content != null) { |
393 // gzip encoding (wrap content with GZipInputStream) | 408 // gzip encoding (wrap content with GZipInputStream) |
394 String contentEncoding = this.contentEncoding; | 409 String contentEncoding = this.contentEncoding; |
395 if (contentEncoding != null && contentEncoding.contains("gzip")) { | 410 if (contentEncoding != null && contentEncoding.contains("gzip")) { |
396 content = new GZIPInputStream(content); | 411 content = new GZIPInputStream(content); |
397 contentLength = -1; | 412 contentLength = -1; |
398 } | 413 } |
399 // logging (wrap content with LoggingInputStream) | 414 // logging (wrap content with LoggingInputStream) |
400 Logger logger = HttpTransport.LOGGER; | 415 Logger logger = HttpTransport.LOGGER; |
401 if (loggingEnabled && logger.isLoggable(Level.CONFIG)) { | 416 if (loggingEnabled && logger.isLoggable(Level.CONFIG)) { |
402 content = new LoggingInputStream(content, logger, Level.CONFIG, contentL oggingLimit); | 417 content = new LoggingInputStream(content, logger, Level.CONFIG, contentL oggingLimit); |
403 } | 418 } |
404 this.content = content; | 419 this.content = content; |
405 } | 420 } |
421 contentRead = true; | |
406 return content; | 422 return content; |
407 } | 423 } |
408 | 424 |
409 /** | 425 /** |
410 * Writes the content of the HTTP response into the given destination output s tream. | 426 * Writes the content of the HTTP response into the given destination output s tream. |
411 * | 427 * |
412 * <p> | 428 * <p> |
413 * Sample usage: <code> | 429 * Sample usage: <code> |
414 HttpRequest request = | 430 HttpRequest request = |
415 requestFactory.buildGetRequest(new GenericUrl( | 431 requestFactory.buildGetRequest(new GenericUrl( |
(...skipping 30 matching lines...) Expand all Loading... | |
446 * Closes the content of the HTTP response from {@link #getContent()}, ignorin g any content. | 462 * Closes the content of the HTTP response from {@link #getContent()}, ignorin g any content. |
447 */ | 463 */ |
448 public void ignore() throws IOException { | 464 public void ignore() throws IOException { |
449 InputStream content = getContent(); | 465 InputStream content = getContent(); |
450 if (content != null) { | 466 if (content != null) { |
451 content.close(); | 467 content.close(); |
452 } | 468 } |
453 } | 469 } |
454 | 470 |
455 /** | 471 /** |
456 * Disconnect using {@link LowLevelHttpResponse#disconnect()}. | 472 * Close the HTTP response content and disconnect using {@link LowLevelHttpRes ponse#disconnect()}. |
473 * | |
474 * <p> | |
475 * Upgrade warning: since version 1.10 {@link #disconnect} now closes the HTTP response content | |
476 * input stream. It was not closed by this method prior to version 1.10. | |
477 * </p> | |
457 * | 478 * |
458 * @since 1.4 | 479 * @since 1.4 |
459 */ | 480 */ |
460 public void disconnect() throws IOException { | 481 public void disconnect() throws IOException { |
482 ignore(); | |
461 response.disconnect(); | 483 response.disconnect(); |
462 } | 484 } |
463 | 485 |
464 /** | 486 /** |
465 * Returns the HTTP response content parser to use for the content type of thi s HTTP response or | 487 * Returns the HTTP response content parser to use for the content type of thi s HTTP response or |
466 * {@code null} for none. | 488 * {@code null} for none. |
467 */ | 489 */ |
468 public HttpParser getParser() { | 490 public HttpParser getParser() { |
469 return request.getParser(contentType); | 491 return request.getParser(contentType); |
470 } | 492 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 } | 539 } |
518 System.arraycopy(tmp, 0, buffer, length, bytesRead); | 540 System.arraycopy(tmp, 0, buffer, length, bytesRead); |
519 length += bytesRead; | 541 length += bytesRead; |
520 } | 542 } |
521 return new String(buffer, 0, length, "UTF-8"); | 543 return new String(buffer, 0, length, "UTF-8"); |
522 } finally { | 544 } finally { |
523 content.close(); | 545 content.close(); |
524 } | 546 } |
525 } | 547 } |
526 } | 548 } |
OLD | NEW |