Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(525)

Side by Side Diff: google-http-client/src/main/java/com/google/api/client/http/HttpResponse.java

Issue 6225045: Closing input stream in HttpResponse.disconnect and fixing NPE (Closed) Base URL: https://google-http-java-client.googlecode.com/hg/
Patch Set: Addressing code review comments Created 12 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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 14 matching lines...) Expand all
25 import java.util.logging.Level; 25 import java.util.logging.Level;
26 import java.util.logging.Logger; 26 import java.util.logging.Logger;
27 import java.util.regex.Matcher; 27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern; 28 import java.util.regex.Pattern;
29 import java.util.zip.GZIPInputStream; 29 import java.util.zip.GZIPInputStream;
30 30
31 /** 31 /**
32 * HTTP response. 32 * HTTP response.
33 * 33 *
34 * <p> 34 * <p>
35 * Callers should call {@link #disconnect} when the HTTP response object is no l onger needed.
36 * However, {@link #disconnect} does not have to be called if the response strea m is properly
37 * closed. Example usage:
38 * </p>
39 *
40 * <pre>
41 HttpResponse response = request.execute();
42 try {
43 // process the HTTP response object
44 } finally {
45 response.disconnect();
46 }
47 * </pre>
48 *
49 * <p>
35 * Implementation is not thread-safe. 50 * Implementation is not thread-safe.
36 * </p> 51 * </p>
37 * 52 *
38 * @since 1.0 53 * @since 1.0
39 * @author Yaniv Inbar 54 * @author Yaniv Inbar
40 */ 55 */
41 public final class HttpResponse { 56 public final class HttpResponse {
42 57
43 /** Content-Type parameter pattern. */ 58 /** Content-Type parameter pattern. */
44 private static final Pattern CONTENT_TYPE_PARAM_PATTERN = 59 private static final Pattern CONTENT_TYPE_PARAM_PATTERN =
45 Pattern.compile(";\\s*(\\S[^=]*)=([^;]*[^;\\p{Space}])"); 60 Pattern.compile(";\\s*(\\S[^=]*)=([^;]*[^;\\p{Space}])");
46 61
47 /** HTTP response content or {@code null} before {@link #getContent()}. */ 62 /** HTTP response content or {@code null} before {@link #getContent()}. */
48 private InputStream content; 63 private InputStream content;
49 64
50 /** Content encoding or {@code null}. */ 65 /** Content encoding or {@code null}. */
51 private final String contentEncoding; 66 private final String contentEncoding;
52 67
53 /** Content type or {@code null} for none. */ 68 /** Content type or {@code null} for none. */
54 private final String contentType; 69 private final String contentType;
55 70
56 /** HTTP headers. */ 71 /** HTTP headers. */
57 private final HttpHeaders headers; 72 private final HttpHeaders headers;
58 73
59 /** Low-level HTTP response. */ 74 /** Low-level HTTP response. */
60 private LowLevelHttpResponse response; 75 LowLevelHttpResponse response;
61 76
62 /** Status code. */ 77 /** Status code. */
63 private final int statusCode; 78 private final int statusCode;
64 79
65 /** Status message or {@code null}. */ 80 /** Status message or {@code null}. */
66 private final String statusMessage; 81 private final String statusMessage;
67 82
68 /** HTTP transport. */ 83 /** HTTP transport. */
69 private final HttpTransport transport; 84 private final HttpTransport transport;
70 85
(...skipping 24 matching lines...) Expand all
95 110
96 /** 111 /**
97 * Determines whether logging should be enabled on this response. 112 * Determines whether logging should be enabled on this response.
98 * 113 *
99 * <p> 114 * <p>
100 * Defaults to {@link HttpRequest#isLoggingEnabled()}. 115 * Defaults to {@link HttpRequest#isLoggingEnabled()}.
101 * </p> 116 * </p>
102 */ 117 */
103 private boolean loggingEnabled; 118 private boolean loggingEnabled;
104 119
120 /** Signals whether the content has been read from the input stream. */
121 private boolean contentRead;
122
105 HttpResponse(HttpRequest request, LowLevelHttpResponse response) { 123 HttpResponse(HttpRequest request, LowLevelHttpResponse response) {
106 this.request = request; 124 this.request = request;
107 transport = request.getTransport(); 125 transport = request.getTransport();
108 headers = request.getResponseHeaders(); 126 headers = request.getResponseHeaders();
109 contentLoggingLimit = request.getContentLoggingLimit(); 127 contentLoggingLimit = request.getContentLoggingLimit();
110 loggingEnabled = request.isLoggingEnabled(); 128 loggingEnabled = request.isLoggingEnabled();
111 this.response = response; 129 this.response = response;
112 contentType = response.getContentType(); 130 contentType = response.getContentType();
113 contentEncoding = response.getContentEncoding(); 131 contentEncoding = response.getContentEncoding();
114 int code = response.getStatusCode(); 132 int code = response.getStatusCode();
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 326 }
309 327
310 /** 328 /**
311 * Returns the content of the HTTP response. 329 * Returns the content of the HTTP response.
312 * <p> 330 * <p>
313 * The result is cached, so subsequent calls will be fast. 331 * The result is cached, so subsequent calls will be fast.
314 * 332 *
315 * @return input stream content of the HTTP response or {@code null} for none 333 * @return input stream content of the HTTP response or {@code null} for none
316 * @throws IOException I/O exception 334 * @throws IOException I/O exception
317 */ 335 */
318 public InputStream getContent() throws IOException { 336 public InputStream getContent() throws IOException {
yanivi 2012/05/30 21:07:26 would help to add JavaDoc explaining that the cont
yanivi 2012/05/30 21:07:26 implementation of getContent has a similar problem
rmistry 2012/05/31 12:25:38 Done.
rmistry 2012/05/31 12:25:38 Done.
319 LowLevelHttpResponse response = this.response; 337 if (!contentRead) {
320 if (response == null) { 338 InputStream lowLevelResponseContent = this.response.getContent();
321 return content; 339 if (lowLevelResponseContent != null) {
322 } 340 // gzip encoding (wrap content with GZipInputStream)
323 InputStream content = this.response.getContent(); 341 String contentEncoding = this.contentEncoding;
324 this.response = null; 342 if (contentEncoding != null && contentEncoding.contains("gzip")) {
325 if (content != null) { 343 lowLevelResponseContent = new GZIPInputStream(lowLevelResponseContent) ;
326 // gzip encoding (wrap content with GZipInputStream) 344 }
327 String contentEncoding = this.contentEncoding; 345 // logging (wrap content with LoggingInputStream)
328 if (contentEncoding != null && contentEncoding.contains("gzip")) { 346 Logger logger = HttpTransport.LOGGER;
329 content = new GZIPInputStream(content); 347 if (loggingEnabled && logger.isLoggable(Level.CONFIG)) {
348 lowLevelResponseContent = new LoggingInputStream(
349 lowLevelResponseContent, logger, Level.CONFIG, contentLoggingLimit );
350 }
351 content = lowLevelResponseContent;
330 } 352 }
331 // logging (wrap content with LoggingInputStream) 353 contentRead = true;
332 Logger logger = HttpTransport.LOGGER;
333 if (loggingEnabled && logger.isLoggable(Level.CONFIG)) {
334 content = new LoggingInputStream(content, logger, Level.CONFIG, contentL oggingLimit);
335 }
336 this.content = content;
337 } 354 }
338 return content; 355 return content;
339 } 356 }
340 357
341 /** 358 /**
342 * Writes the content of the HTTP response into the given destination output s tream. 359 * Writes the content of the HTTP response into the given destination output s tream.
343 * 360 *
344 * <p> 361 * <p>
345 * Sample usage: <code> 362 * Sample usage: <code>
346 HttpRequest request = 363 HttpRequest request =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 * Closes the content of the HTTP response from {@link #getContent()}, ignorin g any content. 395 * Closes the content of the HTTP response from {@link #getContent()}, ignorin g any content.
379 */ 396 */
380 public void ignore() throws IOException { 397 public void ignore() throws IOException {
381 InputStream content = getContent(); 398 InputStream content = getContent();
382 if (content != null) { 399 if (content != null) {
383 content.close(); 400 content.close();
384 } 401 }
385 } 402 }
386 403
387 /** 404 /**
388 * Disconnect using {@link LowLevelHttpResponse#disconnect()}. 405 * Close the HTTP response content and disconnect using {@link LowLevelHttpRes ponse#disconnect()}.
406 *
407 * <p>
408 * Upgrade warning: since version 1.10 {@link #disconnect} now closes the HTTP response content
409 * input stream. This was not done by this method prior to version 1.10.
410 * </p>
389 * 411 *
390 * @since 1.4 412 * @since 1.4
391 */ 413 */
392 public void disconnect() throws IOException { 414 public void disconnect() throws IOException {
415 ignore();
393 response.disconnect(); 416 response.disconnect();
394 } 417 }
395 418
396 /** 419 /**
397 * Returns the HTTP response content parser to use for the content type of thi s HTTP response or 420 * Returns the HTTP response content parser to use for the content type of thi s HTTP response or
398 * {@code null} for none. 421 * {@code null} for none.
399 */ 422 */
400 public HttpParser getParser() { 423 public HttpParser getParser() {
401 return request.getParser(contentType); 424 return request.getParser(contentType);
402 } 425 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 Matcher m = CONTENT_TYPE_PARAM_PATTERN.matcher(contentType); 476 Matcher m = CONTENT_TYPE_PARAM_PATTERN.matcher(contentType);
454 while (m.find()) { 477 while (m.find()) {
455 if ("charset".equalsIgnoreCase(m.group(1))) { 478 if ("charset".equalsIgnoreCase(m.group(1))) {
456 return m.group(2); 479 return m.group(2);
457 } 480 }
458 } 481 }
459 } 482 }
460 return "ISO-8859-1"; 483 return "ISO-8859-1";
461 } 484 }
462 } 485 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b