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

Unified Diff: net/http/http_pipelined_connection_impl.cc

Issue 7289006: Basic HTTP pipelining support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 9 years, 2 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
« no previous file with comments | « net/http/http_pipelined_connection_impl.h ('k') | net/http/http_pipelined_connection_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
new file mode 100644
index 0000000000000000000000000000000000000000..33f2ef62baabfdc8ffc4f946e7d20f6f5b7fcccc
--- /dev/null
+++ b/net/http/http_pipelined_connection_impl.cc
@@ -0,0 +1,612 @@
+// Copyright (c) 2011 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/message_loop.h"
+#include "base/stl_util.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_stream_parser.h"
+#include "net/socket/client_socket_handle.h"
+
+namespace net {
+
+HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
+ ClientSocketHandle* connection,
+ HttpPipelinedConnection::Delegate* delegate,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ const BoundNetLog& net_log,
+ bool was_npn_negotiated)
+ : delegate_(delegate),
+ connection_(connection),
+ used_ssl_config_(used_ssl_config),
+ used_proxy_info_(used_proxy_info),
+ net_log_(net_log),
+ was_npn_negotiated_(was_npn_negotiated),
+ read_buf_(new GrowableIOBuffer()),
+ next_pipeline_id_(1),
+ active_(false),
+ usable_(true),
+ completed_one_request_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
+ send_next_state_(SEND_STATE_NONE),
+ ALLOW_THIS_IN_INITIALIZER_LIST(send_io_callback_(
+ this, &HttpPipelinedConnectionImpl::OnSendIOCallback)),
+ send_user_callback_(NULL),
+ read_next_state_(READ_STATE_NONE),
+ ALLOW_THIS_IN_INITIALIZER_LIST(read_io_callback_(
+ this, &HttpPipelinedConnectionImpl::OnReadIOCallback)),
+ read_user_callback_(NULL) {
+ CHECK(connection_.get());
+}
+
+HttpPipelinedConnectionImpl::~HttpPipelinedConnectionImpl() {
+ CHECK_EQ(depth(), 0);
+ CHECK(stream_info_map_.empty());
+ CHECK(deferred_request_queue_.empty());
+ CHECK(request_order_.empty());
+ CHECK_EQ(send_next_state_, SEND_STATE_NONE);
+ CHECK_EQ(read_next_state_, READ_STATE_NONE);
+ CHECK(!send_user_callback_);
+ CHECK(!read_user_callback_);
+ if (!usable_) {
+ connection_->socket()->Disconnect();
+ }
+ connection_->Reset();
+}
+
+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));
+
+ // In case our first stream doesn't SendRequest() immediately, we should still
+ // allow others to use this pipeline.
+ if (pipeline_id == 1) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::ActivatePipeline));
+ }
+}
+
+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());
+ CHECK(!stream_info_map_[pipeline_id].read_headers_callback);
+ stream_info_map_.erase(pipeline_id);
+
+ delegate_->OnPipelineHasCapacity(this);
+}
+
+int HttpPipelinedConnectionImpl::SendRequest(int pipeline_id,
+ const std::string& request_line,
+ const HttpRequestHeaders& headers,
+ UploadDataStream* request_body,
+ HttpResponseInfo* response,
+ OldCompletionCallback* callback) {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_BOUND);
+ if (!usable_) {
+ return ERR_PIPELINE_EVICTION;
+ }
+
+ DeferredSendRequest deferred_request;
+ deferred_request.pipeline_id = pipeline_id;
+ deferred_request.request_line = request_line;
+ deferred_request.headers = headers;
+ deferred_request.request_body = request_body;
+ deferred_request.response = response;
+ deferred_request.callback = callback;
+ deferred_request_queue_.push(deferred_request);
+
+ int rv;
+ if (send_next_state_ == SEND_STATE_NONE) {
+ send_next_state_ = SEND_STATE_NEXT_REQUEST;
+ 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_NEXT_REQUEST:
+ rv = DoSendNextRequest(rv);
+ break;
+ case SEND_STATE_COMPLETE:
+ rv = DoSendComplete(rv);
+ break;
+ case SEND_STATE_UNUSABLE:
+ rv = DoEvictPendingSendRequests(rv);
+ break;
+ default:
+ NOTREACHED() << "bad send state: " << state;
+ rv = ERR_FAILED;
+ break;
+ }
+ } while (rv != ERR_IO_PENDING && send_next_state_ != SEND_STATE_NONE);
+ return rv;
+}
+
+void HttpPipelinedConnectionImpl::OnSendIOCallback(int result) {
+ CHECK(send_user_callback_);
+ DoSendRequestLoop(result);
+}
+
+int HttpPipelinedConnectionImpl::DoSendNextRequest(int result) {
+ CHECK(!deferred_request_queue_.empty());
+ const DeferredSendRequest& deferred_request = deferred_request_queue_.front();
+ CHECK(ContainsKey(stream_info_map_, deferred_request.pipeline_id));
+ if (stream_info_map_[deferred_request.pipeline_id].state == STREAM_CLOSED) {
+ deferred_request_queue_.pop();
+ if (deferred_request_queue_.empty()) {
+ send_next_state_ = SEND_STATE_NONE;
+ } else {
+ send_next_state_ = SEND_STATE_NEXT_REQUEST;
+ }
+ return OK;
+ }
+ CHECK(stream_info_map_[deferred_request.pipeline_id].parser.get());
+ int rv = stream_info_map_[deferred_request.pipeline_id].parser->SendRequest(
+ deferred_request.request_line,
+ deferred_request.headers,
+ deferred_request.request_body,
+ deferred_request.response,
+ &send_io_callback_);
+ // |result| == ERR_IO_PENDING means this function was *not* called on the same
+ // stack as SendRequest(). That means we returned ERR_IO_PENDING to
+ // SendRequest() earlier and will need to invoke its callback.
+ if (result == ERR_IO_PENDING || rv == ERR_IO_PENDING) {
+ send_user_callback_ = deferred_request.callback;
+ }
+ stream_info_map_[deferred_request.pipeline_id].state = STREAM_SENDING;
+ send_next_state_ = SEND_STATE_COMPLETE;
+ return rv;
+}
+
+int HttpPipelinedConnectionImpl::DoSendComplete(int result) {
+ CHECK(!deferred_request_queue_.empty());
+ const DeferredSendRequest& deferred_request = deferred_request_queue_.front();
+ CHECK_EQ(stream_info_map_[deferred_request.pipeline_id].state,
+ STREAM_SENDING);
+ request_order_.push(deferred_request.pipeline_id);
+ stream_info_map_[deferred_request.pipeline_id].state = STREAM_SENT;
+ deferred_request_queue_.pop();
+ if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) {
+ result = ERR_PIPELINE_EVICTION;
+ }
+ if (result < OK) {
+ send_next_state_ = SEND_STATE_UNUSABLE;
+ usable_ = false;
+ }
+ if (send_user_callback_) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::FireUserCallback,
+ send_user_callback_,
+ result));
+ send_user_callback_ = NULL;
+ }
+ if (result < OK) {
+ return result;
+ }
+ if (deferred_request_queue_.empty()) {
+ send_next_state_ = SEND_STATE_NONE;
+ return OK;
+ }
+ send_next_state_ = SEND_STATE_NEXT_REQUEST;
+ return OK;
+}
+
+int HttpPipelinedConnectionImpl::DoEvictPendingSendRequests(int result) {
+ send_next_state_ = SEND_STATE_NONE;
+ while (!deferred_request_queue_.empty()) {
+ const DeferredSendRequest& evicted_send = deferred_request_queue_.front();
+ if (stream_info_map_[evicted_send.pipeline_id].state != STREAM_CLOSED) {
+ evicted_send.callback->Run(ERR_PIPELINE_EVICTION);
+ }
+ deferred_request_queue_.pop();
+ }
+ return result;
+}
+
+int HttpPipelinedConnectionImpl::ReadResponseHeaders(
+ int pipeline_id,
+ OldCompletionCallback* callback) {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_SENT);
+ CHECK(!stream_info_map_[pipeline_id].read_headers_callback);
+ 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) {
+ read_next_state_ = READ_STATE_NEXT_HEADERS;
+ return DoReadHeadersLoop(OK);
+ } else {
+ return ERR_IO_PENDING;
+ }
+}
+
+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_NEXT_HEADERS:
+ rv = DoReadNextHeaders(rv);
+ break;
+ case READ_STATE_COMPLETE:
+ rv = DoReadHeadersComplete(rv);
+ break;
+ case READ_STATE_WAITING_FOR_CLOSE:
+ rv = DoReadWaitingForClose(rv);
+ return rv;
+ case READ_STATE_STREAM_CLOSED:
+ rv = DoReadStreamClosed();
+ break;
+ case READ_STATE_UNUSABLE:
+ rv = DoEvictPendingReadHeaders(rv);
+ break;
+ case READ_STATE_NONE:
+ break;
+ default:
+ NOTREACHED() << "bad read state";
+ rv = ERR_FAILED;
+ break;
+ }
+ } while (rv != ERR_IO_PENDING && read_next_state_ != READ_STATE_NONE);
+ return rv;
+}
+
+void HttpPipelinedConnectionImpl::OnReadIOCallback(int result) {
+ CHECK(read_user_callback_);
+ DoReadHeadersLoop(result);
+}
+
+int HttpPipelinedConnectionImpl::DoReadNextHeaders(int result) {
+ CHECK(!request_order_.empty());
+ int pipeline_id = request_order_.front();
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ if (stream_info_map_[pipeline_id].state == 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_UNUSABLE;
+ return OK;
+ }
+ if (stream_info_map_[pipeline_id].read_headers_callback == NULL) {
+ return ERR_IO_PENDING;
+ }
+ CHECK(stream_info_map_[pipeline_id].parser.get());
+
+ if (result == ERR_IO_PENDING) {
+ CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_ACTIVE);
+ } else {
+ CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_READ_PENDING);
+ stream_info_map_[pipeline_id].state = STREAM_ACTIVE;
+ }
+
+ int rv = stream_info_map_[pipeline_id].parser->ReadResponseHeaders(
+ &read_io_callback_);
+ if (rv == ERR_IO_PENDING) {
+ read_next_state_ = READ_STATE_COMPLETE;
+ read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback;
+ } else if (rv < OK) {
+ read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
+ if (rv == ERR_SOCKET_NOT_CONNECTED && completed_one_request_)
+ rv = ERR_PIPELINE_EVICTION;
+ } else {
+ CHECK_LE(OK, rv);
+ read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
+ }
+
+ // |result| == ERR_IO_PENDING means this function was *not* called on the same
+ // stack as ReadResponseHeaders(). That means we returned ERR_IO_PENDING to
+ // ReadResponseHeaders() earlier and now need to invoke its callback.
+ if (rv != ERR_IO_PENDING && result == ERR_IO_PENDING) {
+ read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
+ read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback;
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::FireUserCallback,
+ read_user_callback_,
+ rv));
+ }
+ return rv;
+}
+
+int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) {
+ read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
+ if (read_user_callback_) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::FireUserCallback,
+ read_user_callback_,
+ result));
+ read_user_callback_ = NULL;
+ }
+ return result;
+}
+
+int HttpPipelinedConnectionImpl::DoReadWaitingForClose(int result) {
+ read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
+ return result;
+}
+
+int HttpPipelinedConnectionImpl::DoReadStreamClosed() {
+ CHECK(!request_order_.empty());
+ int pipeline_id = request_order_.front();
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_CLOSED);
+ CHECK(stream_info_map_[pipeline_id].read_headers_callback);
+ stream_info_map_[pipeline_id].read_headers_callback = NULL;
+ request_order_.pop();
+ if (!usable_) {
+ read_next_state_ = READ_STATE_UNUSABLE;
+ return OK;
+ } else {
+ completed_one_request_ = true;
+ if (!request_order_.empty()) {
+ int next_pipeline_id = request_order_.front();
+ CHECK(ContainsKey(stream_info_map_, next_pipeline_id));
+ if (stream_info_map_[next_pipeline_id].read_headers_callback) {
+ stream_info_map_[next_pipeline_id].state = STREAM_ACTIVE;
+ read_next_state_ = READ_STATE_NEXT_HEADERS;
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::DoReadHeadersLoop,
+ ERR_IO_PENDING));
+ return ERR_IO_PENDING; // Wait for the task to fire.
+ }
+ }
+ 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) ||
+ (stream_info_map_[evicted_id].read_headers_callback == NULL)) {
+ continue;
+ }
+ if (stream_info_map_[evicted_id].state != STREAM_CLOSED) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpPipelinedConnectionImpl::FireUserCallback,
+ stream_info_map_[evicted_id].read_headers_callback,
+ ERR_PIPELINE_EVICTION));
+ }
+ stream_info_map_[evicted_id].read_headers_callback = NULL;
+ }
+ read_next_state_ = READ_STATE_NONE;
+ return result;
+}
+
+void HttpPipelinedConnectionImpl::Close(int pipeline_id,
+ bool not_reusable) {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ 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;
+ send_user_callback_ = NULL;
+ send_next_state_ = SEND_STATE_UNUSABLE;
+ DoSendRequestLoop(OK);
+ break;
+
+ case STREAM_SENT:
+ case STREAM_READ_PENDING:
+ usable_ = false;
+ stream_info_map_[pipeline_id].state = STREAM_CLOSED;
+ stream_info_map_[pipeline_id].read_headers_callback = NULL;
+ if (read_next_state_ == READ_STATE_NONE) {
+ read_next_state_ = READ_STATE_UNUSABLE;
+ 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;
+ read_user_callback_ = NULL;
+ DoReadHeadersLoop(OK);
+ break;
+
+ case STREAM_CLOSED:
+ case STREAM_UNUSED:
+ // TODO(simonjam): Why is Close() sometimes called twice?
+ break;
+
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+int HttpPipelinedConnectionImpl::ReadResponseBody(
+ int pipeline_id,
+ IOBuffer* buf,
+ int buf_len,
+ OldCompletionCallback* callback) {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK(!request_order_.empty());
+ CHECK_EQ(pipeline_id, request_order_.front());
+ CHECK(stream_info_map_[pipeline_id].parser.get());
+ return stream_info_map_[pipeline_id].parser->ReadResponseBody(
+ buf, buf_len, callback);
+}
+
+uint64 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::IsMoreDataBuffered(int pipeline_id) const {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ return read_buf_->offset() != 0;
+}
+
+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_is_reused(true);
+}
+
+void HttpPipelinedConnectionImpl::GetSSLInfo(int pipeline_id,
+ SSLInfo* ssl_info) {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK(stream_info_map_[pipeline_id].parser.get());
+ return 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());
+ return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo(
+ cert_request_info);
+}
+
+void HttpPipelinedConnectionImpl::FireUserCallback(
+ OldCompletionCallback* callback,
+ int result) {
+ CHECK(callback);
+ 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 NetLog::Source& HttpPipelinedConnectionImpl::source() const {
+ return net_log_.source();
+}
+
+bool HttpPipelinedConnectionImpl::was_npn_negotiated() const {
+ return was_npn_negotiated_;
+}
+
+HttpPipelinedConnectionImpl::DeferredSendRequest::DeferredSendRequest() {
+}
+
+HttpPipelinedConnectionImpl::DeferredSendRequest::~DeferredSendRequest() {
+}
+
+HttpPipelinedConnectionImpl::StreamInfo::StreamInfo()
+ : read_headers_callback(NULL),
+ state(STREAM_CREATED) {
+}
+
+HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() {
+}
+
+} // namespace net
« no previous file with comments | « net/http/http_pipelined_connection_impl.h ('k') | net/http/http_pipelined_connection_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698