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