Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: net/http/http_pipelined_connection_impl.cc

Issue 275953002: Remove HTTP pipelining support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/http_pipelined_connection_impl.cc
diff --git a/net/http/http_pipelined_connection_impl.cc b/net/http/http_pipelined_connection_impl.cc
deleted file mode 100644
index ebd73f24ab7fcf8119c3e7db3b6f47cee2636ad2..0000000000000000000000000000000000000000
--- a/net/http/http_pipelined_connection_impl.cc
+++ /dev/null
@@ -1,846 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_pipelined_connection_impl.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/message_loop/message_loop.h"
-#include "base/stl_util.h"
-#include "base/values.h"
-#include "net/base/io_buffer.h"
-#include "net/http/http_pipelined_stream.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_response_body_drainer.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_stream_parser.h"
-#include "net/http/http_version.h"
-#include "net/socket/client_socket_handle.h"
-
-namespace net {
-
-namespace {
-
-base::Value* NetLogReceivedHeadersCallback(const NetLog::Source& source,
- const std::string* feedback,
- NetLog::LogLevel /* log_level */) {
- base::DictionaryValue* dict = new base::DictionaryValue;
- source.AddToEventParameters(dict);
- dict->SetString("feedback", *feedback);
- return dict;
-}
-
-base::Value* NetLogStreamClosedCallback(const NetLog::Source& source,
- bool not_reusable,
- NetLog::LogLevel /* log_level */) {
- base::DictionaryValue* dict = new base::DictionaryValue;
- source.AddToEventParameters(dict);
- dict->SetBoolean("not_reusable", not_reusable);
- return dict;
-}
-
-base::Value* NetLogHostPortPairCallback(const HostPortPair* host_port_pair,
- NetLog::LogLevel /* log_level */) {
- base::DictionaryValue* dict = new base::DictionaryValue;
- dict->SetString("host_and_port", host_port_pair->ToString());
- return dict;
-}
-
-} // anonymous namespace
-
-HttpPipelinedConnection*
-HttpPipelinedConnectionImpl::Factory::CreateNewPipeline(
- ClientSocketHandle* connection,
- HttpPipelinedConnection::Delegate* delegate,
- const HostPortPair& origin,
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- const BoundNetLog& net_log,
- bool was_npn_negotiated,
- NextProto protocol_negotiated) {
- return new HttpPipelinedConnectionImpl(connection, delegate, origin,
- used_ssl_config, used_proxy_info,
- net_log, was_npn_negotiated,
- protocol_negotiated);
-}
-
-HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
- ClientSocketHandle* connection,
- HttpPipelinedConnection::Delegate* delegate,
- const HostPortPair& origin,
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- const BoundNetLog& net_log,
- bool was_npn_negotiated,
- NextProto protocol_negotiated)
- : delegate_(delegate),
- connection_(connection),
- used_ssl_config_(used_ssl_config),
- used_proxy_info_(used_proxy_info),
- net_log_(BoundNetLog::Make(net_log.net_log(),
- NetLog::SOURCE_HTTP_PIPELINED_CONNECTION)),
- was_npn_negotiated_(was_npn_negotiated),
- protocol_negotiated_(protocol_negotiated),
- read_buf_(new GrowableIOBuffer()),
- next_pipeline_id_(1),
- active_(false),
- usable_(true),
- completed_one_request_(false),
- weak_factory_(this),
- send_next_state_(SEND_STATE_NONE),
- send_still_on_call_stack_(false),
- read_next_state_(READ_STATE_NONE),
- active_read_id_(0),
- read_still_on_call_stack_(false) {
- CHECK(connection_.get());
- net_log_.BeginEvent(
- NetLog::TYPE_HTTP_PIPELINED_CONNECTION,
- base::Bind(&NetLogHostPortPairCallback, &origin));
-}
-
-HttpPipelinedConnectionImpl::~HttpPipelinedConnectionImpl() {
- CHECK_EQ(depth(), 0);
- CHECK(stream_info_map_.empty());
- CHECK(pending_send_request_queue_.empty());
- CHECK(request_order_.empty());
- CHECK_EQ(send_next_state_, SEND_STATE_NONE);
- CHECK_EQ(read_next_state_, READ_STATE_NONE);
- CHECK(!active_send_request_.get());
- CHECK(!active_read_id_);
- if (!usable_) {
- connection_->socket()->Disconnect();
- }
- connection_->Reset();
- net_log_.EndEvent(NetLog::TYPE_HTTP_PIPELINED_CONNECTION);
-}
-
-HttpPipelinedStream* HttpPipelinedConnectionImpl::CreateNewStream() {
- int pipeline_id = next_pipeline_id_++;
- CHECK(pipeline_id);
- HttpPipelinedStream* stream = new HttpPipelinedStream(this, pipeline_id);
- stream_info_map_.insert(std::make_pair(pipeline_id, StreamInfo()));
- return stream;
-}
-
-void HttpPipelinedConnectionImpl::InitializeParser(
- int pipeline_id,
- const HttpRequestInfo* request,
- const BoundNetLog& net_log) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(!stream_info_map_[pipeline_id].parser.get());
- stream_info_map_[pipeline_id].state = STREAM_BOUND;
- stream_info_map_[pipeline_id].parser.reset(new HttpStreamParser(
- connection_.get(), request, read_buf_.get(), net_log));
- stream_info_map_[pipeline_id].source = net_log.source();
-
- // In case our first stream doesn't SendRequest() immediately, we should still
- // allow others to use this pipeline.
- if (pipeline_id == 1) {
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&HttpPipelinedConnectionImpl::ActivatePipeline,
- weak_factory_.GetWeakPtr()));
- }
-}
-
-void HttpPipelinedConnectionImpl::ActivatePipeline() {
- if (!active_) {
- active_ = true;
- delegate_->OnPipelineHasCapacity(this);
- }
-}
-
-void HttpPipelinedConnectionImpl::OnStreamDeleted(int pipeline_id) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- Close(pipeline_id, false);
-
- if (stream_info_map_[pipeline_id].state != STREAM_CREATED &&
- stream_info_map_[pipeline_id].state != STREAM_UNUSED) {
- CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_CLOSED);
- CHECK(stream_info_map_[pipeline_id].parser.get());
- stream_info_map_[pipeline_id].parser.reset();
- }
- CHECK(!stream_info_map_[pipeline_id].parser.get());
- stream_info_map_.erase(pipeline_id);
-
- delegate_->OnPipelineHasCapacity(this);
-}
-
-int HttpPipelinedConnectionImpl::SendRequest(
- int pipeline_id,
- const std::string& request_line,
- const HttpRequestHeaders& headers,
- HttpResponseInfo* response,
- const CompletionCallback& callback) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_BOUND);
- if (!usable_) {
- return ERR_PIPELINE_EVICTION;
- }
-
- PendingSendRequest* send_request = new PendingSendRequest;
- send_request->pipeline_id = pipeline_id;
- send_request->request_line = request_line;
- send_request->headers = headers;
- send_request->response = response;
- send_request->callback = callback;
- pending_send_request_queue_.push(send_request);
-
- int rv;
- if (send_next_state_ == SEND_STATE_NONE) {
- send_next_state_ = SEND_STATE_START_IMMEDIATELY;
- rv = DoSendRequestLoop(OK);
- } else {
- rv = ERR_IO_PENDING;
- }
- ActivatePipeline();
- return rv;
-}
-
-int HttpPipelinedConnectionImpl::DoSendRequestLoop(int result) {
- int rv = result;
- do {
- SendRequestState state = send_next_state_;
- send_next_state_ = SEND_STATE_NONE;
- switch (state) {
- case SEND_STATE_START_IMMEDIATELY:
- rv = DoStartRequestImmediately(rv);
- break;
- case SEND_STATE_START_NEXT_DEFERRED_REQUEST:
- rv = DoStartNextDeferredRequest(rv);
- break;
- case SEND_STATE_SEND_ACTIVE_REQUEST:
- rv = DoSendActiveRequest(rv);
- break;
- case SEND_STATE_COMPLETE:
- rv = DoSendComplete(rv);
- break;
- case SEND_STATE_EVICT_PENDING_REQUESTS:
- rv = DoEvictPendingSendRequests(rv);
- break;
- default:
- CHECK(false) << "bad send state: " << state;
- rv = ERR_FAILED;
- break;
- }
- } while (rv != ERR_IO_PENDING && send_next_state_ != SEND_STATE_NONE);
- send_still_on_call_stack_ = false;
- return rv;
-}
-
-void HttpPipelinedConnectionImpl::OnSendIOCallback(int result) {
- CHECK(active_send_request_.get());
- DoSendRequestLoop(result);
-}
-
-int HttpPipelinedConnectionImpl::DoStartRequestImmediately(int result) {
- CHECK(!active_send_request_.get());
- CHECK_EQ(static_cast<size_t>(1), pending_send_request_queue_.size());
- // If SendRequest() completes synchronously, then we need to return the value
- // directly to the caller. |send_still_on_call_stack_| will track this.
- // Otherwise, asynchronous completions will notify the caller via callback.
- send_still_on_call_stack_ = true;
- active_send_request_.reset(pending_send_request_queue_.front());
- pending_send_request_queue_.pop();
- send_next_state_ = SEND_STATE_SEND_ACTIVE_REQUEST;
- return OK;
-}
-
-int HttpPipelinedConnectionImpl::DoStartNextDeferredRequest(int result) {
- CHECK(!send_still_on_call_stack_);
- CHECK(!active_send_request_.get());
-
- while (!pending_send_request_queue_.empty()) {
- scoped_ptr<PendingSendRequest> next_request(
- pending_send_request_queue_.front());
- pending_send_request_queue_.pop();
- CHECK(ContainsKey(stream_info_map_, next_request->pipeline_id));
- if (stream_info_map_[next_request->pipeline_id].state != STREAM_CLOSED) {
- active_send_request_.reset(next_request.release());
- send_next_state_ = SEND_STATE_SEND_ACTIVE_REQUEST;
- return OK;
- }
- }
-
- send_next_state_ = SEND_STATE_NONE;
- return OK;
-}
-
-int HttpPipelinedConnectionImpl::DoSendActiveRequest(int result) {
- CHECK(stream_info_map_[active_send_request_->pipeline_id].parser.get());
- int rv = stream_info_map_[active_send_request_->pipeline_id].parser->
- SendRequest(active_send_request_->request_line,
- active_send_request_->headers,
- active_send_request_->response,
- base::Bind(&HttpPipelinedConnectionImpl::OnSendIOCallback,
- base::Unretained(this)));
- stream_info_map_[active_send_request_->pipeline_id].state = STREAM_SENDING;
- send_next_state_ = SEND_STATE_COMPLETE;
- return rv;
-}
-
-int HttpPipelinedConnectionImpl::DoSendComplete(int result) {
- CHECK(active_send_request_.get());
- CHECK_EQ(STREAM_SENDING,
- stream_info_map_[active_send_request_->pipeline_id].state);
-
- request_order_.push(active_send_request_->pipeline_id);
- stream_info_map_[active_send_request_->pipeline_id].state = STREAM_SENT;
- net_log_.AddEvent(
- NetLog::TYPE_HTTP_PIPELINED_CONNECTION_SENT_REQUEST,
- stream_info_map_[active_send_request_->pipeline_id].source.
- ToEventParametersCallback());
-
- if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) {
- result = ERR_PIPELINE_EVICTION;
- }
- if (result < OK) {
- usable_ = false;
- }
-
- if (!send_still_on_call_stack_) {
- QueueUserCallback(active_send_request_->pipeline_id,
- active_send_request_->callback, result, FROM_HERE);
- }
-
- active_send_request_.reset();
-
- if (send_still_on_call_stack_) {
- // It should be impossible for another request to appear on the queue while
- // this send was on the call stack.
- CHECK(pending_send_request_queue_.empty());
- send_next_state_ = SEND_STATE_NONE;
- } else if (!usable_) {
- send_next_state_ = SEND_STATE_EVICT_PENDING_REQUESTS;
- } else {
- send_next_state_ = SEND_STATE_START_NEXT_DEFERRED_REQUEST;
- }
-
- return result;
-}
-
-int HttpPipelinedConnectionImpl::DoEvictPendingSendRequests(int result) {
- while (!pending_send_request_queue_.empty()) {
- scoped_ptr<PendingSendRequest> evicted_send(
- pending_send_request_queue_.front());
- pending_send_request_queue_.pop();
- if (ContainsKey(stream_info_map_, evicted_send->pipeline_id) &&
- stream_info_map_[evicted_send->pipeline_id].state != STREAM_CLOSED) {
- evicted_send->callback.Run(ERR_PIPELINE_EVICTION);
- }
- }
- send_next_state_ = SEND_STATE_NONE;
- return result;
-}
-
-int HttpPipelinedConnectionImpl::ReadResponseHeaders(
- int pipeline_id, const CompletionCallback& callback) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK_EQ(STREAM_SENT, stream_info_map_[pipeline_id].state);
- CHECK(stream_info_map_[pipeline_id].read_headers_callback.is_null());
-
- if (!usable_)
- return ERR_PIPELINE_EVICTION;
-
- stream_info_map_[pipeline_id].state = STREAM_READ_PENDING;
- stream_info_map_[pipeline_id].read_headers_callback = callback;
- if (read_next_state_ == READ_STATE_NONE &&
- pipeline_id == request_order_.front()) {
- read_next_state_ = READ_STATE_START_IMMEDIATELY;
- return DoReadHeadersLoop(OK);
- }
- return ERR_IO_PENDING;
-}
-
-void HttpPipelinedConnectionImpl::StartNextDeferredRead() {
- if (read_next_state_ == READ_STATE_NONE) {
- read_next_state_ = READ_STATE_START_NEXT_DEFERRED_READ;
- DoReadHeadersLoop(OK);
- }
-}
-
-int HttpPipelinedConnectionImpl::DoReadHeadersLoop(int result) {
- int rv = result;
- do {
- ReadHeadersState state = read_next_state_;
- read_next_state_ = READ_STATE_NONE;
- switch (state) {
- case READ_STATE_START_IMMEDIATELY:
- rv = DoStartReadImmediately(rv);
- break;
- case READ_STATE_START_NEXT_DEFERRED_READ:
- rv = DoStartNextDeferredRead(rv);
- break;
- case READ_STATE_READ_HEADERS:
- rv = DoReadHeaders(rv);
- break;
- case READ_STATE_READ_HEADERS_COMPLETE:
- rv = DoReadHeadersComplete(rv);
- break;
- case READ_STATE_WAITING_FOR_CLOSE:
- // This is a holding state. We return instead of continuing to run hte
- // loop. The state will advance when the stream calls Close().
- rv = DoReadWaitForClose(rv);
- read_still_on_call_stack_ = false;
- return rv;
- case READ_STATE_STREAM_CLOSED:
- rv = DoReadStreamClosed();
- break;
- case READ_STATE_EVICT_PENDING_READS:
- rv = DoEvictPendingReadHeaders(rv);
- break;
- case READ_STATE_NONE:
- break;
- default:
- CHECK(false) << "bad read state";
- rv = ERR_FAILED;
- break;
- }
- } while (rv != ERR_IO_PENDING && read_next_state_ != READ_STATE_NONE);
- read_still_on_call_stack_ = false;
- return rv;
-}
-
-void HttpPipelinedConnectionImpl::OnReadIOCallback(int result) {
- DoReadHeadersLoop(result);
-}
-
-int HttpPipelinedConnectionImpl::DoStartReadImmediately(int result) {
- CHECK(!active_read_id_);
- CHECK(!read_still_on_call_stack_);
- CHECK(!request_order_.empty());
- // If ReadResponseHeaders() completes synchronously, then we need to return
- // the value directly to the caller. |read_still_on_call_stack_| will track
- // this. Otherwise, asynchronous completions will notify the caller via
- // callback.
- read_still_on_call_stack_ = true;
- read_next_state_ = READ_STATE_READ_HEADERS;
- active_read_id_ = request_order_.front();
- request_order_.pop();
- return OK;
-}
-
-int HttpPipelinedConnectionImpl::DoStartNextDeferredRead(int result) {
- CHECK(!active_read_id_);
- CHECK(!read_still_on_call_stack_);
-
- if (request_order_.empty()) {
- read_next_state_ = READ_STATE_NONE;
- return OK;
- }
-
- int next_id = request_order_.front();
- CHECK(ContainsKey(stream_info_map_, next_id));
- switch (stream_info_map_[next_id].state) {
- case STREAM_READ_PENDING:
- read_next_state_ = READ_STATE_READ_HEADERS;
- active_read_id_ = next_id;
- request_order_.pop();
- break;
-
- case STREAM_CLOSED:
- // Since nobody will read whatever data is on the pipeline associated with
- // this closed request, we must shut down the rest of the pipeline.
- read_next_state_ = READ_STATE_EVICT_PENDING_READS;
- break;
-
- case STREAM_SENT:
- read_next_state_ = READ_STATE_NONE;
- break;
-
- default:
- CHECK(false) << "Unexpected read state: "
- << stream_info_map_[next_id].state;
- }
-
- return OK;
-}
-
-int HttpPipelinedConnectionImpl::DoReadHeaders(int result) {
- CHECK(active_read_id_);
- CHECK(ContainsKey(stream_info_map_, active_read_id_));
- CHECK_EQ(STREAM_READ_PENDING, stream_info_map_[active_read_id_].state);
- stream_info_map_[active_read_id_].state = STREAM_ACTIVE;
- int rv = stream_info_map_[active_read_id_].parser->ReadResponseHeaders(
- base::Bind(&HttpPipelinedConnectionImpl::OnReadIOCallback,
- base::Unretained(this)));
- read_next_state_ = READ_STATE_READ_HEADERS_COMPLETE;
- return rv;
-}
-
-int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) {
- CHECK(active_read_id_);
- CHECK(ContainsKey(stream_info_map_, active_read_id_));
- CHECK_EQ(STREAM_ACTIVE, stream_info_map_[active_read_id_].state);
-
- read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
- if (result < OK) {
- if (completed_one_request_ &&
- (result == ERR_CONNECTION_CLOSED ||
- result == ERR_EMPTY_RESPONSE ||
- result == ERR_SOCKET_NOT_CONNECTED)) {
- // These usually indicate that pipelining failed on the server side. In
- // that case, we should retry without pipelining.
- result = ERR_PIPELINE_EVICTION;
- }
- usable_ = false;
- }
-
- CheckHeadersForPipelineCompatibility(active_read_id_, result);
-
- if (!read_still_on_call_stack_) {
- QueueUserCallback(active_read_id_,
- stream_info_map_[active_read_id_].read_headers_callback,
- result, FROM_HERE);
- }
-
- return result;
-}
-
-int HttpPipelinedConnectionImpl::DoReadWaitForClose(int result) {
- read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
- return result;
-}
-
-int HttpPipelinedConnectionImpl::DoReadStreamClosed() {
- CHECK(active_read_id_);
- CHECK(ContainsKey(stream_info_map_, active_read_id_));
- CHECK_EQ(stream_info_map_[active_read_id_].state, STREAM_CLOSED);
- active_read_id_ = 0;
- if (!usable_) {
- // TODO(simonjam): Don't wait this long to evict.
- read_next_state_ = READ_STATE_EVICT_PENDING_READS;
- return OK;
- }
- completed_one_request_ = true;
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&HttpPipelinedConnectionImpl::StartNextDeferredRead,
- weak_factory_.GetWeakPtr()));
- read_next_state_ = READ_STATE_NONE;
- return OK;
-}
-
-int HttpPipelinedConnectionImpl::DoEvictPendingReadHeaders(int result) {
- while (!request_order_.empty()) {
- int evicted_id = request_order_.front();
- request_order_.pop();
- if (!ContainsKey(stream_info_map_, evicted_id)) {
- continue;
- }
- if (stream_info_map_[evicted_id].state == STREAM_READ_PENDING) {
- stream_info_map_[evicted_id].state = STREAM_READ_EVICTED;
- stream_info_map_[evicted_id].read_headers_callback.Run(
- ERR_PIPELINE_EVICTION);
- }
- }
- read_next_state_ = READ_STATE_NONE;
- return result;
-}
-
-void HttpPipelinedConnectionImpl::Close(int pipeline_id,
- bool not_reusable) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- net_log_.AddEvent(
- NetLog::TYPE_HTTP_PIPELINED_CONNECTION_STREAM_CLOSED,
- base::Bind(&NetLogStreamClosedCallback,
- stream_info_map_[pipeline_id].source, not_reusable));
- switch (stream_info_map_[pipeline_id].state) {
- case STREAM_CREATED:
- stream_info_map_[pipeline_id].state = STREAM_UNUSED;
- break;
-
- case STREAM_BOUND:
- stream_info_map_[pipeline_id].state = STREAM_CLOSED;
- break;
-
- case STREAM_SENDING:
- usable_ = false;
- stream_info_map_[pipeline_id].state = STREAM_CLOSED;
- active_send_request_.reset();
- send_next_state_ = SEND_STATE_EVICT_PENDING_REQUESTS;
- DoSendRequestLoop(OK);
- break;
-
- case STREAM_SENT:
- case STREAM_READ_PENDING:
- usable_ = false;
- stream_info_map_[pipeline_id].state = STREAM_CLOSED;
- if (!request_order_.empty() &&
- pipeline_id == request_order_.front() &&
- read_next_state_ == READ_STATE_NONE) {
- read_next_state_ = READ_STATE_EVICT_PENDING_READS;
- DoReadHeadersLoop(OK);
- }
- break;
-
- case STREAM_ACTIVE:
- stream_info_map_[pipeline_id].state = STREAM_CLOSED;
- if (not_reusable) {
- usable_ = false;
- }
- read_next_state_ = READ_STATE_STREAM_CLOSED;
- DoReadHeadersLoop(OK);
- break;
-
- case STREAM_READ_EVICTED:
- stream_info_map_[pipeline_id].state = STREAM_CLOSED;
- break;
-
- case STREAM_CLOSED:
- case STREAM_UNUSED:
- // TODO(simonjam): Why is Close() sometimes called twice?
- break;
-
- default:
- CHECK(false);
- break;
- }
-}
-
-int HttpPipelinedConnectionImpl::ReadResponseBody(
- int pipeline_id, IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK_EQ(active_read_id_, pipeline_id);
- CHECK(stream_info_map_[pipeline_id].parser.get());
- return stream_info_map_[pipeline_id].parser->ReadResponseBody(
- buf, buf_len, callback);
-}
-
-UploadProgress HttpPipelinedConnectionImpl::GetUploadProgress(
- int pipeline_id) const {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
- return stream_info_map_.find(pipeline_id)->second.parser->GetUploadProgress();
-}
-
-HttpResponseInfo* HttpPipelinedConnectionImpl::GetResponseInfo(
- int pipeline_id) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
- return stream_info_map_.find(pipeline_id)->second.parser->GetResponseInfo();
-}
-
-bool HttpPipelinedConnectionImpl::IsResponseBodyComplete(
- int pipeline_id) const {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
- return stream_info_map_.find(pipeline_id)->second.parser->
- IsResponseBodyComplete();
-}
-
-bool HttpPipelinedConnectionImpl::CanFindEndOfResponse(int pipeline_id) const {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
- return stream_info_map_.find(pipeline_id)->second.parser->
- CanFindEndOfResponse();
-}
-
-bool HttpPipelinedConnectionImpl::IsConnectionReused(int pipeline_id) const {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- if (pipeline_id > 1) {
- return true;
- }
- ClientSocketHandle::SocketReuseType reuse_type = connection_->reuse_type();
- return connection_->is_reused() ||
- reuse_type == ClientSocketHandle::UNUSED_IDLE;
-}
-
-void HttpPipelinedConnectionImpl::SetConnectionReused(int pipeline_id) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
-}
-
-int64 HttpPipelinedConnectionImpl::GetTotalReceivedBytes(
- int pipeline_id) const {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- if (stream_info_map_.find(pipeline_id)->second.parser.get())
- return stream_info_map_.find(pipeline_id)->second.parser->received_bytes();
- return 0;
-}
-
-bool HttpPipelinedConnectionImpl::GetLoadTimingInfo(
- int pipeline_id, LoadTimingInfo* load_timing_info) const {
- return connection_->GetLoadTimingInfo(IsConnectionReused(pipeline_id),
- load_timing_info);
-}
-
-void HttpPipelinedConnectionImpl::GetSSLInfo(int pipeline_id,
- SSLInfo* ssl_info) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_[pipeline_id].parser.get());
- stream_info_map_[pipeline_id].parser->GetSSLInfo(ssl_info);
-}
-
-void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo(
- int pipeline_id,
- SSLCertRequestInfo* cert_request_info) {
- CHECK(ContainsKey(stream_info_map_, pipeline_id));
- CHECK(stream_info_map_[pipeline_id].parser.get());
- stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo(
- cert_request_info);
-}
-
-void HttpPipelinedConnectionImpl::Drain(HttpPipelinedStream* stream,
- HttpNetworkSession* session) {
- HttpResponseHeaders* headers = stream->GetResponseInfo()->headers.get();
- if (!stream->CanFindEndOfResponse() || headers->IsChunkEncoded() ||
- !usable_) {
- // TODO(simonjam): Drain chunk-encoded responses if they're relatively
- // common.
- stream->Close(true);
- delete stream;
- return;
- }
- HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(stream);
- drainer->StartWithSize(session, headers->GetContentLength());
- // |drainer| will delete itself when done.
-}
-
-void HttpPipelinedConnectionImpl::CheckHeadersForPipelineCompatibility(
- int pipeline_id,
- int result) {
- if (result < OK) {
- switch (result) {
- // TODO(simonjam): Ignoring specific errors like this may not work.
- // Collect metrics to see if this code is useful.
- case ERR_ABORTED:
- case ERR_INTERNET_DISCONNECTED:
- case ERR_NETWORK_CHANGED:
- // These errors are no fault of the server.
- break;
-
- default:
- ReportPipelineFeedback(pipeline_id, PIPELINE_SOCKET_ERROR);
- break;
- }
- return;
- }
- HttpResponseInfo* info = GetResponseInfo(pipeline_id);
- const HttpVersion required_version(1, 1);
- if (info->headers->GetParsedHttpVersion() < required_version) {
- ReportPipelineFeedback(pipeline_id, OLD_HTTP_VERSION);
- return;
- }
- if (!info->headers->IsKeepAlive() || !CanFindEndOfResponse(pipeline_id)) {
- usable_ = false;
- ReportPipelineFeedback(pipeline_id, MUST_CLOSE_CONNECTION);
- return;
- }
- if (info->headers->HasHeader(
- HttpAuth::GetChallengeHeaderName(HttpAuth::AUTH_SERVER))) {
- ReportPipelineFeedback(pipeline_id, AUTHENTICATION_REQUIRED);
- return;
- }
- ReportPipelineFeedback(pipeline_id, OK);
-}
-
-void HttpPipelinedConnectionImpl::ReportPipelineFeedback(int pipeline_id,
- Feedback feedback) {
- std::string feedback_str;
- switch (feedback) {
- case OK:
- feedback_str = "OK";
- break;
-
- case PIPELINE_SOCKET_ERROR:
- feedback_str = "PIPELINE_SOCKET_ERROR";
- break;
-
- case OLD_HTTP_VERSION:
- feedback_str = "OLD_HTTP_VERSION";
- break;
-
- case MUST_CLOSE_CONNECTION:
- feedback_str = "MUST_CLOSE_CONNECTION";
- break;
-
- case AUTHENTICATION_REQUIRED:
- feedback_str = "AUTHENTICATION_REQUIRED";
- break;
-
- default:
- NOTREACHED();
- feedback_str = "UNKNOWN";
- break;
- }
- net_log_.AddEvent(
- NetLog::TYPE_HTTP_PIPELINED_CONNECTION_RECEIVED_HEADERS,
- base::Bind(&NetLogReceivedHeadersCallback,
- stream_info_map_[pipeline_id].source, &feedback_str));
- delegate_->OnPipelineFeedback(this, feedback);
-}
-
-void HttpPipelinedConnectionImpl::QueueUserCallback(
- int pipeline_id, const CompletionCallback& callback, int rv,
- const tracked_objects::Location& from_here) {
- CHECK(stream_info_map_[pipeline_id].pending_user_callback.is_null());
- stream_info_map_[pipeline_id].pending_user_callback = callback;
- base::MessageLoop::current()->PostTask(
- from_here,
- base::Bind(&HttpPipelinedConnectionImpl::FireUserCallback,
- weak_factory_.GetWeakPtr(), pipeline_id, rv));
-}
-
-void HttpPipelinedConnectionImpl::FireUserCallback(int pipeline_id,
- int result) {
- if (ContainsKey(stream_info_map_, pipeline_id)) {
- CHECK(!stream_info_map_[pipeline_id].pending_user_callback.is_null());
- CompletionCallback callback =
- stream_info_map_[pipeline_id].pending_user_callback;
- stream_info_map_[pipeline_id].pending_user_callback.Reset();
- callback.Run(result);
- }
-}
-
-int HttpPipelinedConnectionImpl::depth() const {
- return stream_info_map_.size();
-}
-
-bool HttpPipelinedConnectionImpl::usable() const {
- return usable_;
-}
-
-bool HttpPipelinedConnectionImpl::active() const {
- return active_;
-}
-
-const SSLConfig& HttpPipelinedConnectionImpl::used_ssl_config() const {
- return used_ssl_config_;
-}
-
-const ProxyInfo& HttpPipelinedConnectionImpl::used_proxy_info() const {
- return used_proxy_info_;
-}
-
-const BoundNetLog& HttpPipelinedConnectionImpl::net_log() const {
- return net_log_;
-}
-
-bool HttpPipelinedConnectionImpl::was_npn_negotiated() const {
- return was_npn_negotiated_;
-}
-
-NextProto HttpPipelinedConnectionImpl::protocol_negotiated()
- const {
- return protocol_negotiated_;
-}
-
-HttpPipelinedConnectionImpl::PendingSendRequest::PendingSendRequest()
- : pipeline_id(0),
- response(NULL) {
-}
-
-HttpPipelinedConnectionImpl::PendingSendRequest::~PendingSendRequest() {
-}
-
-HttpPipelinedConnectionImpl::StreamInfo::StreamInfo()
- : state(STREAM_CREATED) {
-}
-
-HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() {
-}
-
-} // namespace net

Powered by Google App Engine
This is Rietveld 408576698