OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |
| 6 #define NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |
| 7 #pragma once |
| 8 |
| 9 #include <map> |
| 10 #include <queue> |
| 11 #include <string> |
| 12 |
| 13 #include "base/basictypes.h" |
| 14 #include "base/memory/linked_ptr.h" |
| 15 #include "base/task.h" |
| 16 #include "net/base/completion_callback.h" |
| 17 #include "net/base/net_export.h" |
| 18 #include "net/base/net_log.h" |
| 19 #include "net/base/ssl_config_service.h" |
| 20 #include "net/base/upload_data_stream.h" |
| 21 #include "net/http/http_pipelined_connection.h" |
| 22 #include "net/http/http_request_info.h" |
| 23 #include "net/http/http_stream_parser.h" |
| 24 #include "net/proxy/proxy_info.h" |
| 25 |
| 26 namespace net { |
| 27 |
| 28 class ClientSocketHandle; |
| 29 class GrowableIOBuffer; |
| 30 class HttpRequestHeaders; |
| 31 class HttpResponseInfo; |
| 32 class IOBuffer; |
| 33 class SSLCertRequestInfo; |
| 34 class SSLInfo; |
| 35 |
| 36 // This class manages all of the state for a single pipelined connection. It |
| 37 // tracks the order that HTTP requests are sent and enforces that the |
| 38 // subsequent reads occur in the appropriate order. |
| 39 // |
| 40 // If an error occurs related to pipelining, ERR_PIPELINE_EVICTION will be |
| 41 // returned to the client. This indicates the client should retry the request |
| 42 // without pipelining. |
| 43 class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl |
| 44 : public HttpPipelinedConnection { |
| 45 public: |
| 46 HttpPipelinedConnectionImpl(ClientSocketHandle* connection, |
| 47 Delegate* delegate, |
| 48 const SSLConfig& used_ssl_config, |
| 49 const ProxyInfo& used_proxy_info, |
| 50 const BoundNetLog& net_log, |
| 51 bool was_npn_negotiated); |
| 52 virtual ~HttpPipelinedConnectionImpl(); |
| 53 |
| 54 // HttpPipelinedConnection interface. |
| 55 |
| 56 // Used by HttpStreamFactoryImpl and friends. |
| 57 virtual HttpPipelinedStream* CreateNewStream() OVERRIDE; |
| 58 |
| 59 // Used by HttpPipelinedHost. |
| 60 virtual int depth() const OVERRIDE; |
| 61 virtual bool usable() const OVERRIDE; |
| 62 virtual bool active() const OVERRIDE; |
| 63 |
| 64 // Used by HttpStreamFactoryImpl. |
| 65 virtual const SSLConfig& used_ssl_config() const OVERRIDE; |
| 66 virtual const ProxyInfo& used_proxy_info() const OVERRIDE; |
| 67 virtual const NetLog::Source& source() const OVERRIDE; |
| 68 virtual bool was_npn_negotiated() const OVERRIDE; |
| 69 |
| 70 // Used by HttpPipelinedStream. |
| 71 |
| 72 // Notifies this pipeline that a stream is no longer using it. |
| 73 void OnStreamDeleted(int pipeline_id); |
| 74 |
| 75 // Effective implementation of HttpStream. Note that we don't directly |
| 76 // implement that interface. Instead, these functions will be called by the |
| 77 // pass-through methods in HttpPipelinedStream. |
| 78 void InitializeParser(int pipeline_id, |
| 79 const HttpRequestInfo* request, |
| 80 const BoundNetLog& net_log); |
| 81 |
| 82 int SendRequest(int pipeline_id, |
| 83 const std::string& request_line, |
| 84 const HttpRequestHeaders& headers, |
| 85 UploadDataStream* request_body, |
| 86 HttpResponseInfo* response, |
| 87 OldCompletionCallback* callback); |
| 88 |
| 89 int ReadResponseHeaders(int pipeline_id, |
| 90 OldCompletionCallback* callback); |
| 91 |
| 92 int ReadResponseBody(int pipeline_id, |
| 93 IOBuffer* buf, int buf_len, |
| 94 OldCompletionCallback* callback); |
| 95 |
| 96 void Close(int pipeline_id, |
| 97 bool not_reusable); |
| 98 |
| 99 uint64 GetUploadProgress(int pipeline_id) const; |
| 100 |
| 101 HttpResponseInfo* GetResponseInfo(int pipeline_id); |
| 102 |
| 103 bool IsResponseBodyComplete(int pipeline_id) const; |
| 104 |
| 105 bool CanFindEndOfResponse(int pipeline_id) const; |
| 106 |
| 107 bool IsMoreDataBuffered(int pipeline_id) const; |
| 108 |
| 109 bool IsConnectionReused(int pipeline_id) const; |
| 110 |
| 111 void SetConnectionReused(int pipeline_id); |
| 112 |
| 113 void GetSSLInfo(int pipeline_id, |
| 114 SSLInfo* ssl_info); |
| 115 |
| 116 void GetSSLCertRequestInfo(int pipeline_id, |
| 117 SSLCertRequestInfo* cert_request_info); |
| 118 |
| 119 private: |
| 120 enum StreamState { |
| 121 STREAM_CREATED, |
| 122 STREAM_BOUND, |
| 123 STREAM_SENDING, |
| 124 STREAM_SENT, |
| 125 STREAM_READ_PENDING, |
| 126 STREAM_ACTIVE, |
| 127 STREAM_CLOSED, |
| 128 STREAM_UNUSED, |
| 129 }; |
| 130 enum SendRequestState { |
| 131 SEND_STATE_NEXT_REQUEST, |
| 132 SEND_STATE_COMPLETE, |
| 133 SEND_STATE_NONE, |
| 134 SEND_STATE_UNUSABLE, |
| 135 }; |
| 136 enum ReadHeadersState { |
| 137 READ_STATE_NEXT_HEADERS, |
| 138 READ_STATE_COMPLETE, |
| 139 READ_STATE_WAITING_FOR_CLOSE, |
| 140 READ_STATE_STREAM_CLOSED, |
| 141 READ_STATE_NONE, |
| 142 READ_STATE_UNUSABLE, |
| 143 }; |
| 144 |
| 145 struct DeferredSendRequest { |
| 146 DeferredSendRequest(); |
| 147 ~DeferredSendRequest(); |
| 148 |
| 149 int pipeline_id; |
| 150 std::string request_line; |
| 151 HttpRequestHeaders headers; |
| 152 UploadDataStream* request_body; |
| 153 HttpResponseInfo* response; |
| 154 OldCompletionCallback* callback; |
| 155 }; |
| 156 |
| 157 struct StreamInfo { |
| 158 StreamInfo(); |
| 159 ~StreamInfo(); |
| 160 |
| 161 linked_ptr<HttpStreamParser> parser; |
| 162 OldCompletionCallback* read_headers_callback; |
| 163 StreamState state; |
| 164 }; |
| 165 |
| 166 typedef std::map<int, StreamInfo> StreamInfoMap; |
| 167 |
| 168 // Called after the first request is sent or in a task sometime after the |
| 169 // first stream is added to this pipeline. This gives the first request |
| 170 // priority to send, but doesn't hold up other requests if it doesn't. |
| 171 // When called the first time, notifies the |delegate_| that we can accept new |
| 172 // requests. |
| 173 void ActivatePipeline(); |
| 174 |
| 175 // Responsible for sending one request at a time and waiting until each |
| 176 // comepletes. |
| 177 int DoSendRequestLoop(int result); |
| 178 |
| 179 // Called when an asynchronous Send() completes. |
| 180 void OnSendIOCallback(int result); |
| 181 |
| 182 // Sends the next deferred request. This may be called immediately after |
| 183 // SendRequest(), or it may be in a new task after a prior send completes in |
| 184 // DoSendComplete(). |
| 185 int DoSendNextRequest(int result); |
| 186 |
| 187 // Notifies the user that the send has completed. This may be called directly |
| 188 // after SendRequest() for a synchronous request, or it may be called in |
| 189 // response to OnSendIOCallback for an asynchronous request. |
| 190 int DoSendComplete(int result); |
| 191 |
| 192 // Evicts all unsent deferred requests. This is called if there is a Send() |
| 193 // error or one of our streams informs us the connection is no longer |
| 194 // reusable. |
| 195 int DoEvictPendingSendRequests(int result); |
| 196 |
| 197 // Ensures that only the active request's HttpPipelinedSocket can read from |
| 198 // the underlying socket until it completes. A HttpPipelinedSocket informs us |
| 199 // that it's done by calling Close(). |
| 200 int DoReadHeadersLoop(int result); |
| 201 |
| 202 // Called when the pending asynchronous ReadResponseHeaders() completes. |
| 203 void OnReadIOCallback(int result); |
| 204 |
| 205 // Determines if the next response in the pipeline is ready to be read. |
| 206 // If it's ready, then we call ReadResponseHeaders() on the underlying parser. |
| 207 // HttpPipelinedSocket indicates its readiness by calling |
| 208 // ReadResponseHeaders(). This function may be called immediately after |
| 209 // ReadResponseHeaders(), or it may be called in a new task after a previous |
| 210 // HttpPipelinedSocket finishes its work. |
| 211 int DoReadNextHeaders(int result); |
| 212 |
| 213 // Notifies the user that reading the headers has completed. This may happen |
| 214 // directly after DoReadNextHeaders() if the response is already available. |
| 215 // Otherwise, it is called in response to OnReadIOCallback(). |
| 216 int DoReadHeadersComplete(int result); |
| 217 |
| 218 // This is a holding state. It does not do anything, except exit the |
| 219 // DoReadHeadersLoop(). It is called after DoReadHeadersComplete(). |
| 220 int DoReadWaitingForClose(int result); |
| 221 |
| 222 // Cleans up the state associated with the active request. Invokes |
| 223 // DoReadNextHeaders() in a new task to start the next response. This is |
| 224 // called after the active request's HttpPipelinedSocket calls Close(). |
| 225 int DoReadStreamClosed(); |
| 226 |
| 227 // Removes all pending ReadResponseHeaders() requests from the queue. This may |
| 228 // happen if there is an error with the pipeline or one of our |
| 229 // HttpPipelinedSockets indicates the connection was suddenly closed. |
| 230 int DoEvictPendingReadHeaders(int result); |
| 231 |
| 232 // Invokes the user's callback in response to SendRequest() or |
| 233 // ReadResponseHeaders() completing on an underlying parser. This might be |
| 234 // invoked in response to our own IO callbacks, or it may be invoked if the |
| 235 // underlying parser completes SendRequest() or ReadResponseHeaders() |
| 236 // synchronously, but we've already returned ERR_IO_PENDING to the user's |
| 237 // SendRequest() or ReadResponseHeaders() call into us. |
| 238 void FireUserCallback(OldCompletionCallback* callback, int result); |
| 239 |
| 240 Delegate* delegate_; |
| 241 scoped_ptr<ClientSocketHandle> connection_; |
| 242 SSLConfig used_ssl_config_; |
| 243 ProxyInfo used_proxy_info_; |
| 244 BoundNetLog net_log_; |
| 245 bool was_npn_negotiated_; |
| 246 scoped_refptr<GrowableIOBuffer> read_buf_; |
| 247 int next_pipeline_id_; |
| 248 bool active_; |
| 249 bool usable_; |
| 250 bool completed_one_request_; |
| 251 ScopedRunnableMethodFactory<HttpPipelinedConnectionImpl> method_factory_; |
| 252 |
| 253 StreamInfoMap stream_info_map_; |
| 254 |
| 255 std::queue<int> request_order_; |
| 256 |
| 257 std::queue<DeferredSendRequest> deferred_request_queue_; |
| 258 SendRequestState send_next_state_; |
| 259 OldCompletionCallbackImpl<HttpPipelinedConnectionImpl> send_io_callback_; |
| 260 OldCompletionCallback* send_user_callback_; |
| 261 |
| 262 ReadHeadersState read_next_state_; |
| 263 OldCompletionCallbackImpl<HttpPipelinedConnectionImpl> read_io_callback_; |
| 264 OldCompletionCallback* read_user_callback_; |
| 265 |
| 266 DISALLOW_COPY_AND_ASSIGN(HttpPipelinedConnectionImpl); |
| 267 }; |
| 268 |
| 269 } // namespace net |
| 270 |
| 271 #endif // NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_ |
OLD | NEW |