Index: net/http/http_pipelined_connection_impl.h |
diff --git a/net/http/http_pipelined_connection_impl.h b/net/http/http_pipelined_connection_impl.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bf39e625326ba7a6db3be3d3b3090daf2c7d7cf5 |
--- /dev/null |
+++ b/net/http/http_pipelined_connection_impl.h |
@@ -0,0 +1,271 @@ |
+// 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. |
+ |
+#ifndef NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |
+#define NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |
+#pragma once |
+ |
+#include <map> |
+#include <queue> |
+#include <string> |
+ |
+#include "base/basictypes.h" |
+#include "base/memory/linked_ptr.h" |
+#include "base/task.h" |
+#include "net/base/completion_callback.h" |
+#include "net/base/net_export.h" |
+#include "net/base/net_log.h" |
+#include "net/base/ssl_config_service.h" |
+#include "net/base/upload_data_stream.h" |
+#include "net/http/http_pipelined_connection.h" |
+#include "net/http/http_request_info.h" |
+#include "net/http/http_stream_parser.h" |
+#include "net/proxy/proxy_info.h" |
+ |
+namespace net { |
+ |
+class ClientSocketHandle; |
+class GrowableIOBuffer; |
+class HttpRequestHeaders; |
+class HttpResponseInfo; |
+class IOBuffer; |
+class SSLCertRequestInfo; |
+class SSLInfo; |
+ |
+// This class manages all of the state for a single pipelined connection. It |
+// tracks the order that HTTP requests are sent and enforces that the |
+// subsequent reads occur in the appropriate order. |
+// |
+// If an error occurs related to pipelining, ERR_PIPELINE_EVICTION will be |
+// returned to the client. This indicates the client should retry the request |
+// without pipelining. |
+class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl |
+ : public HttpPipelinedConnection { |
+ public: |
+ HttpPipelinedConnectionImpl(ClientSocketHandle* connection, |
+ Delegate* delegate, |
+ const SSLConfig& used_ssl_config, |
+ const ProxyInfo& used_proxy_info, |
+ const BoundNetLog& net_log, |
+ bool was_npn_negotiated); |
+ virtual ~HttpPipelinedConnectionImpl(); |
+ |
+ // HttpPipelinedConnection interface. |
+ |
+ // Used by HttpStreamFactoryImpl and friends. |
+ virtual HttpPipelinedStream* CreateNewStream() OVERRIDE; |
+ |
+ // Used by HttpPipelinedHost. |
+ virtual int depth() const OVERRIDE; |
+ virtual bool usable() const OVERRIDE; |
+ virtual bool active() const OVERRIDE; |
+ |
+ // Used by HttpStreamFactoryImpl. |
+ virtual const SSLConfig& used_ssl_config() const OVERRIDE; |
+ virtual const ProxyInfo& used_proxy_info() const OVERRIDE; |
+ virtual const NetLog::Source& source() const OVERRIDE; |
+ virtual bool was_npn_negotiated() const OVERRIDE; |
+ |
+ // Used by HttpPipelinedStream. |
+ |
+ // Notifies this pipeline that a stream is no longer using it. |
+ void OnStreamDeleted(int pipeline_id); |
+ |
+ // Effective implementation of HttpStream. Note that we don't directly |
+ // implement that interface. Instead, these functions will be called by the |
+ // pass-through methods in HttpPipelinedStream. |
+ void InitializeParser(int pipeline_id, |
+ const HttpRequestInfo* request, |
+ const BoundNetLog& net_log); |
+ |
+ int SendRequest(int pipeline_id, |
+ const std::string& request_line, |
+ const HttpRequestHeaders& headers, |
+ UploadDataStream* request_body, |
+ HttpResponseInfo* response, |
+ OldCompletionCallback* callback); |
+ |
+ int ReadResponseHeaders(int pipeline_id, |
+ OldCompletionCallback* callback); |
+ |
+ int ReadResponseBody(int pipeline_id, |
+ IOBuffer* buf, int buf_len, |
+ OldCompletionCallback* callback); |
+ |
+ void Close(int pipeline_id, |
+ bool not_reusable); |
+ |
+ uint64 GetUploadProgress(int pipeline_id) const; |
+ |
+ HttpResponseInfo* GetResponseInfo(int pipeline_id); |
+ |
+ bool IsResponseBodyComplete(int pipeline_id) const; |
+ |
+ bool CanFindEndOfResponse(int pipeline_id) const; |
+ |
+ bool IsMoreDataBuffered(int pipeline_id) const; |
+ |
+ bool IsConnectionReused(int pipeline_id) const; |
+ |
+ void SetConnectionReused(int pipeline_id); |
+ |
+ void GetSSLInfo(int pipeline_id, |
+ SSLInfo* ssl_info); |
+ |
+ void GetSSLCertRequestInfo(int pipeline_id, |
+ SSLCertRequestInfo* cert_request_info); |
+ |
+ private: |
+ enum StreamState { |
+ STREAM_CREATED, |
+ STREAM_BOUND, |
+ STREAM_SENDING, |
+ STREAM_SENT, |
+ STREAM_READ_PENDING, |
+ STREAM_ACTIVE, |
+ STREAM_CLOSED, |
+ STREAM_UNUSED, |
+ }; |
+ enum SendRequestState { |
+ SEND_STATE_NEXT_REQUEST, |
+ SEND_STATE_COMPLETE, |
+ SEND_STATE_NONE, |
+ SEND_STATE_UNUSABLE, |
+ }; |
+ enum ReadHeadersState { |
+ READ_STATE_NEXT_HEADERS, |
+ READ_STATE_COMPLETE, |
+ READ_STATE_WAITING_FOR_CLOSE, |
+ READ_STATE_STREAM_CLOSED, |
+ READ_STATE_NONE, |
+ READ_STATE_UNUSABLE, |
+ }; |
+ |
+ struct DeferredSendRequest { |
+ DeferredSendRequest(); |
+ ~DeferredSendRequest(); |
+ |
+ int pipeline_id; |
+ std::string request_line; |
+ HttpRequestHeaders headers; |
+ UploadDataStream* request_body; |
+ HttpResponseInfo* response; |
+ OldCompletionCallback* callback; |
+ }; |
+ |
+ struct StreamInfo { |
+ StreamInfo(); |
+ ~StreamInfo(); |
+ |
+ linked_ptr<HttpStreamParser> parser; |
+ OldCompletionCallback* read_headers_callback; |
+ StreamState state; |
+ }; |
+ |
+ typedef std::map<int, StreamInfo> StreamInfoMap; |
+ |
+ // Called after the first request is sent or in a task sometime after the |
+ // first stream is added to this pipeline. This gives the first request |
+ // priority to send, but doesn't hold up other requests if it doesn't. |
+ // When called the first time, notifies the |delegate_| that we can accept new |
+ // requests. |
+ void ActivatePipeline(); |
+ |
+ // Responsible for sending one request at a time and waiting until each |
+ // comepletes. |
+ int DoSendRequestLoop(int result); |
+ |
+ // Called when an asynchronous Send() completes. |
+ void OnSendIOCallback(int result); |
+ |
+ // Sends the next deferred request. This may be called immediately after |
+ // SendRequest(), or it may be in a new task after a prior send completes in |
+ // DoSendComplete(). |
+ int DoSendNextRequest(int result); |
+ |
+ // Notifies the user that the send has completed. This may be called directly |
+ // after SendRequest() for a synchronous request, or it may be called in |
+ // response to OnSendIOCallback for an asynchronous request. |
+ int DoSendComplete(int result); |
+ |
+ // Evicts all unsent deferred requests. This is called if there is a Send() |
+ // error or one of our streams informs us the connection is no longer |
+ // reusable. |
+ int DoEvictPendingSendRequests(int result); |
+ |
+ // Ensures that only the active request's HttpPipelinedSocket can read from |
+ // the underlying socket until it completes. A HttpPipelinedSocket informs us |
+ // that it's done by calling Close(). |
+ int DoReadHeadersLoop(int result); |
+ |
+ // Called when the pending asynchronous ReadResponseHeaders() completes. |
+ void OnReadIOCallback(int result); |
+ |
+ // Determines if the next response in the pipeline is ready to be read. |
+ // If it's ready, then we call ReadResponseHeaders() on the underlying parser. |
+ // HttpPipelinedSocket indicates its readiness by calling |
+ // ReadResponseHeaders(). This function may be called immediately after |
+ // ReadResponseHeaders(), or it may be called in a new task after a previous |
+ // HttpPipelinedSocket finishes its work. |
+ int DoReadNextHeaders(int result); |
+ |
+ // Notifies the user that reading the headers has completed. This may happen |
+ // directly after DoReadNextHeaders() if the response is already available. |
+ // Otherwise, it is called in response to OnReadIOCallback(). |
+ int DoReadHeadersComplete(int result); |
+ |
+ // This is a holding state. It does not do anything, except exit the |
+ // DoReadHeadersLoop(). It is called after DoReadHeadersComplete(). |
+ int DoReadWaitingForClose(int result); |
+ |
+ // Cleans up the state associated with the active request. Invokes |
+ // DoReadNextHeaders() in a new task to start the next response. This is |
+ // called after the active request's HttpPipelinedSocket calls Close(). |
+ int DoReadStreamClosed(); |
+ |
+ // Removes all pending ReadResponseHeaders() requests from the queue. This may |
+ // happen if there is an error with the pipeline or one of our |
+ // HttpPipelinedSockets indicates the connection was suddenly closed. |
+ int DoEvictPendingReadHeaders(int result); |
+ |
+ // Invokes the user's callback in response to SendRequest() or |
+ // ReadResponseHeaders() completing on an underlying parser. This might be |
+ // invoked in response to our own IO callbacks, or it may be invoked if the |
+ // underlying parser completes SendRequest() or ReadResponseHeaders() |
+ // synchronously, but we've already returned ERR_IO_PENDING to the user's |
+ // SendRequest() or ReadResponseHeaders() call into us. |
+ void FireUserCallback(OldCompletionCallback* callback, int result); |
+ |
+ Delegate* delegate_; |
+ scoped_ptr<ClientSocketHandle> connection_; |
+ SSLConfig used_ssl_config_; |
+ ProxyInfo used_proxy_info_; |
+ BoundNetLog net_log_; |
+ bool was_npn_negotiated_; |
+ scoped_refptr<GrowableIOBuffer> read_buf_; |
+ int next_pipeline_id_; |
+ bool active_; |
+ bool usable_; |
+ bool completed_one_request_; |
+ ScopedRunnableMethodFactory<HttpPipelinedConnectionImpl> method_factory_; |
+ |
+ StreamInfoMap stream_info_map_; |
+ |
+ std::queue<int> request_order_; |
+ |
+ std::queue<DeferredSendRequest> deferred_request_queue_; |
+ SendRequestState send_next_state_; |
+ OldCompletionCallbackImpl<HttpPipelinedConnectionImpl> send_io_callback_; |
+ OldCompletionCallback* send_user_callback_; |
+ |
+ ReadHeadersState read_next_state_; |
+ OldCompletionCallbackImpl<HttpPipelinedConnectionImpl> read_io_callback_; |
+ OldCompletionCallback* read_user_callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HttpPipelinedConnectionImpl); |
+}; |
+ |
+} // namespace net |
+ |
+#endif // NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |