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

Side by Side Diff: net/http/http_pipelined_connection_impl.h

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

Powered by Google App Engine
This is Rietveld 408576698