diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-16 23:18:14 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-16 23:18:14 +0000 |
commit | a7e4131b3f56e3396a7d2b51ac022e2df220f28f (patch) | |
tree | 27f9cb64b2df2f31c13fd242338e30c504980de9 /net | |
parent | 18d6a8f3322db4c50ae4a1ebd9e95796f43ea013 (diff) | |
download | chromium_src-a7e4131b3f56e3396a7d2b51ac022e2df220f28f.zip chromium_src-a7e4131b3f56e3396a7d2b51ac022e2df220f28f.tar.gz chromium_src-a7e4131b3f56e3396a7d2b51ac022e2df220f28f.tar.bz2 |
Make the transactions own the HttpResponseInfo.
Necessary since we need the SSLInfo to handle certificate errors, but it lives within the HttpResponseInfo. SSL is before we choose http or spdy, so we don't have an http stream or a spdy stream yet, so they cannot own the HttpResponseInfo.
Review URL: http://codereview.chromium.org/500039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34773 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/flip/flip_network_transaction.cc | 5 | ||||
-rw-r--r-- | net/flip/flip_network_transaction.h | 2 | ||||
-rwxr-xr-x | net/flip/flip_stream.cc | 16 | ||||
-rwxr-xr-x | net/flip/flip_stream.h | 6 | ||||
-rw-r--r-- | net/flip/flip_stream_unittest.cc | 4 | ||||
-rw-r--r-- | net/http/http_basic_stream.cc | 4 | ||||
-rw-r--r-- | net/http/http_basic_stream.h | 1 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 47 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 1 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 4 | ||||
-rw-r--r-- | net/http/http_stream.h | 1 | ||||
-rw-r--r-- | net/http/http_stream_parser.cc | 23 | ||||
-rw-r--r-- | net/http/http_stream_parser.h | 7 |
13 files changed, 66 insertions, 55 deletions
diff --git a/net/flip/flip_network_transaction.cc b/net/flip/flip_network_transaction.cc index 4b94b1f..4e0c3d2d 100644 --- a/net/flip/flip_network_transaction.cc +++ b/net/flip/flip_network_transaction.cc @@ -99,8 +99,7 @@ int FlipNetworkTransaction::Read(IOBuffer* buf, int buf_len, } const HttpResponseInfo* FlipNetworkTransaction::GetResponseInfo() const { - const HttpResponseInfo* response = stream_->GetResponseInfo(); - return (response->headers || response->ssl_info.cert) ? response : NULL; + return (response_.headers || response_.ssl_info.cert) ? &response_ : NULL; } LoadState FlipNetworkTransaction::GetLoadState() const { @@ -253,7 +252,7 @@ int FlipNetworkTransaction::DoSendRequest() { UploadDataStream* upload_data = request_->upload_data ? new UploadDataStream(request_->upload_data) : NULL; stream_ = flip_->GetOrCreateStream(*request_, upload_data); - return stream_->SendRequest(upload_data, &io_callback_); + return stream_->SendRequest(upload_data, &response_, &io_callback_); } int FlipNetworkTransaction::DoSendRequestComplete(int result) { diff --git a/net/flip/flip_network_transaction.h b/net/flip/flip_network_transaction.h index eab2f45..a48455a 100644 --- a/net/flip/flip_network_transaction.h +++ b/net/flip/flip_network_transaction.h @@ -15,6 +15,7 @@ #include "net/base/completion_callback.h" #include "net/base/load_states.h" #include "net/flip/flip_session.h" +#include "net/http/http_response_info.h" #include "net/http/http_transaction.h" namespace net { @@ -103,6 +104,7 @@ class FlipNetworkTransaction : public HttpTransaction { scoped_refptr<HttpNetworkSession> session_; const HttpRequestInfo* request_; + HttpResponseInfo response_; // The time the Start method was called. base::TimeTicks start_time_; diff --git a/net/flip/flip_stream.cc b/net/flip/flip_stream.cc index b0c7236..7288480 100755 --- a/net/flip/flip_stream.cc +++ b/net/flip/flip_stream.cc @@ -50,7 +50,7 @@ uint64 FlipStream::GetUploadProgress() const { } const HttpResponseInfo* FlipStream::GetResponseInfo() const { - return response_.get(); + return response_; } int FlipStream::ReadResponseHeaders(CompletionCallback* callback) { @@ -61,7 +61,7 @@ int FlipStream::ReadResponseHeaders(CompletionCallback* callback) { CHECK(!cancelled_); // The SYN_REPLY has already been received. - if (response_.get()) + if (response_->headers) return OK; io_state_ = STATE_READ_HEADERS; @@ -114,9 +114,13 @@ int FlipStream::ReadResponseBody( } int FlipStream::SendRequest(UploadDataStream* upload_data, + HttpResponseInfo* response, CompletionCallback* callback) { CHECK(callback); CHECK(!cancelled_); + CHECK(response); + + response_ = response; if (upload_data) { if (upload_data->size()) @@ -157,10 +161,10 @@ void FlipStream::Cancel() { void FlipStream::OnResponseReceived(const HttpResponseInfo& response) { metrics_.StartStream(); - CHECK(!response_.get()); + CHECK(!response_->headers); - response_.reset(new HttpResponseInfo); *response_ = response; // TODO(mbelshe): avoid copy. + DCHECK(response_->headers); if (io_state_ == STATE_NONE) { CHECK(pushed_); @@ -184,7 +188,7 @@ bool FlipStream::OnDataReceived(const char* data, int length) { // If we don't have a response, then the SYN_REPLY did not come through. // We cannot pass data up to the caller unless the reply headers have been // received. - if (!response_.get()) { + if (!response_->headers) { OnClose(ERR_SYN_REPLY_NOT_RECEIVED); return false; } @@ -359,7 +363,7 @@ int FlipStream::DoSendBodyComplete(int result) { int FlipStream::DoReadHeaders() { io_state_ = STATE_READ_HEADERS_COMPLETE; - return response_.get() ? OK : ERR_IO_PENDING; + return response_->headers ? OK : ERR_IO_PENDING; } int FlipStream::DoReadHeadersComplete(int result) { diff --git a/net/flip/flip_stream.h b/net/flip/flip_stream.h index 54c5cd4..3ebdc2e 100755 --- a/net/flip/flip_stream.h +++ b/net/flip/flip_stream.h @@ -51,7 +51,9 @@ class FlipStream : public base::RefCounted<FlipStream> { // body. |callback| is used when this completes asynchronously. Note that // the actual SYN_STREAM packet will have already been sent by this point. // Also note that FlipStream takes ownership of |upload_data|. - int SendRequest(UploadDataStream* upload_data, CompletionCallback* callback); + int SendRequest(UploadDataStream* upload_data, + HttpResponseInfo* response, + CompletionCallback* callback); // Reads the response headers. Returns a net error code. int ReadResponseHeaders(CompletionCallback* callback); @@ -164,7 +166,7 @@ class FlipStream : public base::RefCounted<FlipStream> { scoped_refptr<FlipSession> session_; - scoped_ptr<HttpResponseInfo> response_; + HttpResponseInfo* response_; scoped_ptr<UploadDataStream> request_body_stream_; bool response_complete_; // TODO(mbelshe): fold this into the io_state. diff --git a/net/flip/flip_stream_unittest.cc b/net/flip/flip_stream_unittest.cc index 311b51c..bb64d63 100644 --- a/net/flip/flip_stream_unittest.cc +++ b/net/flip/flip_stream_unittest.cc @@ -13,6 +13,7 @@ #include "net/flip/flip_session_pool.h" #include "net/http/http_network_session.h" #include "net/http/http_request_info.h" +#include "net/http/http_response_info.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -103,9 +104,10 @@ TEST_F(FlipStreamTest, SendRequest) { request.method = "GET"; request.url = GURL("http://www.google.com/"); TestCompletionCallback callback; + HttpResponseInfo response; scoped_refptr<FlipStream> stream(new FlipStream(session, 1, false)); - EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(NULL, &callback)); + EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(NULL, &response, &callback)); // Need to manually remove the flip session since normally it gets removed on // socket close/error, but we aren't communicating over a socket here. diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc index f1e6100..220996b 100644 --- a/net/http/http_basic_stream.cc +++ b/net/http/http_basic_stream.cc @@ -14,8 +14,10 @@ HttpBasicStream::HttpBasicStream(ClientSocketHandle* handle) int HttpBasicStream::SendRequest(const HttpRequestInfo* request, const std::string& headers, UploadDataStream* request_body, + HttpResponseInfo* response, CompletionCallback* callback) { - return parser_->SendRequest(request, headers, request_body, callback); + return parser_->SendRequest( + request, headers, request_body, response, callback); } uint64 HttpBasicStream::GetUploadProgress() const { diff --git a/net/http/http_basic_stream.h b/net/http/http_basic_stream.h index 1b1f68a..53675a3 100644 --- a/net/http/http_basic_stream.h +++ b/net/http/http_basic_stream.h @@ -32,6 +32,7 @@ class HttpBasicStream : public HttpStream { virtual int SendRequest(const HttpRequestInfo* request, const std::string& headers, UploadDataStream* request_body, + HttpResponseInfo* response, CompletionCallback* callback); virtual uint64 GetUploadProgress() const; diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 6e925b8..a45d3ab 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -332,9 +332,8 @@ int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, } const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { - const HttpResponseInfo* response = http_stream_->GetResponseInfo(); - return ((headers_valid_ && response->headers) || response->ssl_info.cert || - response->cert_request_info) ? response : NULL; + return ((headers_valid_ && response_.headers) || response_.ssl_info.cert || + response_.cert_request_info) ? &response_ : NULL; } LoadState HttpNetworkTransaction::GetLoadState() const { @@ -756,8 +755,8 @@ int HttpNetworkTransaction::DoSendRequest() { } } - return http_stream_->SendRequest(request_, request_headers_, request_body, - &io_callback_); + return http_stream_->SendRequest(request_, request_headers_, + request_body, &response_, &io_callback_); } int HttpNetworkTransaction::DoSendRequestComplete(int result) { @@ -781,7 +780,7 @@ int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { return ERR_TUNNEL_CONNECTION_FAILED; } - if (!http_stream_->GetResponseInfo()->headers) { + if (!response_.headers) { // The connection was closed before any data was sent. Likely an error // rather than empty HTTP/0.9 response. return ERR_EMPTY_RESPONSE; @@ -819,7 +818,6 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // After we call RestartWithAuth a new response_time will be recorded, and // we need to be cautious about incorrectly logging the duration across the // authentication activity. - HttpResponseInfo* response = http_stream_->GetResponseInfo(); if (!logged_response_time) { LogTransactionConnectedMetrics(); logged_response_time = true; @@ -835,7 +833,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { result = 0; } - if (response->headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { + if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { // Require the "HTTP/1.x" status line for SSL CONNECT. if (establishing_tunnel_) return ERR_TUNNEL_CONNECTION_FAILED; @@ -848,7 +846,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { } if (establishing_tunnel_) { - switch (response->headers->response_code()) { + switch (response_.headers->response_code()) { case 200: // OK if (http_stream_->IsMoreDataBuffered()) { // The proxy sent extraneous data after the headers. @@ -880,7 +878,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // 501 response bodies that contain a useful error message. For // example, Squid uses a 404 response to report the DNS error: "The // domain name does not exist." - LogBlockedTunnelResponse(response->headers->response_code()); + LogBlockedTunnelResponse(response_.headers->response_code()); return ERR_TUNNEL_CONNECTION_FAILED; } } @@ -890,7 +888,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // need to skip over it. // We treat any other 1xx in this same way (although in practice getting // a 1xx that isn't a 100 is rare). - if (response->headers->response_code() / 100 == 1) { + if (response_.headers->response_code() / 100 == 1) { next_state_ = STATE_READ_HEADERS; return OK; } @@ -902,7 +900,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { if (using_ssl_ && !establishing_tunnel_) { SSLClientSocket* ssl_socket = reinterpret_cast<SSLClientSocket*>(connection_.socket()); - ssl_socket->GetSSLInfo(&response->ssl_info); + ssl_socket->GetSSLInfo(&response_.ssl_info); } headers_valid_ = true; @@ -1131,8 +1129,7 @@ void HttpNetworkTransaction::LogIOErrorMetrics( } void HttpNetworkTransaction::LogTransactionConnectedMetrics() const { - base::TimeDelta total_duration = - http_stream_->GetResponseInfo()->response_time - start_time_; + base::TimeDelta total_duration = response_.response_time - start_time_; UMA_HISTOGRAM_CLIPPED_TIMES( "Net.Transaction_Connected_Under_10", @@ -1180,7 +1177,7 @@ void HttpNetworkTransaction::LogTransactionConnectedMetrics() const { void HttpNetworkTransaction::LogTransactionMetrics() const { base::TimeDelta duration = base::Time::Now() - - http_stream_->GetResponseInfo()->request_time; + response_.request_time; if (60 < duration.InMinutes()) return; @@ -1233,18 +1230,17 @@ int HttpNetworkTransaction::HandleCertificateError(int error) { } if (error != OK) { - HttpResponseInfo* response = http_stream_->GetResponseInfo(); SSLClientSocket* ssl_socket = reinterpret_cast<SSLClientSocket*>(connection_.socket()); - ssl_socket->GetSSLInfo(&response->ssl_info); + ssl_socket->GetSSLInfo(&response_.ssl_info); // Add the bad certificate to the set of allowed certificates in the // SSL info object. This data structure will be consulted after calling // RestartIgnoringLastError(). And the user will be asked interactively // before RestartIgnoringLastError() is ever called. SSLConfig::CertAndStatus bad_cert; - bad_cert.cert = response->ssl_info.cert; - bad_cert.cert_status = response->ssl_info.cert_status; + bad_cert.cert = response_.ssl_info.cert; + bad_cert.cert_status = response_.ssl_info.cert_status; ssl_config_.allowed_bad_certs.push_back(bad_cert); } return error; @@ -1261,11 +1257,10 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) { // test. DCHECK(reused_socket_ || !ssl_config_.send_client_cert); - HttpResponseInfo* response = http_stream_->GetResponseInfo(); - response->cert_request_info = new SSLCertRequestInfo; + response_.cert_request_info = new SSLCertRequestInfo; SSLClientSocket* ssl_socket = reinterpret_cast<SSLClientSocket*>(connection_.socket()); - ssl_socket->GetSSLCertRequestInfo(response->cert_request_info); + ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); // Close the connection while the user is selecting a certificate to send // to the server. @@ -1278,7 +1273,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) { Lookup(GetHostAndPort(request_->url)); if (client_cert) { const std::vector<scoped_refptr<X509Certificate> >& client_certs = - response->cert_request_info->client_certs; + response_.cert_request_info->client_certs; for (size_t i = 0; i < client_certs.size(); ++i) { if (client_cert->fingerprint().Equals(client_certs[i]->fingerprint())) { ssl_config_.client_cert = client_cert; @@ -1348,11 +1343,11 @@ void HttpNetworkTransaction::ResetStateForRestart() { http_stream_.reset(new HttpBasicStream(&connection_)); headers_valid_ = false; request_headers_.clear(); + response_ = HttpResponseInfo(); } HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { - CHECK(http_stream_.get()); - return http_stream_->GetResponseInfo()->headers; + return response_.headers; } bool HttpNetworkTransaction::ShouldResendRequest(int error) const { @@ -1690,7 +1685,7 @@ void HttpNetworkTransaction::PopulateAuthChallenge(HttpAuth::Target target, auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); // TODO(eroman): decode realm according to RFC 2047. auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); - http_stream_->GetResponseInfo()->auth_challenge = auth_info; + response_.auth_challenge = auth_info; } } // namespace net diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index d19638b..10c8955 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -265,6 +265,7 @@ class HttpNetworkTransaction : public HttpTransaction { scoped_refptr<LoadLog> load_log_; const HttpRequestInfo* request_; + HttpResponseInfo response_; ProxyService::PacRequest* pac_request_; ProxyInfo proxy_info_; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 7d64bb1..1106757 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -2793,8 +2793,7 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { trans->request_headers_ = "Authorization: NTLM"; // Setup state in response_ - trans->http_stream_.reset(new HttpBasicStream(NULL)); - HttpResponseInfo* response = trans->http_stream_->GetResponseInfo(); + HttpResponseInfo* response = &trans->response_; response->auth_challenge = new AuthChallengeInfo(); response->ssl_info.cert_status = -15; response->response_time = base::Time::Now(); @@ -2813,7 +2812,6 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { trans->ResetStateForRestart(); // Verify that the state that needed to be reset, has been reset. - response = trans->http_stream_->GetResponseInfo(); EXPECT_TRUE(trans->read_buf_.get() == NULL); EXPECT_EQ(0, trans->read_buf_len_); EXPECT_EQ(0U, trans->request_headers_.size()); diff --git a/net/http/http_stream.h b/net/http/http_stream.h index b13bb6f..49651dd 100644 --- a/net/http/http_stream.h +++ b/net/http/http_stream.h @@ -35,6 +35,7 @@ class HttpStream { virtual int SendRequest(const HttpRequestInfo* request, const std::string& request_headers, UploadDataStream* request_body, + HttpResponseInfo* response, CompletionCallback* callback) = 0; // Queries the UploadDataStream for its progress (bytes sent). diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc index 6ad29ae..cd58ee2 100644 --- a/net/http/http_stream_parser.cc +++ b/net/http/http_stream_parser.cc @@ -37,12 +37,15 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, int HttpStreamParser::SendRequest(const HttpRequestInfo* request, const std::string& headers, UploadDataStream* request_body, + HttpResponseInfo* response, CompletionCallback* callback) { DCHECK_EQ(STATE_NONE, io_state_); DCHECK(!user_callback_); DCHECK(callback); + DCHECK(response); request_ = request; + response_ = response; scoped_refptr<StringIOBuffer> headers_io_buf = new StringIOBuffer(headers); request_headers_ = new DrainableIOBuffer(headers_io_buf, headers_io_buf->size()); @@ -178,7 +181,7 @@ int HttpStreamParser::DoSendHeaders(int result) { // Record our best estimate of the 'request time' as the time when we send // out the first bytes of the request headers. if (request_headers_->BytesRemaining() == request_headers_->size()) { - response_.request_time = base::Time::Now(); + response_->request_time = base::Time::Now(); } result = connection_->socket()->Write(request_headers_, request_headers_->BytesRemaining(), @@ -239,7 +242,7 @@ int HttpStreamParser::DoReadHeadersComplete(int result) { // Record our best estimate of the 'response time' as the time when we read // the first bytes of the response headers. if (read_buf_->offset() == 0 && result != ERR_CONNECTION_CLOSED) - response_.response_time = base::Time::Now(); + response_->response_time = base::Time::Now(); if (result == ERR_CONNECTION_CLOSED) { // The connection closed before we detected the end of the headers. @@ -279,7 +282,7 @@ int HttpStreamParser::DoReadHeadersComplete(int result) { // Note where the headers stop. read_buf_unused_offset_ = end_of_header_offset; - if (response_.headers->response_code() / 100 == 1) { + if (response_->headers->response_code() / 100 == 1) { // After processing a 1xx response, the caller will ask for the next // header, so reset state to support that. We don't just skip these // completely because 1xx codes aren't acceptable when establishing a @@ -446,8 +449,8 @@ void HttpStreamParser::DoParseResponseHeaders(int end_offset) { headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); } - response_.headers = headers; - response_.vary_data.Init(*request_, *response_.headers); + response_->headers = headers; + response_->vary_data.Init(*request_, *response_->headers); } void HttpStreamParser::CalculateResponseBodySize() { @@ -464,7 +467,7 @@ void HttpStreamParser::CalculateResponseBodySize() { // (informational), 204 (no content), and 304 (not modified) responses // MUST NOT include a message-body. All other responses do include a // message-body, although it MAY be of zero length. - switch (response_.headers->response_code()) { + switch (response_->headers->response_code()) { // Note that 1xx was already handled earlier. case 204: // No Content case 205: // Reset Content @@ -479,11 +482,11 @@ void HttpStreamParser::CalculateResponseBodySize() { // Ignore spurious chunked responses from HTTP/1.0 servers and // proxies. Otherwise "Transfer-Encoding: chunked" trumps // "Content-Length: N" - if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1) && - response_.headers->HasHeaderValue("Transfer-Encoding", "chunked")) { + if (response_->headers->GetHttpVersion() >= HttpVersion(1, 1) && + response_->headers->HasHeaderValue("Transfer-Encoding", "chunked")) { chunked_decoder_.reset(new HttpChunkedDecoder()); } else { - response_body_length_ = response_.headers->GetContentLength(); + response_body_length_ = response_->headers->GetContentLength(); // If response_body_length_ is still -1, then we have to wait // for the server to close the connection. } @@ -498,7 +501,7 @@ uint64 HttpStreamParser::GetUploadProgress() const { } HttpResponseInfo* HttpStreamParser::GetResponseInfo() { - return &response_; + return response_; } bool HttpStreamParser::IsResponseBodyComplete() const { diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h index f2108a9..4ccc6ee 100644 --- a/net/http/http_stream_parser.h +++ b/net/http/http_stream_parser.h @@ -33,7 +33,8 @@ class HttpStreamParser { // These functions implement the interface described in HttpStream with // some additional functionality int SendRequest(const HttpRequestInfo* request, const std::string& headers, - UploadDataStream* request_body, CompletionCallback* callback); + UploadDataStream* request_body, HttpResponseInfo* response, + CompletionCallback* callback); int ReadResponseHeaders(CompletionCallback* callback); @@ -128,8 +129,8 @@ class HttpStreamParser { // -1 if not found yet. int response_header_start_offset_; - // The parsed response headers. - HttpResponseInfo response_; + // The parsed response headers. Owned by the caller. + HttpResponseInfo* response_; // Indicates the content length. If this value is less than zero // (and chunked_decoder_ is null), then we must read until the server |