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

Side by Side Diff: net/spdy/spdy_http_stream.cc

Issue 15936003: [SPDY] Refactor SpdyStream::Delegate (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 7 years, 6 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
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_proxy_client_socket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_http_stream.h" 5 #include "net/spdy/spdy_http_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list> 8 #include <list>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 15 matching lines...) Expand all
26 namespace net { 26 namespace net {
27 27
28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session, 28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session,
29 bool direct) 29 bool direct)
30 : weak_factory_(this), 30 : weak_factory_(this),
31 spdy_session_(spdy_session), 31 spdy_session_(spdy_session),
32 stream_closed_(false), 32 stream_closed_(false),
33 closed_stream_status_(ERR_FAILED), 33 closed_stream_status_(ERR_FAILED),
34 closed_stream_id_(0), 34 closed_stream_id_(0),
35 request_info_(NULL), 35 request_info_(NULL),
36 has_upload_data_(false),
37 response_info_(NULL), 36 response_info_(NULL),
38 response_headers_received_(false), 37 response_headers_received_(false),
39 user_buffer_len_(0), 38 user_buffer_len_(0),
40 raw_request_body_buf_size_(0), 39 request_body_buf_size_(0),
41 buffered_read_callback_pending_(false), 40 buffered_read_callback_pending_(false),
42 more_read_data_pending_(false), 41 more_read_data_pending_(false),
43 direct_(direct) {} 42 direct_(direct) {}
44 43
45 void SpdyHttpStream::InitializeWithExistingStream( 44 void SpdyHttpStream::InitializeWithExistingStream(
46 const base::WeakPtr<SpdyStream>& spdy_stream) { 45 const base::WeakPtr<SpdyStream>& spdy_stream) {
47 stream_ = spdy_stream; 46 stream_ = spdy_stream;
48 stream_->SetDelegate(this); 47 stream_->SetDelegate(this);
49 response_headers_received_ = true; 48 response_headers_received_ = true;
50 } 49 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 90 }
92 91
93 return rv; 92 return rv;
94 } 93 }
95 94
96 const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const { 95 const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const {
97 return response_info_; 96 return response_info_;
98 } 97 }
99 98
100 UploadProgress SpdyHttpStream::GetUploadProgress() const { 99 UploadProgress SpdyHttpStream::GetUploadProgress() const {
101 if (!request_info_ || !request_info_->upload_data_stream) 100 if (!HasUploadData())
102 return UploadProgress(); 101 return UploadProgress();
103 102
104 return UploadProgress(request_info_->upload_data_stream->position(), 103 return UploadProgress(request_info_->upload_data_stream->position(),
105 request_info_->upload_data_stream->size()); 104 request_info_->upload_data_stream->size());
106 } 105 }
107 106
108 int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { 107 int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
109 CHECK(!callback.is_null()); 108 CHECK(!callback.is_null());
110 if (stream_closed_) 109 if (stream_closed_)
111 return closed_stream_status_; 110 return closed_stream_status_;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 base::Time request_time = base::Time::Now(); 211 base::Time request_time = base::Time::Now();
213 CHECK(stream_.get()); 212 CHECK(stream_.get());
214 213
215 stream_->SetRequestTime(request_time); 214 stream_->SetRequestTime(request_time);
216 // This should only get called in the case of a request occurring 215 // This should only get called in the case of a request occurring
217 // during server push that has already begun but hasn't finished, 216 // during server push that has already begun but hasn't finished,
218 // so we set the response's request time to be the actual one 217 // so we set the response's request time to be the actual one
219 if (response_info_) 218 if (response_info_)
220 response_info_->request_time = request_time; 219 response_info_->request_time = request_time;
221 220
222 CHECK(!has_upload_data_); 221 CHECK(!request_body_buf_);
223 has_upload_data_ = request_info_->upload_data_stream && 222 if (HasUploadData()) {
224 (request_info_->upload_data_stream->size() ||
225 request_info_->upload_data_stream->is_chunked());
226 if (has_upload_data_) {
227 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request 223 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request
228 // body data is written with this size at a time. 224 // body data is written with this size at a time.
229 raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); 225 request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize);
230 // The request body buffer is empty at first. 226 // The request body buffer is empty at first.
231 raw_request_body_buf_size_ = 0; 227 request_body_buf_size_ = 0;
232 } 228 }
233 229
234 CHECK(!callback.is_null()); 230 CHECK(!callback.is_null());
235 CHECK(response); 231 CHECK(response);
236 232
237 // SendRequest can be called in two cases. 233 // SendRequest can be called in two cases.
238 // 234 //
239 // a) A client initiated request. In this case, |response_info_| should be 235 // a) A client initiated request. In this case, |response_info_| should be
240 // NULL to start with. 236 // NULL to start with.
241 // b) A client request which matches a response that the server has already 237 // b) A client request which matches a response that the server has already
(...skipping 25 matching lines...) Expand all
267 CreateSpdyHeadersFromHttpRequest( 263 CreateSpdyHeadersFromHttpRequest(
268 *request_info_, request_headers, 264 *request_info_, request_headers,
269 headers.get(), stream_->GetProtocolVersion(), 265 headers.get(), stream_->GetProtocolVersion(),
270 direct_); 266 direct_);
271 stream_->net_log().AddEvent( 267 stream_->net_log().AddEvent(
272 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS, 268 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS,
273 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get())); 269 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get()));
274 result = 270 result =
275 stream_->SendRequestHeaders( 271 stream_->SendRequestHeaders(
276 headers.Pass(), 272 headers.Pass(),
277 has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND); 273 HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
278 } 274 }
279 275
280 if (result == ERR_IO_PENDING) { 276 if (result == ERR_IO_PENDING) {
281 CHECK(callback_.is_null()); 277 CHECK(callback_.is_null());
282 callback_ = callback; 278 callback_ = callback;
283 } 279 }
284 return result; 280 return result;
285 } 281 }
286 282
287 void SpdyHttpStream::Cancel() { 283 void SpdyHttpStream::Cancel() {
288 callback_.Reset(); 284 callback_.Reset();
289 if (stream_) { 285 if (stream_) {
290 stream_->Cancel(); 286 stream_->Cancel();
291 DCHECK(!stream_); 287 DCHECK(!stream_);
292 } 288 }
293 } 289 }
294 290
295 void SpdyHttpStream::OnSendRequestHeadersComplete() { 291 void SpdyHttpStream::OnRequestHeadersSent() {
296 if (!callback_.is_null()) 292 if (!callback_.is_null())
297 DoCallback(OK); 293 DoCallback(OK);
294
295 if (HasUploadData())
296 ReadAndSendRequestBodyData();
298 } 297 }
299 298
300 void SpdyHttpStream::OnSendBody() { 299 int SpdyHttpStream::OnResponseHeadersReceived(const SpdyHeaderBlock& response,
301 CHECK(request_info_ && request_info_->upload_data_stream); 300 base::Time response_time,
302 if (raw_request_body_buf_size_ > 0) { 301 int status) {
303 SendRequestBodyData();
304 } else {
305 // We shouldn't be called if there's no more data to read.
306 CHECK(!request_info_->upload_data_stream->IsEOF());
307 ReadAndSendRequestBodyData();
308 }
309 }
310
311 void SpdyHttpStream::OnSendBodyComplete() {
312 // |status| is the number of bytes written to the SPDY stream.
313 CHECK(request_info_ && request_info_->upload_data_stream);
314 raw_request_body_buf_size_ = 0;
315 }
316
317 int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response,
318 base::Time response_time,
319 int status) {
320 if (!response_info_) { 302 if (!response_info_) {
321 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM); 303 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
322 push_response_info_.reset(new HttpResponseInfo); 304 push_response_info_.reset(new HttpResponseInfo);
323 response_info_ = push_response_info_.get(); 305 response_info_ = push_response_info_.get();
324 } 306 }
325 307
326 // If the response is already received, these headers are too late. 308 // If the response is already received, these headers are too late.
327 if (response_headers_received_) { 309 if (response_headers_received_) {
328 LOG(WARNING) << "SpdyHttpStream headers received after response started."; 310 LOG(WARNING) << "SpdyHttpStream headers received after response started.";
329 return OK; 311 return OK;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 if (user_buffer_) { 374 if (user_buffer_) {
393 // Handing small chunks of data to the caller creates measurable overhead. 375 // Handing small chunks of data to the caller creates measurable overhead.
394 // We buffer data in short time-spans and send a single read notification. 376 // We buffer data in short time-spans and send a single read notification.
395 ScheduleBufferedReadCallback(); 377 ScheduleBufferedReadCallback();
396 } 378 }
397 } 379 }
398 return OK; 380 return OK;
399 } 381 }
400 382
401 void SpdyHttpStream::OnDataSent() { 383 void SpdyHttpStream::OnDataSent() {
402 // For HTTP streams, no data is sent from the client while in the OPEN state, 384 request_body_buf_size_ = 0;
403 // so it is never called. 385 ReadAndSendRequestBodyData();
404 CHECK(false);
405 } 386 }
406 387
407 void SpdyHttpStream::OnClose(int status) { 388 void SpdyHttpStream::OnClose(int status) {
408 if (stream_) { 389 if (stream_) {
409 stream_closed_ = true; 390 stream_closed_ = true;
410 closed_stream_status_ = status; 391 closed_stream_status_ = status;
411 closed_stream_id_ = stream_->stream_id(); 392 closed_stream_id_ = stream_->stream_id();
412 } 393 }
413 stream_.reset(); 394 stream_.reset();
414 bool invoked_callback = false; 395 bool invoked_callback = false;
415 if (status == net::OK) { 396 if (status == net::OK) {
416 // We need to complete any pending buffered read now. 397 // We need to complete any pending buffered read now.
417 invoked_callback = DoBufferedReadCallback(); 398 invoked_callback = DoBufferedReadCallback();
418 } 399 }
419 if (!invoked_callback && !callback_.is_null()) 400 if (!invoked_callback && !callback_.is_null())
420 DoCallback(status); 401 DoCallback(status);
421 } 402 }
422 403
404 bool SpdyHttpStream::HasUploadData() const {
405 CHECK(request_info_);
406 return
407 request_info_->upload_data_stream &&
408 ((request_info_->upload_data_stream->size() > 0) ||
409 request_info_->upload_data_stream->is_chunked());
410 }
411
423 void SpdyHttpStream::OnStreamCreated( 412 void SpdyHttpStream::OnStreamCreated(
424 const CompletionCallback& callback, 413 const CompletionCallback& callback,
425 int rv) { 414 int rv) {
426 if (rv == OK) { 415 if (rv == OK) {
427 stream_ = stream_request_.ReleaseStream(); 416 stream_ = stream_request_.ReleaseStream();
428 stream_->SetDelegate(this); 417 stream_->SetDelegate(this);
429 } 418 }
430 callback.Run(rv); 419 callback.Run(rv);
431 } 420 }
432 421
433 void SpdyHttpStream::ReadAndSendRequestBodyData() { 422 void SpdyHttpStream::ReadAndSendRequestBodyData() {
434 CHECK(request_info_ && request_info_->upload_data_stream); 423 CHECK(HasUploadData());
435 CHECK_EQ(raw_request_body_buf_size_, 0); 424 CHECK_EQ(request_body_buf_size_, 0);
425
426 if (request_info_->upload_data_stream->IsEOF())
427 return;
436 428
437 // Read the data from the request body stream. 429 // Read the data from the request body stream.
438 const int rv = request_info_->upload_data_stream->Read( 430 const int rv = request_info_->upload_data_stream->Read(
439 raw_request_body_buf_, raw_request_body_buf_->size(), 431 request_body_buf_, request_body_buf_->size(),
440 base::Bind( 432 base::Bind(
441 &SpdyHttpStream::OnRequestBodyReadCompleted, 433 &SpdyHttpStream::OnRequestBodyReadCompleted,
442 weak_factory_.GetWeakPtr())); 434 weak_factory_.GetWeakPtr()));
443 435
444 if (rv != ERR_IO_PENDING) { 436 if (rv != ERR_IO_PENDING) {
445 // ERR_IO_PENDING is the only possible error. 437 // ERR_IO_PENDING is the only possible error.
446 CHECK_GE(rv, 0); 438 CHECK_GE(rv, 0);
447 OnRequestBodyReadCompleted(rv); 439 OnRequestBodyReadCompleted(rv);
448 } 440 }
449 } 441 }
450 442
451 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { 443 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) {
452 CHECK_GE(status, 0); 444 CHECK_GE(status, 0);
453 raw_request_body_buf_size_ = status; 445 request_body_buf_size_ = status;
454 SendRequestBodyData();
455 }
456
457 void SpdyHttpStream::SendRequestBodyData() {
458 const bool eof = request_info_->upload_data_stream->IsEOF(); 446 const bool eof = request_info_->upload_data_stream->IsEOF();
459 if (eof) { 447 if (eof) {
460 CHECK_GE(raw_request_body_buf_size_, 0); 448 CHECK_GE(request_body_buf_size_, 0);
461 } else { 449 } else {
462 CHECK_GT(raw_request_body_buf_size_, 0); 450 CHECK_GT(request_body_buf_size_, 0);
463 } 451 }
464 stream_->SendStreamData(raw_request_body_buf_, 452 stream_->SendData(request_body_buf_,
465 raw_request_body_buf_size_, 453 request_body_buf_size_,
466 eof ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); 454 eof ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND);
467 } 455 }
468 456
469 void SpdyHttpStream::ScheduleBufferedReadCallback() { 457 void SpdyHttpStream::ScheduleBufferedReadCallback() {
470 // If there is already a scheduled DoBufferedReadCallback, don't issue 458 // If there is already a scheduled DoBufferedReadCallback, don't issue
471 // another one. Mark that we have received more data and return. 459 // another one. Mark that we have received more data and return.
472 if (buffered_read_callback_pending_) { 460 if (buffered_read_callback_pending_) {
473 more_read_data_pending_ = true; 461 more_read_data_pending_ = true;
474 return; 462 return;
475 } 463 }
476 464
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 bool SpdyHttpStream::IsSpdyHttpStream() const { 543 bool SpdyHttpStream::IsSpdyHttpStream() const {
556 return true; 544 return true;
557 } 545 }
558 546
559 void SpdyHttpStream::Drain(HttpNetworkSession* session) { 547 void SpdyHttpStream::Drain(HttpNetworkSession* session) {
560 Close(false); 548 Close(false);
561 delete this; 549 delete this;
562 } 550 }
563 551
564 } // namespace net 552 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_proxy_client_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698