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

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

Issue 7289006: Basic HTTP pipelining support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge 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 #include "net/http/http_pipelined_connection_impl.h"
6
7 #include "base/message_loop.h"
8 #include "base/stl_util.h"
9 #include "net/base/io_buffer.h"
10 #include "net/http/http_pipelined_stream.h"
11 #include "net/http/http_request_info.h"
12 #include "net/http/http_stream_parser.h"
13 #include "net/socket/client_socket_handle.h"
14
15 namespace net {
16
17 HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
18 ClientSocketHandle* connection,
19 HttpPipelinedConnection::Delegate* delegate,
20 const SSLConfig& used_ssl_config,
21 const ProxyInfo& used_proxy_info,
22 const BoundNetLog& net_log,
23 bool was_npn_negotiated)
24 : delegate_(delegate),
25 connection_(connection),
26 used_ssl_config_(used_ssl_config),
27 used_proxy_info_(used_proxy_info),
28 net_log_(net_log),
29 was_npn_negotiated_(was_npn_negotiated),
30 read_buf_(new GrowableIOBuffer()),
31 next_pipeline_id_(1),
32 active_(false),
33 usable_(true),
34 completed_one_request_(false),
35 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
36 send_next_state_(SEND_STATE_NONE),
37 ALLOW_THIS_IN_INITIALIZER_LIST(send_io_callback_(
38 this, &HttpPipelinedConnectionImpl::OnSendIOCallback)),
39 send_user_callback_(NULL),
40 read_next_state_(READ_STATE_NONE),
41 ALLOW_THIS_IN_INITIALIZER_LIST(read_io_callback_(
42 this, &HttpPipelinedConnectionImpl::OnReadIOCallback)),
43 read_user_callback_(NULL) {
44 CHECK(connection_.get());
45 }
46
47 HttpPipelinedConnectionImpl::~HttpPipelinedConnectionImpl() {
48 CHECK_EQ(depth(), 0);
49 CHECK(stream_info_map_.empty());
50 CHECK(deferred_request_queue_.empty());
51 CHECK(request_order_.empty());
52 CHECK_EQ(send_next_state_, SEND_STATE_NONE);
53 CHECK_EQ(read_next_state_, READ_STATE_NONE);
54 CHECK(!send_user_callback_);
55 CHECK(!read_user_callback_);
56 if (!usable_) {
57 connection_->socket()->Disconnect();
58 }
59 connection_->Reset();
60 }
61
62 HttpPipelinedStream* HttpPipelinedConnectionImpl::CreateNewStream() {
63 int pipeline_id = next_pipeline_id_++;
64 CHECK(pipeline_id);
65 HttpPipelinedStream* stream = new HttpPipelinedStream(this, pipeline_id);
66 stream_info_map_.insert(std::make_pair(pipeline_id, StreamInfo()));
67 return stream;
68 }
69
70 void HttpPipelinedConnectionImpl::InitializeParser(
71 int pipeline_id,
72 const HttpRequestInfo* request,
73 const BoundNetLog& net_log) {
74 CHECK(ContainsKey(stream_info_map_, pipeline_id));
75 CHECK(!stream_info_map_[pipeline_id].parser.get());
76 stream_info_map_[pipeline_id].state = STREAM_BOUND;
77 stream_info_map_[pipeline_id].parser.reset(new HttpStreamParser(
78 connection_.get(), request, read_buf_.get(), net_log));
79
80 // In case our first stream doesn't SendRequest() immediately, we should still
81 // allow others to use this pipeline.
82 if (pipeline_id == 1) {
83 MessageLoop::current()->PostTask(
84 FROM_HERE,
85 method_factory_.NewRunnableMethod(
86 &HttpPipelinedConnectionImpl::ActivatePipeline));
87 }
88 }
89
90 void HttpPipelinedConnectionImpl::ActivatePipeline() {
91 if (!active_) {
92 active_ = true;
93 delegate_->OnPipelineHasCapacity(this);
94 }
95 }
96
97 void HttpPipelinedConnectionImpl::OnStreamDeleted(int pipeline_id) {
98 CHECK(ContainsKey(stream_info_map_, pipeline_id));
99 Close(pipeline_id, false);
100
101 if (stream_info_map_[pipeline_id].state != STREAM_CREATED &&
102 stream_info_map_[pipeline_id].state != STREAM_UNUSED) {
103 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_CLOSED);
104 CHECK(stream_info_map_[pipeline_id].parser.get());
105 stream_info_map_[pipeline_id].parser.reset();
106 }
107 CHECK(!stream_info_map_[pipeline_id].parser.get());
108 CHECK(!stream_info_map_[pipeline_id].read_headers_callback);
109 stream_info_map_.erase(pipeline_id);
110
111 delegate_->OnPipelineHasCapacity(this);
112 }
113
114 int HttpPipelinedConnectionImpl::SendRequest(int pipeline_id,
115 const std::string& request_line,
116 const HttpRequestHeaders& headers,
117 UploadDataStream* request_body,
118 HttpResponseInfo* response,
119 OldCompletionCallback* callback) {
120 CHECK(ContainsKey(stream_info_map_, pipeline_id));
121 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_BOUND);
122 if (!usable_) {
123 return ERR_PIPELINE_EVICTION;
124 }
125
126 DeferredSendRequest deferred_request;
127 deferred_request.pipeline_id = pipeline_id;
128 deferred_request.request_line = request_line;
129 deferred_request.headers = headers;
130 deferred_request.request_body = request_body;
131 deferred_request.response = response;
132 deferred_request.callback = callback;
133 deferred_request_queue_.push(deferred_request);
134
135 int rv;
136 if (send_next_state_ == SEND_STATE_NONE) {
137 send_next_state_ = SEND_STATE_NEXT_REQUEST;
138 rv = DoSendRequestLoop(OK);
139 } else {
140 rv = ERR_IO_PENDING;
141 }
142 ActivatePipeline();
143 return rv;
144 }
145
146 int HttpPipelinedConnectionImpl::DoSendRequestLoop(int result) {
147 int rv = result;
148 do {
149 SendRequestState state = send_next_state_;
150 send_next_state_ = SEND_STATE_NONE;
151 switch (state) {
152 case SEND_STATE_NEXT_REQUEST:
153 rv = DoSendNextRequest(rv);
154 break;
155 case SEND_STATE_COMPLETE:
156 rv = DoSendComplete(rv);
157 break;
158 case SEND_STATE_UNUSABLE:
159 rv = DoEvictPendingSendRequests(rv);
160 break;
161 default:
162 NOTREACHED() << "bad send state: " << state;
163 rv = ERR_FAILED;
164 break;
165 }
166 } while (rv != ERR_IO_PENDING && send_next_state_ != SEND_STATE_NONE);
167 return rv;
168 }
169
170 void HttpPipelinedConnectionImpl::OnSendIOCallback(int result) {
171 CHECK(send_user_callback_);
172 DoSendRequestLoop(result);
173 }
174
175 int HttpPipelinedConnectionImpl::DoSendNextRequest(int result) {
176 CHECK(!deferred_request_queue_.empty());
177 const DeferredSendRequest& deferred_request = deferred_request_queue_.front();
178 CHECK(ContainsKey(stream_info_map_, deferred_request.pipeline_id));
179 if (stream_info_map_[deferred_request.pipeline_id].state == STREAM_CLOSED) {
180 deferred_request_queue_.pop();
181 if (deferred_request_queue_.empty()) {
182 send_next_state_ = SEND_STATE_NONE;
183 } else {
184 send_next_state_ = SEND_STATE_NEXT_REQUEST;
185 }
186 return OK;
187 }
188 CHECK(stream_info_map_[deferred_request.pipeline_id].parser.get());
189 int rv = stream_info_map_[deferred_request.pipeline_id].parser->SendRequest(
190 deferred_request.request_line,
191 deferred_request.headers,
192 deferred_request.request_body,
193 deferred_request.response,
194 &send_io_callback_);
195 // |result| == ERR_IO_PENDING means this function was *not* called on the same
196 // stack as SendRequest(). That means we returned ERR_IO_PENDING to
197 // SendRequest() earlier and will need to invoke its callback.
198 if (result == ERR_IO_PENDING || rv == ERR_IO_PENDING) {
199 send_user_callback_ = deferred_request.callback;
200 }
201 stream_info_map_[deferred_request.pipeline_id].state = STREAM_SENDING;
202 send_next_state_ = SEND_STATE_COMPLETE;
203 return rv;
204 }
205
206 int HttpPipelinedConnectionImpl::DoSendComplete(int result) {
207 CHECK(!deferred_request_queue_.empty());
208 const DeferredSendRequest& deferred_request = deferred_request_queue_.front();
209 CHECK_EQ(stream_info_map_[deferred_request.pipeline_id].state,
210 STREAM_SENDING);
211 request_order_.push(deferred_request.pipeline_id);
212 stream_info_map_[deferred_request.pipeline_id].state = STREAM_SENT;
213 deferred_request_queue_.pop();
214 if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) {
215 result = ERR_PIPELINE_EVICTION;
216 }
217 if (result < OK) {
218 send_next_state_ = SEND_STATE_UNUSABLE;
219 usable_ = false;
220 }
221 if (send_user_callback_) {
222 MessageLoop::current()->PostTask(
223 FROM_HERE,
224 method_factory_.NewRunnableMethod(
225 &HttpPipelinedConnectionImpl::FireUserCallback,
226 send_user_callback_,
227 result));
228 send_user_callback_ = NULL;
229 }
230 if (result < OK) {
231 return result;
232 }
233 if (deferred_request_queue_.empty()) {
234 send_next_state_ = SEND_STATE_NONE;
235 return OK;
236 }
237 send_next_state_ = SEND_STATE_NEXT_REQUEST;
238 return OK;
239 }
240
241 int HttpPipelinedConnectionImpl::DoEvictPendingSendRequests(int result) {
242 send_next_state_ = SEND_STATE_NONE;
243 while (!deferred_request_queue_.empty()) {
244 const DeferredSendRequest& evicted_send = deferred_request_queue_.front();
245 if (stream_info_map_[evicted_send.pipeline_id].state != STREAM_CLOSED) {
246 evicted_send.callback->Run(ERR_PIPELINE_EVICTION);
247 }
248 deferred_request_queue_.pop();
249 }
250 return result;
251 }
252
253 int HttpPipelinedConnectionImpl::ReadResponseHeaders(
254 int pipeline_id,
255 OldCompletionCallback* callback) {
256 CHECK(ContainsKey(stream_info_map_, pipeline_id));
257 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_SENT);
258 CHECK(!stream_info_map_[pipeline_id].read_headers_callback);
259 if (!usable_) {
260 return ERR_PIPELINE_EVICTION;
261 }
262 stream_info_map_[pipeline_id].state = STREAM_READ_PENDING;
263 stream_info_map_[pipeline_id].read_headers_callback = callback;
264 if (read_next_state_ == READ_STATE_NONE) {
265 read_next_state_ = READ_STATE_NEXT_HEADERS;
266 return DoReadHeadersLoop(OK);
267 } else {
268 return ERR_IO_PENDING;
269 }
270 }
271
272 int HttpPipelinedConnectionImpl::DoReadHeadersLoop(int result) {
273 int rv = result;
274 do {
275 ReadHeadersState state = read_next_state_;
276 read_next_state_ = READ_STATE_NONE;
277 switch (state) {
278 case READ_STATE_NEXT_HEADERS:
279 rv = DoReadNextHeaders(rv);
280 break;
281 case READ_STATE_COMPLETE:
282 rv = DoReadHeadersComplete(rv);
283 break;
284 case READ_STATE_WAITING_FOR_CLOSE:
285 rv = DoReadWaitingForClose(rv);
286 return rv;
287 case READ_STATE_STREAM_CLOSED:
288 rv = DoReadStreamClosed();
289 break;
290 case READ_STATE_UNUSABLE:
291 rv = DoEvictPendingReadHeaders(rv);
292 break;
293 case READ_STATE_NONE:
294 break;
295 default:
296 NOTREACHED() << "bad read state";
297 rv = ERR_FAILED;
298 break;
299 }
300 } while (rv != ERR_IO_PENDING && read_next_state_ != READ_STATE_NONE);
301 return rv;
302 }
303
304 void HttpPipelinedConnectionImpl::OnReadIOCallback(int result) {
305 CHECK(read_user_callback_);
306 DoReadHeadersLoop(result);
307 }
308
309 int HttpPipelinedConnectionImpl::DoReadNextHeaders(int result) {
310 CHECK(!request_order_.empty());
311 int pipeline_id = request_order_.front();
312 CHECK(ContainsKey(stream_info_map_, pipeline_id));
313 if (stream_info_map_[pipeline_id].state == STREAM_CLOSED) {
314 // Since nobody will read whatever data is on the pipeline associated with
315 // this closed request, we must shut down the rest of the pipeline.
316 read_next_state_ = READ_STATE_UNUSABLE;
317 return OK;
318 }
319 if (stream_info_map_[pipeline_id].read_headers_callback == NULL) {
320 return ERR_IO_PENDING;
321 }
322 CHECK(stream_info_map_[pipeline_id].parser.get());
323
324 if (result == ERR_IO_PENDING) {
325 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_ACTIVE);
326 } else {
327 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_READ_PENDING);
328 stream_info_map_[pipeline_id].state = STREAM_ACTIVE;
329 }
330
331 int rv = stream_info_map_[pipeline_id].parser->ReadResponseHeaders(
332 &read_io_callback_);
333 if (rv == ERR_IO_PENDING) {
334 read_next_state_ = READ_STATE_COMPLETE;
335 read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback;
336 } else if (rv < OK) {
337 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
338 if (rv == ERR_SOCKET_NOT_CONNECTED && completed_one_request_)
339 rv = ERR_PIPELINE_EVICTION;
340 } else {
341 CHECK_LE(OK, rv);
342 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
343 }
344
345 // |result| == ERR_IO_PENDING means this function was *not* called on the same
346 // stack as ReadResponseHeaders(). That means we returned ERR_IO_PENDING to
347 // ReadResponseHeaders() earlier and now need to invoke its callback.
348 if (rv != ERR_IO_PENDING && result == ERR_IO_PENDING) {
349 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
350 read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback;
351 MessageLoop::current()->PostTask(
352 FROM_HERE,
353 method_factory_.NewRunnableMethod(
354 &HttpPipelinedConnectionImpl::FireUserCallback,
355 read_user_callback_,
356 rv));
357 }
358 return rv;
359 }
360
361 int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) {
362 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
363 if (read_user_callback_) {
364 MessageLoop::current()->PostTask(
365 FROM_HERE,
366 method_factory_.NewRunnableMethod(
367 &HttpPipelinedConnectionImpl::FireUserCallback,
368 read_user_callback_,
369 result));
370 read_user_callback_ = NULL;
371 }
372 return result;
373 }
374
375 int HttpPipelinedConnectionImpl::DoReadWaitingForClose(int result) {
376 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
377 return result;
378 }
379
380 int HttpPipelinedConnectionImpl::DoReadStreamClosed() {
381 CHECK(!request_order_.empty());
382 int pipeline_id = request_order_.front();
383 CHECK(ContainsKey(stream_info_map_, pipeline_id));
384 CHECK_EQ(stream_info_map_[pipeline_id].state, STREAM_CLOSED);
385 CHECK(stream_info_map_[pipeline_id].read_headers_callback);
386 stream_info_map_[pipeline_id].read_headers_callback = NULL;
387 request_order_.pop();
388 if (!usable_) {
389 read_next_state_ = READ_STATE_UNUSABLE;
390 return OK;
391 } else {
392 completed_one_request_ = true;
393 if (!request_order_.empty()) {
394 int next_pipeline_id = request_order_.front();
395 CHECK(ContainsKey(stream_info_map_, next_pipeline_id));
396 if (stream_info_map_[next_pipeline_id].read_headers_callback) {
397 stream_info_map_[next_pipeline_id].state = STREAM_ACTIVE;
398 read_next_state_ = READ_STATE_NEXT_HEADERS;
399 MessageLoop::current()->PostTask(
400 FROM_HERE,
401 method_factory_.NewRunnableMethod(
402 &HttpPipelinedConnectionImpl::DoReadHeadersLoop,
403 ERR_IO_PENDING));
404 return ERR_IO_PENDING; // Wait for the task to fire.
405 }
406 }
407 read_next_state_ = READ_STATE_NONE;
408 return OK;
409 }
410 }
411
412 int HttpPipelinedConnectionImpl::DoEvictPendingReadHeaders(int result) {
413 while (!request_order_.empty()) {
414 int evicted_id = request_order_.front();
415 request_order_.pop();
416 if (!ContainsKey(stream_info_map_, evicted_id) ||
417 (stream_info_map_[evicted_id].read_headers_callback == NULL)) {
418 continue;
419 }
420 if (stream_info_map_[evicted_id].state != STREAM_CLOSED) {
421 MessageLoop::current()->PostTask(
422 FROM_HERE,
423 method_factory_.NewRunnableMethod(
424 &HttpPipelinedConnectionImpl::FireUserCallback,
425 stream_info_map_[evicted_id].read_headers_callback,
426 ERR_PIPELINE_EVICTION));
427 }
428 stream_info_map_[evicted_id].read_headers_callback = NULL;
429 }
430 read_next_state_ = READ_STATE_NONE;
431 return result;
432 }
433
434 void HttpPipelinedConnectionImpl::Close(int pipeline_id,
435 bool not_reusable) {
436 CHECK(ContainsKey(stream_info_map_, pipeline_id));
437 switch (stream_info_map_[pipeline_id].state) {
438 case STREAM_CREATED:
439 stream_info_map_[pipeline_id].state = STREAM_UNUSED;
440 break;
441
442 case STREAM_BOUND:
443 stream_info_map_[pipeline_id].state = STREAM_CLOSED;
444 break;
445
446 case STREAM_SENDING:
447 usable_ = false;
448 stream_info_map_[pipeline_id].state = STREAM_CLOSED;
449 send_user_callback_ = NULL;
450 send_next_state_ = SEND_STATE_UNUSABLE;
451 DoSendRequestLoop(OK);
452 break;
453
454 case STREAM_SENT:
455 case STREAM_READ_PENDING:
456 usable_ = false;
457 stream_info_map_[pipeline_id].state = STREAM_CLOSED;
458 stream_info_map_[pipeline_id].read_headers_callback = NULL;
459 if (read_next_state_ == READ_STATE_NONE) {
460 read_next_state_ = READ_STATE_UNUSABLE;
461 DoReadHeadersLoop(OK);
462 }
463 break;
464
465 case STREAM_ACTIVE:
466 stream_info_map_[pipeline_id].state = STREAM_CLOSED;
467 if (not_reusable) {
468 usable_ = false;
469 }
470 read_next_state_ = READ_STATE_STREAM_CLOSED;
471 read_user_callback_ = NULL;
472 DoReadHeadersLoop(OK);
473 break;
474
475 case STREAM_CLOSED:
476 case STREAM_UNUSED:
477 // TODO(simonjam): Why is Close() sometimes called twice?
478 break;
479
480 default:
481 NOTREACHED();
482 break;
483 }
484 }
485
486 int HttpPipelinedConnectionImpl::ReadResponseBody(
487 int pipeline_id,
488 IOBuffer* buf,
489 int buf_len,
490 OldCompletionCallback* callback) {
491 CHECK(ContainsKey(stream_info_map_, pipeline_id));
492 CHECK(!request_order_.empty());
493 CHECK_EQ(pipeline_id, request_order_.front());
494 CHECK(stream_info_map_[pipeline_id].parser.get());
495 return stream_info_map_[pipeline_id].parser->ReadResponseBody(
496 buf, buf_len, callback);
497 }
498
499 uint64 HttpPipelinedConnectionImpl::GetUploadProgress(int pipeline_id) const {
500 CHECK(ContainsKey(stream_info_map_, pipeline_id));
501 CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
502 return stream_info_map_.find(pipeline_id)->second.parser->GetUploadProgress();
503 }
504
505 HttpResponseInfo* HttpPipelinedConnectionImpl::GetResponseInfo(
506 int pipeline_id) {
507 CHECK(ContainsKey(stream_info_map_, pipeline_id));
508 CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
509 return stream_info_map_.find(pipeline_id)->second.parser->GetResponseInfo();
510 }
511
512 bool HttpPipelinedConnectionImpl::IsResponseBodyComplete(
513 int pipeline_id) const {
514 CHECK(ContainsKey(stream_info_map_, pipeline_id));
515 CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
516 return stream_info_map_.find(pipeline_id)->second.parser->
517 IsResponseBodyComplete();
518 }
519
520 bool HttpPipelinedConnectionImpl::CanFindEndOfResponse(int pipeline_id) const {
521 CHECK(ContainsKey(stream_info_map_, pipeline_id));
522 CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
523 return stream_info_map_.find(pipeline_id)->second.parser->
524 CanFindEndOfResponse();
525 }
526
527 bool HttpPipelinedConnectionImpl::IsMoreDataBuffered(int pipeline_id) const {
528 CHECK(ContainsKey(stream_info_map_, pipeline_id));
529 return read_buf_->offset() != 0;
530 }
531
532 bool HttpPipelinedConnectionImpl::IsConnectionReused(int pipeline_id) const {
533 CHECK(ContainsKey(stream_info_map_, pipeline_id));
534 if (pipeline_id > 1) {
535 return true;
536 }
537 ClientSocketHandle::SocketReuseType reuse_type = connection_->reuse_type();
538 return connection_->is_reused() ||
539 reuse_type == ClientSocketHandle::UNUSED_IDLE;
540 }
541
542 void HttpPipelinedConnectionImpl::SetConnectionReused(int pipeline_id) {
543 CHECK(ContainsKey(stream_info_map_, pipeline_id));
544 connection_->set_is_reused(true);
545 }
546
547 void HttpPipelinedConnectionImpl::GetSSLInfo(int pipeline_id,
548 SSLInfo* ssl_info) {
549 CHECK(ContainsKey(stream_info_map_, pipeline_id));
550 CHECK(stream_info_map_[pipeline_id].parser.get());
551 return stream_info_map_[pipeline_id].parser->GetSSLInfo(ssl_info);
552 }
553
554 void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo(
555 int pipeline_id,
556 SSLCertRequestInfo* cert_request_info) {
557 CHECK(ContainsKey(stream_info_map_, pipeline_id));
558 CHECK(stream_info_map_[pipeline_id].parser.get());
559 return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo(
560 cert_request_info);
561 }
562
563 void HttpPipelinedConnectionImpl::FireUserCallback(
564 OldCompletionCallback* callback,
565 int result) {
566 CHECK(callback);
567 callback->Run(result);
568 }
569
570 int HttpPipelinedConnectionImpl::depth() const {
571 return stream_info_map_.size();
572 }
573
574 bool HttpPipelinedConnectionImpl::usable() const {
575 return usable_;
576 }
577
578 bool HttpPipelinedConnectionImpl::active() const {
579 return active_;
580 }
581
582 const SSLConfig& HttpPipelinedConnectionImpl::used_ssl_config() const {
583 return used_ssl_config_;
584 }
585
586 const ProxyInfo& HttpPipelinedConnectionImpl::used_proxy_info() const {
587 return used_proxy_info_;
588 }
589
590 const NetLog::Source& HttpPipelinedConnectionImpl::source() const {
591 return net_log_.source();
592 }
593
594 bool HttpPipelinedConnectionImpl::was_npn_negotiated() const {
595 return was_npn_negotiated_;
596 }
597
598 HttpPipelinedConnectionImpl::DeferredSendRequest::DeferredSendRequest() {
599 }
600
601 HttpPipelinedConnectionImpl::DeferredSendRequest::~DeferredSendRequest() {
602 }
603
604 HttpPipelinedConnectionImpl::StreamInfo::StreamInfo()
605 : read_headers_callback(NULL),
606 state(STREAM_CREATED) {
607 }
608
609 HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() {
610 }
611
612 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_pipelined_connection_impl.h ('k') | net/http/http_pipelined_connection_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698