Index: net/http/http_pipelined_connection.h |
diff --git a/net/http/http_pipelined_connection.h b/net/http/http_pipelined_connection.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6d2870c869ddc78501acc91dfac01ab2d5f1f013 |
--- /dev/null |
+++ b/net/http/http_pipelined_connection.h |
@@ -0,0 +1,205 @@ |
+// 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. |
+// |
+// This class manages all of the state for a single pipelined connection. It |
mmenke
2011/08/03 21:09:39
nit: All this should go just before the class, ra
James Simonsen
2011/08/05 01:39:00
Done.
|
+// 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. |
+ |
+#ifndef NET_HTTP_HTTP_PIPELINED_CONNECTION_H_ |
+#define NET_HTTP_HTTP_PIPELINED_CONNECTION_H_ |
+#pragma once |
+ |
+#include <map> |
+#include <queue> |
+#include <string> |
+ |
+#include "base/basictypes.h" |
+#include "base/task.h" |
+#include "net/base/completion_callback.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_request_info.h" |
+#include "net/proxy/proxy_info.h" |
+ |
+namespace net { |
+ |
+class ClientSocketHandle; |
+class GrowableIOBuffer; |
+class HttpPipelinedHost; |
+class HttpPipelinedStream; |
+class HttpRequestHeaders; |
+class HttpResponseInfo; |
+class HttpStreamParser; |
+class IOBuffer; |
+class SSLCertRequestInfo; |
+class SSLInfo; |
+ |
+class HttpPipelinedConnection { |
+ public: |
+ HttpPipelinedConnection(ClientSocketHandle* connection, |
+ HttpPipelinedHost* host, |
+ const SSLConfig& used_ssl_config, |
+ const ProxyInfo& used_proxy_info, |
+ const BoundNetLog& net_log, |
+ bool was_npn_negotiated); |
+ ~HttpPipelinedConnection(); |
+ |
+ // The number of HTTP requests pending on this pipeline. |
+ int depth() const { return stream_state_map_.size(); } |
+ |
+ // True if this pipeline can accept new HTTP requests. False if a fatal error |
+ // has occurred. |
+ bool usable() const { return usable_; } |
+ |
+ // True if this pipeline has bound one request is ready for additional |
mmenke
2011/08/03 21:09:39
nit: "has bound one request and...".
James Simonsen
2011/08/05 01:39:00
Done.
|
+ // requests. |
+ bool active() const { return active_; } |
+ |
+ const SSLConfig& used_ssl_config() const { return used_ssl_config_; } |
+ const ProxyInfo& used_proxy_info() const { return used_proxy_info_; } |
+ const NetLog::Source& source() const { return net_log_.source(); } |
+ bool was_npn_negotiated() const { return was_npn_negotiated_; } |
+ |
+ // HttpPipelinedStream uses these functions. |
+ |
+ // Associates a HttpPipelinedStream with this connection. Returns a unique |
+ // identifier. |
+ int AddStream(); |
+ |
+ // Disassociates a previously associated HttpPipelinedStream. |
+ void RemoveStream(int pipeline_id); |
+ |
+ // Constructs a HttpStreamParser for the associated HttpPipelinedStream. |
+ void InitializeParser(int pipeline_id, |
+ const HttpRequestInfo* request, |
+ const BoundNetLog& net_log); |
+ |
+ // Indirect implementation of HttpStream used by our HttpPipelinedStreams. |
+ int SendRequest(int pipeline_id, |
+ const std::string& request_line, |
+ const HttpRequestHeaders& headers, |
+ UploadDataStream* request_body, |
+ HttpResponseInfo* response, |
+ CompletionCallback* callback); |
+ |
+ int ReadResponseHeaders(int pipeline_id, |
+ CompletionCallback* callback); |
+ |
+ int ReadResponseBody(int pipeline_id, |
+ IOBuffer* buf, int buf_len, |
+ CompletionCallback* 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_SENT, |
+ STREAM_CLOSED, |
+ }; |
+ 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_STREAM_CLOSED, |
+ READ_STATE_NONE, |
+ READ_STATE_UNUSABLE, |
+ }; |
+ |
+ struct DeferredSendRequest { |
+ int pipeline_id; |
+ std::string request_line; |
+ HttpRequestHeaders headers; |
+ UploadDataStream* request_body; |
+ HttpResponseInfo* response; |
+ CompletionCallback* callback; |
+ }; |
+ |
+ // Called after the first request is processed, allowing the rest of this |
+ // pipeline to fill up with any pending requests. |
+ void FillPipeline(); |
+ |
+ int DoSendRequestLoop(int result); |
+ void OnSendIOCallback(int result); |
+ int DoSendNextRequest(int result); |
mmenke
2011/08/03 21:09:39
It'd great to have comments on what these function
James Simonsen
2011/08/05 01:39:00
Done.
|
+ int DoSendComplete(int result); |
+ int DoEvictPendingSendRequests(int result); |
+ |
+ int DoReadHeadersLoop(int result); |
+ void OnReadIOCallback(int result); |
+ int DoReadNextHeaders(int result); |
+ int DoReadHeadersComplete(int result); |
+ int DoStreamClosed(); |
+ int DoEvictPendingReadHeaders(int result); |
+ |
+ void FireUserCallback(CompletionCallback* callback, int result); |
+ |
+ HttpPipelinedHost* host_; |
+ 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_; |
+ ScopedRunnableMethodFactory<HttpPipelinedConnection> method_factory_; |
+ |
+ typedef std::map<int, StreamState> StreamStateMap; |
+ StreamStateMap stream_state_map_; |
+ typedef std::map<int, HttpStreamParser*> ParserMap; |
+ ParserMap parser_map_; |
+ |
+ std::queue<int> request_order_; |
+ |
+ std::queue<DeferredSendRequest> deferred_request_queue_; |
+ SendRequestState send_next_state_; |
+ CompletionCallbackImpl<HttpPipelinedConnection> send_io_callback_; |
+ CompletionCallback* send_user_callback_; |
+ |
+ ReadHeadersState read_next_state_; |
+ CompletionCallbackImpl<HttpPipelinedConnection> read_io_callback_; |
+ CompletionCallback* read_user_callback_; |
+ typedef std::map<int, CompletionCallback*> CallbackMap; |
+ CallbackMap callback_map_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HttpPipelinedConnection); |
+}; |
+ |
+} // namespace net |
+ |
+#endif // NET_HTTP_HTTP_PIPELINED_CONNECTION_H_ |