Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| 11 #include "base/bind_helpers.h" | |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 14 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 15 #include "net/base/host_port_pair.h" | 14 #include "net/base/host_port_pair.h" |
| 16 #include "net/base/net_log.h" | 15 #include "net/base/net_log.h" |
| 17 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
| 18 #include "net/base/upload_data_stream.h" | 17 #include "net/base/upload_data_stream.h" |
| 19 #include "net/http/http_request_headers.h" | 18 #include "net/http/http_request_headers.h" |
| 20 #include "net/http/http_request_info.h" | 19 #include "net/http/http_request_info.h" |
| 21 #include "net/http/http_response_info.h" | 20 #include "net/http/http_response_info.h" |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 } | 273 } |
| 275 | 274 |
| 276 void SpdyHttpStream::Cancel() { | 275 void SpdyHttpStream::Cancel() { |
| 277 callback_.Reset(); | 276 callback_.Reset(); |
| 278 if (stream_) { | 277 if (stream_) { |
| 279 stream_->Cancel(); | 278 stream_->Cancel(); |
| 280 DCHECK(!stream_); | 279 DCHECK(!stream_); |
| 281 } | 280 } |
| 282 } | 281 } |
| 283 | 282 |
| 284 void SpdyHttpStream::OnStreamCreated( | |
| 285 const CompletionCallback& callback, | |
| 286 int rv) { | |
| 287 if (rv == OK) { | |
| 288 stream_ = stream_request_.ReleaseStream(); | |
| 289 stream_->SetDelegate(this); | |
| 290 } | |
| 291 callback.Run(rv); | |
| 292 } | |
| 293 | |
| 294 int SpdyHttpStream::SendData() { | |
| 295 CHECK(request_info_ && request_info_->upload_data_stream); | |
| 296 CHECK_EQ(0, request_body_buf_->BytesRemaining()); | |
| 297 | |
| 298 // Read the data from the request body stream. | |
| 299 const int bytes_read = request_info_->upload_data_stream->Read( | |
| 300 raw_request_body_buf_, raw_request_body_buf_->size(), | |
| 301 base::Bind( | |
| 302 base::IgnoreResult(&SpdyHttpStream::OnRequestBodyReadCompleted), | |
| 303 weak_factory_.GetWeakPtr())); | |
| 304 | |
| 305 if (bytes_read == ERR_IO_PENDING) | |
| 306 return ERR_IO_PENDING; | |
| 307 // ERR_IO_PENDING is the only possible error. | |
| 308 DCHECK_GE(bytes_read, 0); | |
| 309 return OnRequestBodyReadCompleted(bytes_read); | |
| 310 } | |
| 311 | |
| 312 SpdySendStatus SpdyHttpStream::OnSendHeadersComplete() { | 283 SpdySendStatus SpdyHttpStream::OnSendHeadersComplete() { |
| 313 if (!callback_.is_null()) | 284 if (!callback_.is_null()) |
| 314 DoCallback(OK); | 285 DoCallback(OK); |
| 315 return has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND; | 286 return has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND; |
| 316 } | 287 } |
| 317 | 288 |
| 318 int SpdyHttpStream::OnSendBody() { | 289 void SpdyHttpStream::OnSendBody() { |
| 319 CHECK(request_info_ && request_info_->upload_data_stream); | 290 CHECK(request_info_ && request_info_->upload_data_stream); |
| 320 const bool eof = request_info_->upload_data_stream->IsEOF(); | |
| 321 if (request_body_buf_->BytesRemaining() > 0) { | 291 if (request_body_buf_->BytesRemaining() > 0) { |
| 322 stream_->QueueStreamData( | 292 SendRequestBodyData(); |
| 323 request_body_buf_, | 293 } else { |
| 324 request_body_buf_->BytesRemaining(), | 294 // We shouldn't be called if there's no more data to read. |
| 325 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | 295 CHECK(!request_info_->upload_data_stream->IsEOF()); |
| 326 return ERR_IO_PENDING; | 296 ReadAndSendRequestBodyData(); |
| 327 } | 297 } |
| 328 | |
| 329 // The entire body data has been sent. | |
| 330 if (eof) | |
| 331 return OK; | |
| 332 | |
| 333 return SendData(); | |
| 334 } | 298 } |
| 335 | 299 |
| 336 SpdySendStatus SpdyHttpStream::OnSendBodyComplete(size_t bytes_sent) { | 300 SpdySendStatus SpdyHttpStream::OnSendBodyComplete(size_t bytes_sent) { |
| 337 // |status| is the number of bytes written to the SPDY stream. | 301 // |status| is the number of bytes written to the SPDY stream. |
| 338 CHECK(request_info_ && request_info_->upload_data_stream); | 302 CHECK(request_info_ && request_info_->upload_data_stream); |
| 339 DCHECK_GE(static_cast<int>(bytes_sent), 0); | 303 DCHECK_GE(static_cast<int>(bytes_sent), 0); |
| 340 DCHECK_LE(static_cast<int>(bytes_sent), request_body_buf_->BytesRemaining()); | 304 DCHECK_LE(static_cast<int>(bytes_sent), request_body_buf_->BytesRemaining()); |
| 341 | 305 |
| 342 request_body_buf_->DidConsume(static_cast<int>(bytes_sent)); | 306 request_body_buf_->DidConsume(static_cast<int>(bytes_sent)); |
| 343 | 307 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 stream_.reset(); | 418 stream_.reset(); |
| 455 bool invoked_callback = false; | 419 bool invoked_callback = false; |
| 456 if (status == net::OK) { | 420 if (status == net::OK) { |
| 457 // We need to complete any pending buffered read now. | 421 // We need to complete any pending buffered read now. |
| 458 invoked_callback = DoBufferedReadCallback(); | 422 invoked_callback = DoBufferedReadCallback(); |
| 459 } | 423 } |
| 460 if (!invoked_callback && !callback_.is_null()) | 424 if (!invoked_callback && !callback_.is_null()) |
| 461 DoCallback(status); | 425 DoCallback(status); |
| 462 } | 426 } |
| 463 | 427 |
| 428 void SpdyHttpStream::OnStreamCreated( | |
| 429 const CompletionCallback& callback, | |
| 430 int rv) { | |
| 431 if (rv == OK) { | |
| 432 stream_ = stream_request_.ReleaseStream(); | |
| 433 stream_->SetDelegate(this); | |
| 434 } | |
| 435 callback.Run(rv); | |
| 436 } | |
| 437 | |
| 438 void SpdyHttpStream::ReadAndSendRequestBodyData() { | |
| 439 CHECK(request_info_ && request_info_->upload_data_stream); | |
| 440 CHECK_EQ(0, request_body_buf_->BytesRemaining()); | |
| 441 | |
| 442 // Read the data from the request body stream. | |
| 443 const int rv = request_info_->upload_data_stream->Read( | |
| 444 raw_request_body_buf_, raw_request_body_buf_->size(), | |
| 445 base::Bind( | |
| 446 &SpdyHttpStream::OnRequestBodyReadCompleted, | |
| 447 weak_factory_.GetWeakPtr())); | |
| 448 | |
| 449 if (rv != ERR_IO_PENDING) { | |
| 450 // ERR_IO_PENDING is the only possible error. | |
| 451 CHECK_GE(rv, 0); | |
| 452 OnRequestBodyReadCompleted(rv); | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { | |
| 457 CHECK_GE(status, 0); | |
| 458 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, status); | |
| 459 SendRequestBodyData(); | |
| 460 } | |
| 461 | |
| 462 void SpdyHttpStream::SendRequestBodyData() { | |
| 463 const bool eof = request_info_->upload_data_stream->IsEOF(); | |
| 464 if (eof) { | |
| 465 CHECK_GE(request_body_buf_->BytesRemaining(), 0); | |
|
Ryan Hamilton
2013/05/22 03:17:30
Alternatively:
CHECK_GE(request_body_buf_->BytesRe
akalin
2013/05/22 08:40:05
Hmm, I prefer the split-out CHECK, simply because
| |
| 466 } else { | |
| 467 CHECK_GT(request_body_buf_->BytesRemaining(), 0); | |
| 468 } | |
| 469 stream_->QueueStreamData(request_body_buf_, | |
| 470 request_body_buf_->BytesRemaining(), | |
| 471 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | |
| 472 } | |
| 473 | |
| 464 void SpdyHttpStream::ScheduleBufferedReadCallback() { | 474 void SpdyHttpStream::ScheduleBufferedReadCallback() { |
| 465 // If there is already a scheduled DoBufferedReadCallback, don't issue | 475 // If there is already a scheduled DoBufferedReadCallback, don't issue |
| 466 // another one. Mark that we have received more data and return. | 476 // another one. Mark that we have received more data and return. |
| 467 if (buffered_read_callback_pending_) { | 477 if (buffered_read_callback_pending_) { |
| 468 more_read_data_pending_ = true; | 478 more_read_data_pending_ = true; |
| 469 return; | 479 return; |
| 470 } | 480 } |
| 471 | 481 |
| 472 more_read_data_pending_ = false; | 482 more_read_data_pending_ = false; |
| 473 buffered_read_callback_pending_ = true; | 483 buffered_read_callback_pending_ = true; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 void SpdyHttpStream::DoCallback(int rv) { | 537 void SpdyHttpStream::DoCallback(int rv) { |
| 528 CHECK_NE(rv, ERR_IO_PENDING); | 538 CHECK_NE(rv, ERR_IO_PENDING); |
| 529 CHECK(!callback_.is_null()); | 539 CHECK(!callback_.is_null()); |
| 530 | 540 |
| 531 // Since Run may result in being called back, clear user_callback_ in advance. | 541 // Since Run may result in being called back, clear user_callback_ in advance. |
| 532 CompletionCallback c = callback_; | 542 CompletionCallback c = callback_; |
| 533 callback_.Reset(); | 543 callback_.Reset(); |
| 534 c.Run(rv); | 544 c.Run(rv); |
| 535 } | 545 } |
| 536 | 546 |
| 537 int SpdyHttpStream::OnRequestBodyReadCompleted(int status) { | |
| 538 DCHECK_GE(status, 0); | |
| 539 | |
| 540 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, status); | |
| 541 | |
| 542 const bool eof = request_info_->upload_data_stream->IsEOF(); | |
| 543 stream_->QueueStreamData(request_body_buf_, | |
| 544 request_body_buf_->BytesRemaining(), | |
| 545 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | |
| 546 return ERR_IO_PENDING; | |
| 547 } | |
| 548 | |
| 549 void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) { | 547 void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) { |
| 550 DCHECK(stream_); | 548 DCHECK(stream_); |
| 551 bool using_npn; | 549 bool using_npn; |
| 552 NextProto protocol_negotiated = kProtoUnknown; | 550 NextProto protocol_negotiated = kProtoUnknown; |
| 553 stream_->GetSSLInfo(ssl_info, &using_npn, &protocol_negotiated); | 551 stream_->GetSSLInfo(ssl_info, &using_npn, &protocol_negotiated); |
| 554 } | 552 } |
| 555 | 553 |
| 556 void SpdyHttpStream::GetSSLCertRequestInfo( | 554 void SpdyHttpStream::GetSSLCertRequestInfo( |
| 557 SSLCertRequestInfo* cert_request_info) { | 555 SSLCertRequestInfo* cert_request_info) { |
| 558 DCHECK(stream_); | 556 DCHECK(stream_); |
| 559 stream_->GetSSLCertRequestInfo(cert_request_info); | 557 stream_->GetSSLCertRequestInfo(cert_request_info); |
| 560 } | 558 } |
| 561 | 559 |
| 562 bool SpdyHttpStream::IsSpdyHttpStream() const { | 560 bool SpdyHttpStream::IsSpdyHttpStream() const { |
| 563 return true; | 561 return true; |
| 564 } | 562 } |
| 565 | 563 |
| 566 void SpdyHttpStream::Drain(HttpNetworkSession* session) { | 564 void SpdyHttpStream::Drain(HttpNetworkSession* session) { |
| 567 Close(false); | 565 Close(false); |
| 568 delete this; | 566 delete this; |
| 569 } | 567 } |
| 570 | 568 |
| 571 } // namespace net | 569 } // namespace net |
| OLD | NEW |