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

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

Powered by Google App Engine
This is Rietveld 408576698