| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 return false; | 336 return false; |
| 337 size_t data_size = base_->GetDataRemaining(); | 337 size_t data_size = base_->GetDataRemaining(); |
| 338 if (SIZE_UNKNOWN == data_size) | 338 if (SIZE_UNKNOWN == data_size) |
| 339 return false; | 339 return false; |
| 340 if (size) | 340 if (size) |
| 341 *size = data_size; | 341 *size = data_size; |
| 342 return true; | 342 return true; |
| 343 } | 343 } |
| 344 | 344 |
| 345 HttpBase* Disconnect(HttpError error) { | 345 HttpBase* Disconnect(HttpError error) { |
| 346 ASSERT(NULL != base_); | 346 RTC_DCHECK(NULL != base_); |
| 347 ASSERT(NULL != base_->doc_stream_); | 347 RTC_DCHECK(NULL != base_->doc_stream_); |
| 348 HttpBase* base = base_; | 348 HttpBase* base = base_; |
| 349 base_->doc_stream_ = NULL; | 349 base_->doc_stream_ = NULL; |
| 350 base_ = NULL; | 350 base_ = NULL; |
| 351 error_ = error; | 351 error_ = error; |
| 352 return base; | 352 return base; |
| 353 } | 353 } |
| 354 | 354 |
| 355 private: | 355 private: |
| 356 HttpBase* base_; | 356 HttpBase* base_; |
| 357 HttpError error_; | 357 HttpError error_; |
| 358 }; | 358 }; |
| 359 | 359 |
| 360 ////////////////////////////////////////////////////////////////////// | 360 ////////////////////////////////////////////////////////////////////// |
| 361 // HttpBase | 361 // HttpBase |
| 362 ////////////////////////////////////////////////////////////////////// | 362 ////////////////////////////////////////////////////////////////////// |
| 363 | 363 |
| 364 HttpBase::HttpBase() : mode_(HM_NONE), data_(NULL), notify_(NULL), | 364 HttpBase::HttpBase() : mode_(HM_NONE), data_(NULL), notify_(NULL), |
| 365 http_stream_(NULL), doc_stream_(NULL) { | 365 http_stream_(NULL), doc_stream_(NULL) { |
| 366 } | 366 } |
| 367 | 367 |
| 368 HttpBase::~HttpBase() { | 368 HttpBase::~HttpBase() { |
| 369 ASSERT(HM_NONE == mode_); | 369 RTC_DCHECK(HM_NONE == mode_); |
| 370 } | 370 } |
| 371 | 371 |
| 372 bool | 372 bool |
| 373 HttpBase::isConnected() const { | 373 HttpBase::isConnected() const { |
| 374 return (http_stream_ != NULL) && (http_stream_->GetState() == SS_OPEN); | 374 return (http_stream_ != NULL) && (http_stream_->GetState() == SS_OPEN); |
| 375 } | 375 } |
| 376 | 376 |
| 377 bool | 377 bool |
| 378 HttpBase::attach(StreamInterface* stream) { | 378 HttpBase::attach(StreamInterface* stream) { |
| 379 if ((mode_ != HM_NONE) || (http_stream_ != NULL) || (stream == NULL)) { | 379 if ((mode_ != HM_NONE) || (http_stream_ != NULL) || (stream == NULL)) { |
| 380 RTC_NOTREACHED(); | 380 RTC_NOTREACHED(); |
| 381 return false; | 381 return false; |
| 382 } | 382 } |
| 383 http_stream_ = stream; | 383 http_stream_ = stream; |
| 384 http_stream_->SignalEvent.connect(this, &HttpBase::OnHttpStreamEvent); | 384 http_stream_->SignalEvent.connect(this, &HttpBase::OnHttpStreamEvent); |
| 385 mode_ = (http_stream_->GetState() == SS_OPENING) ? HM_CONNECT : HM_NONE; | 385 mode_ = (http_stream_->GetState() == SS_OPENING) ? HM_CONNECT : HM_NONE; |
| 386 return true; | 386 return true; |
| 387 } | 387 } |
| 388 | 388 |
| 389 StreamInterface* | 389 StreamInterface* |
| 390 HttpBase::detach() { | 390 HttpBase::detach() { |
| 391 ASSERT(HM_NONE == mode_); | 391 RTC_DCHECK(HM_NONE == mode_); |
| 392 if (mode_ != HM_NONE) { | 392 if (mode_ != HM_NONE) { |
| 393 return NULL; | 393 return NULL; |
| 394 } | 394 } |
| 395 StreamInterface* stream = http_stream_; | 395 StreamInterface* stream = http_stream_; |
| 396 http_stream_ = NULL; | 396 http_stream_ = NULL; |
| 397 if (stream) { | 397 if (stream) { |
| 398 stream->SignalEvent.disconnect(this); | 398 stream->SignalEvent.disconnect(this); |
| 399 } | 399 } |
| 400 return stream; | 400 return stream; |
| 401 } | 401 } |
| 402 | 402 |
| 403 void | 403 void |
| 404 HttpBase::send(HttpData* data) { | 404 HttpBase::send(HttpData* data) { |
| 405 ASSERT(HM_NONE == mode_); | 405 RTC_DCHECK(HM_NONE == mode_); |
| 406 if (mode_ != HM_NONE) { | 406 if (mode_ != HM_NONE) { |
| 407 return; | 407 return; |
| 408 } else if (!isConnected()) { | 408 } else if (!isConnected()) { |
| 409 OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); | 409 OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); |
| 410 return; | 410 return; |
| 411 } | 411 } |
| 412 | 412 |
| 413 mode_ = HM_SEND; | 413 mode_ = HM_SEND; |
| 414 data_ = data; | 414 data_ = data; |
| 415 len_ = 0; | 415 len_ = 0; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 432 if (header_ == data_->end()) { | 432 if (header_ == data_->end()) { |
| 433 // We must call this at least once, in the case where there are no headers. | 433 // We must call this at least once, in the case where there are no headers. |
| 434 queue_headers(); | 434 queue_headers(); |
| 435 } | 435 } |
| 436 | 436 |
| 437 flush_data(); | 437 flush_data(); |
| 438 } | 438 } |
| 439 | 439 |
| 440 void | 440 void |
| 441 HttpBase::recv(HttpData* data) { | 441 HttpBase::recv(HttpData* data) { |
| 442 ASSERT(HM_NONE == mode_); | 442 RTC_DCHECK(HM_NONE == mode_); |
| 443 if (mode_ != HM_NONE) { | 443 if (mode_ != HM_NONE) { |
| 444 return; | 444 return; |
| 445 } else if (!isConnected()) { | 445 } else if (!isConnected()) { |
| 446 OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); | 446 OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED); |
| 447 return; | 447 return; |
| 448 } | 448 } |
| 449 | 449 |
| 450 mode_ = HM_RECV; | 450 mode_ = HM_RECV; |
| 451 data_ = data; | 451 data_ = data; |
| 452 len_ = 0; | 452 len_ = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 } else if (error == SOCKET_EACCES) { | 490 } else if (error == SOCKET_EACCES) { |
| 491 return HE_AUTH; | 491 return HE_AUTH; |
| 492 } else if (error == SEC_E_CERT_EXPIRED) { | 492 } else if (error == SEC_E_CERT_EXPIRED) { |
| 493 return HE_CERTIFICATE_EXPIRED; | 493 return HE_CERTIFICATE_EXPIRED; |
| 494 } | 494 } |
| 495 LOG_F(LS_ERROR) << "(" << error << ")"; | 495 LOG_F(LS_ERROR) << "(" << error << ")"; |
| 496 return (HM_CONNECT == mode_) ? HE_CONNECT_FAILED : HE_SOCKET_ERROR; | 496 return (HM_CONNECT == mode_) ? HE_CONNECT_FAILED : HE_SOCKET_ERROR; |
| 497 } | 497 } |
| 498 | 498 |
| 499 bool HttpBase::DoReceiveLoop(HttpError* error) { | 499 bool HttpBase::DoReceiveLoop(HttpError* error) { |
| 500 ASSERT(HM_RECV == mode_); | 500 RTC_DCHECK(HM_RECV == mode_); |
| 501 ASSERT(NULL != error); | 501 RTC_DCHECK(NULL != error); |
| 502 | 502 |
| 503 // Do to the latency between receiving read notifications from | 503 // Do to the latency between receiving read notifications from |
| 504 // pseudotcpchannel, we rely on repeated calls to read in order to acheive | 504 // pseudotcpchannel, we rely on repeated calls to read in order to acheive |
| 505 // ideal throughput. The number of reads is limited to prevent starving | 505 // ideal throughput. The number of reads is limited to prevent starving |
| 506 // the caller. | 506 // the caller. |
| 507 | 507 |
| 508 size_t loop_count = 0; | 508 size_t loop_count = 0; |
| 509 const size_t kMaxReadCount = 20; | 509 const size_t kMaxReadCount = 20; |
| 510 bool process_requires_more_data = false; | 510 bool process_requires_more_data = false; |
| 511 do { | 511 do { |
| 512 // The most frequent use of this function is response to new data available | 512 // The most frequent use of this function is response to new data available |
| 513 // on http_stream_. Therefore, we optimize by attempting to read from the | 513 // on http_stream_. Therefore, we optimize by attempting to read from the |
| 514 // network first (as opposed to processing existing data first). | 514 // network first (as opposed to processing existing data first). |
| 515 | 515 |
| 516 if (len_ < sizeof(buffer_)) { | 516 if (len_ < sizeof(buffer_)) { |
| 517 // Attempt to buffer more data. | 517 // Attempt to buffer more data. |
| 518 size_t read; | 518 size_t read; |
| 519 int read_error; | 519 int read_error; |
| 520 StreamResult read_result = http_stream_->Read(buffer_ + len_, | 520 StreamResult read_result = http_stream_->Read(buffer_ + len_, |
| 521 sizeof(buffer_) - len_, | 521 sizeof(buffer_) - len_, |
| 522 &read, &read_error); | 522 &read, &read_error); |
| 523 switch (read_result) { | 523 switch (read_result) { |
| 524 case SR_SUCCESS: | 524 case SR_SUCCESS: |
| 525 ASSERT(len_ + read <= sizeof(buffer_)); | 525 RTC_DCHECK(len_ + read <= sizeof(buffer_)); |
| 526 len_ += read; | 526 len_ += read; |
| 527 break; | 527 break; |
| 528 case SR_BLOCK: | 528 case SR_BLOCK: |
| 529 if (process_requires_more_data) { | 529 if (process_requires_more_data) { |
| 530 // We're can't make progress until more data is available. | 530 // We're can't make progress until more data is available. |
| 531 return false; | 531 return false; |
| 532 } | 532 } |
| 533 // Attempt to process the data already in our buffer. | 533 // Attempt to process the data already in our buffer. |
| 534 break; | 534 break; |
| 535 case SR_EOS: | 535 case SR_EOS: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 550 | 550 |
| 551 // Process data in our buffer. Process is not guaranteed to process all | 551 // Process data in our buffer. Process is not guaranteed to process all |
| 552 // the buffered data. In particular, it will wait until a complete | 552 // the buffered data. In particular, it will wait until a complete |
| 553 // protocol element (such as http header, or chunk size) is available, | 553 // protocol element (such as http header, or chunk size) is available, |
| 554 // before processing it in its entirety. Also, it is valid and sometimes | 554 // before processing it in its entirety. Also, it is valid and sometimes |
| 555 // necessary to call Process with an empty buffer, since the state machine | 555 // necessary to call Process with an empty buffer, since the state machine |
| 556 // may have interrupted state transitions to complete. | 556 // may have interrupted state transitions to complete. |
| 557 size_t processed; | 557 size_t processed; |
| 558 ProcessResult process_result = Process(buffer_, len_, &processed, | 558 ProcessResult process_result = Process(buffer_, len_, &processed, |
| 559 error); | 559 error); |
| 560 ASSERT(processed <= len_); | 560 RTC_DCHECK(processed <= len_); |
| 561 len_ -= processed; | 561 len_ -= processed; |
| 562 memmove(buffer_, buffer_ + processed, len_); | 562 memmove(buffer_, buffer_ + processed, len_); |
| 563 switch (process_result) { | 563 switch (process_result) { |
| 564 case PR_CONTINUE: | 564 case PR_CONTINUE: |
| 565 // We need more data to make progress. | 565 // We need more data to make progress. |
| 566 process_requires_more_data = true; | 566 process_requires_more_data = true; |
| 567 break; | 567 break; |
| 568 case PR_BLOCK: | 568 case PR_BLOCK: |
| 569 // We're stalled on writing the processed data. | 569 // We're stalled on writing the processed data. |
| 570 return false; | 570 return false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 581 void | 581 void |
| 582 HttpBase::read_and_process_data() { | 582 HttpBase::read_and_process_data() { |
| 583 HttpError error; | 583 HttpError error; |
| 584 if (DoReceiveLoop(&error)) { | 584 if (DoReceiveLoop(&error)) { |
| 585 complete(error); | 585 complete(error); |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 | 588 |
| 589 void | 589 void |
| 590 HttpBase::flush_data() { | 590 HttpBase::flush_data() { |
| 591 ASSERT(HM_SEND == mode_); | 591 RTC_DCHECK(HM_SEND == mode_); |
| 592 | 592 |
| 593 // When send_required is true, no more buffering can occur without a network | 593 // When send_required is true, no more buffering can occur without a network |
| 594 // write. | 594 // write. |
| 595 bool send_required = (len_ >= sizeof(buffer_)); | 595 bool send_required = (len_ >= sizeof(buffer_)); |
| 596 | 596 |
| 597 while (true) { | 597 while (true) { |
| 598 ASSERT(len_ <= sizeof(buffer_)); | 598 RTC_DCHECK(len_ <= sizeof(buffer_)); |
| 599 | 599 |
| 600 // HTTP is inherently sensitive to round trip latency, since a frequent use | 600 // HTTP is inherently sensitive to round trip latency, since a frequent use |
| 601 // case is for small requests and responses to be sent back and forth, and | 601 // case is for small requests and responses to be sent back and forth, and |
| 602 // the lack of pipelining forces a single request to take a minimum of the | 602 // the lack of pipelining forces a single request to take a minimum of the |
| 603 // round trip time. As a result, it is to our benefit to pack as much data | 603 // round trip time. As a result, it is to our benefit to pack as much data |
| 604 // into each packet as possible. Thus, we defer network writes until we've | 604 // into each packet as possible. Thus, we defer network writes until we've |
| 605 // buffered as much data as possible. | 605 // buffered as much data as possible. |
| 606 | 606 |
| 607 if (!send_required && (header_ != data_->end())) { | 607 if (!send_required && (header_ != data_->end())) { |
| 608 // First, attempt to queue more header data. | 608 // First, attempt to queue more header data. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 626 | 626 |
| 627 if (reserve >= sizeof(buffer_)) { | 627 if (reserve >= sizeof(buffer_)) { |
| 628 send_required = true; | 628 send_required = true; |
| 629 } else { | 629 } else { |
| 630 size_t read; | 630 size_t read; |
| 631 int error; | 631 int error; |
| 632 StreamResult result = data_->document->Read(buffer_ + offset, | 632 StreamResult result = data_->document->Read(buffer_ + offset, |
| 633 sizeof(buffer_) - reserve, | 633 sizeof(buffer_) - reserve, |
| 634 &read, &error); | 634 &read, &error); |
| 635 if (result == SR_SUCCESS) { | 635 if (result == SR_SUCCESS) { |
| 636 ASSERT(reserve + read <= sizeof(buffer_)); | 636 RTC_DCHECK(reserve + read <= sizeof(buffer_)); |
| 637 if (chunk_data_) { | 637 if (chunk_data_) { |
| 638 // Prepend the chunk length in hex. | 638 // Prepend the chunk length in hex. |
| 639 // Note: sprintfn appends a null terminator, which is why we can't | 639 // Note: sprintfn appends a null terminator, which is why we can't |
| 640 // combine it with the line terminator. | 640 // combine it with the line terminator. |
| 641 sprintfn(buffer_ + len_, kChunkDigits + 1, "%.*x", | 641 sprintfn(buffer_ + len_, kChunkDigits + 1, "%.*x", |
| 642 kChunkDigits, read); | 642 kChunkDigits, read); |
| 643 // Add line terminator to the chunk length. | 643 // Add line terminator to the chunk length. |
| 644 memcpy(buffer_ + len_ + kChunkDigits, "\r\n", 2); | 644 memcpy(buffer_ + len_ + kChunkDigits, "\r\n", 2); |
| 645 // Add line terminator to the end of the chunk. | 645 // Add line terminator to the end of the chunk. |
| 646 memcpy(buffer_ + offset + read, "\r\n", 2); | 646 memcpy(buffer_ + offset + read, "\r\n", 2); |
| 647 } | 647 } |
| 648 len_ = reserve + read; | 648 len_ = reserve + read; |
| 649 } else if (result == SR_BLOCK) { | 649 } else if (result == SR_BLOCK) { |
| 650 // Nothing to do but flush data to the network. | 650 // Nothing to do but flush data to the network. |
| 651 send_required = true; | 651 send_required = true; |
| 652 } else if (result == SR_EOS) { | 652 } else if (result == SR_EOS) { |
| 653 if (chunk_data_) { | 653 if (chunk_data_) { |
| 654 // Append the empty chunk and empty trailers, then turn off | 654 // Append the empty chunk and empty trailers, then turn off |
| 655 // chunking. | 655 // chunking. |
| 656 ASSERT(len_ + 5 <= sizeof(buffer_)); | 656 RTC_DCHECK(len_ + 5 <= sizeof(buffer_)); |
| 657 memcpy(buffer_ + len_, "0\r\n\r\n", 5); | 657 memcpy(buffer_ + len_, "0\r\n\r\n", 5); |
| 658 len_ += 5; | 658 len_ += 5; |
| 659 chunk_data_ = false; | 659 chunk_data_ = false; |
| 660 } else if (0 == len_) { | 660 } else if (0 == len_) { |
| 661 // No more data to read, and no more data to write. | 661 // No more data to read, and no more data to write. |
| 662 do_complete(); | 662 do_complete(); |
| 663 return; | 663 return; |
| 664 } | 664 } |
| 665 // Although we are done reading data, there is still data which needs | 665 // Although we are done reading data, there is still data which needs |
| 666 // to be flushed to the network. | 666 // to be flushed to the network. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 679 // If there is no source document, that means we're done. | 679 // If there is no source document, that means we're done. |
| 680 do_complete(); | 680 do_complete(); |
| 681 } | 681 } |
| 682 return; | 682 return; |
| 683 } | 683 } |
| 684 | 684 |
| 685 size_t written; | 685 size_t written; |
| 686 int error; | 686 int error; |
| 687 StreamResult result = http_stream_->Write(buffer_, len_, &written, &error); | 687 StreamResult result = http_stream_->Write(buffer_, len_, &written, &error); |
| 688 if (result == SR_SUCCESS) { | 688 if (result == SR_SUCCESS) { |
| 689 ASSERT(written <= len_); | 689 RTC_DCHECK(written <= len_); |
| 690 len_ -= written; | 690 len_ -= written; |
| 691 memmove(buffer_, buffer_ + written, len_); | 691 memmove(buffer_, buffer_ + written, len_); |
| 692 send_required = false; | 692 send_required = false; |
| 693 } else if (result == SR_BLOCK) { | 693 } else if (result == SR_BLOCK) { |
| 694 if (send_required) { | 694 if (send_required) { |
| 695 // Nothing more we can do until network is writeable. | 695 // Nothing more we can do until network is writeable. |
| 696 return; | 696 return; |
| 697 } | 697 } |
| 698 } else { | 698 } else { |
| 699 ASSERT(result == SR_ERROR); | 699 RTC_DCHECK(result == SR_ERROR); |
| 700 LOG_F(LS_ERROR) << "error"; | 700 LOG_F(LS_ERROR) << "error"; |
| 701 OnHttpStreamEvent(http_stream_, SE_CLOSE, error); | 701 OnHttpStreamEvent(http_stream_, SE_CLOSE, error); |
| 702 return; | 702 return; |
| 703 } | 703 } |
| 704 } | 704 } |
| 705 | 705 |
| 706 RTC_NOTREACHED(); | 706 RTC_NOTREACHED(); |
| 707 } | 707 } |
| 708 | 708 |
| 709 bool | 709 bool |
| 710 HttpBase::queue_headers() { | 710 HttpBase::queue_headers() { |
| 711 ASSERT(HM_SEND == mode_); | 711 RTC_DCHECK(HM_SEND == mode_); |
| 712 while (header_ != data_->end()) { | 712 while (header_ != data_->end()) { |
| 713 size_t len = sprintfn(buffer_ + len_, sizeof(buffer_) - len_, | 713 size_t len = sprintfn(buffer_ + len_, sizeof(buffer_) - len_, |
| 714 "%.*s: %.*s\r\n", | 714 "%.*s: %.*s\r\n", |
| 715 header_->first.size(), header_->first.data(), | 715 header_->first.size(), header_->first.data(), |
| 716 header_->second.size(), header_->second.data()); | 716 header_->second.size(), header_->second.data()); |
| 717 if (len_ + len < sizeof(buffer_) - 3) { | 717 if (len_ + len < sizeof(buffer_) - 3) { |
| 718 len_ += len; | 718 len_ += len; |
| 719 ++header_; | 719 ++header_; |
| 720 } else if (len_ == 0) { | 720 } else if (len_ == 0) { |
| 721 LOG(WARNING) << "discarding header that is too long: " << header_->first; | 721 LOG(WARNING) << "discarding header that is too long: " << header_->first; |
| 722 ++header_; | 722 ++header_; |
| 723 } else { | 723 } else { |
| 724 // Not enough room for the next header, write to network first. | 724 // Not enough room for the next header, write to network first. |
| 725 return true; | 725 return true; |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 // End of headers | 728 // End of headers |
| 729 len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n"); | 729 len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n"); |
| 730 return false; | 730 return false; |
| 731 } | 731 } |
| 732 | 732 |
| 733 void | 733 void |
| 734 HttpBase::do_complete(HttpError err) { | 734 HttpBase::do_complete(HttpError err) { |
| 735 ASSERT(mode_ != HM_NONE); | 735 RTC_DCHECK(mode_ != HM_NONE); |
| 736 HttpMode mode = mode_; | 736 HttpMode mode = mode_; |
| 737 mode_ = HM_NONE; | 737 mode_ = HM_NONE; |
| 738 if (data_ && data_->document) { | 738 if (data_ && data_->document) { |
| 739 data_->document->SignalEvent.disconnect(this); | 739 data_->document->SignalEvent.disconnect(this); |
| 740 } | 740 } |
| 741 data_ = NULL; | 741 data_ = NULL; |
| 742 if ((HM_RECV == mode) && doc_stream_) { | 742 if ((HM_RECV == mode) && doc_stream_) { |
| 743 ASSERT(HE_NONE != err); // We should have Disconnected doc_stream_ already. | 743 RTC_DCHECK(HE_NONE != |
| 744 err); // We should have Disconnected doc_stream_ already. |
| 744 DocumentStream* ds = doc_stream_; | 745 DocumentStream* ds = doc_stream_; |
| 745 ds->Disconnect(err); | 746 ds->Disconnect(err); |
| 746 ds->SignalEvent(ds, SE_CLOSE, err); | 747 ds->SignalEvent(ds, SE_CLOSE, err); |
| 747 } | 748 } |
| 748 if (notify_) { | 749 if (notify_) { |
| 749 notify_->onHttpComplete(mode, err); | 750 notify_->onHttpComplete(mode, err); |
| 750 } | 751 } |
| 751 } | 752 } |
| 752 | 753 |
| 753 // | 754 // |
| 754 // Stream Signals | 755 // Stream Signals |
| 755 // | 756 // |
| 756 | 757 |
| 757 void | 758 void |
| 758 HttpBase::OnHttpStreamEvent(StreamInterface* stream, int events, int error) { | 759 HttpBase::OnHttpStreamEvent(StreamInterface* stream, int events, int error) { |
| 759 ASSERT(stream == http_stream_); | 760 RTC_DCHECK(stream == http_stream_); |
| 760 if ((events & SE_OPEN) && (mode_ == HM_CONNECT)) { | 761 if ((events & SE_OPEN) && (mode_ == HM_CONNECT)) { |
| 761 do_complete(); | 762 do_complete(); |
| 762 return; | 763 return; |
| 763 } | 764 } |
| 764 | 765 |
| 765 if ((events & SE_WRITE) && (mode_ == HM_SEND)) { | 766 if ((events & SE_WRITE) && (mode_ == HM_SEND)) { |
| 766 flush_data(); | 767 flush_data(); |
| 767 return; | 768 return; |
| 768 } | 769 } |
| 769 | 770 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 784 complete(http_error); | 785 complete(http_error); |
| 785 } else if (mode_ != HM_NONE) { | 786 } else if (mode_ != HM_NONE) { |
| 786 do_complete(http_error); | 787 do_complete(http_error); |
| 787 } else if (notify_) { | 788 } else if (notify_) { |
| 788 notify_->onHttpClosed(http_error); | 789 notify_->onHttpClosed(http_error); |
| 789 } | 790 } |
| 790 } | 791 } |
| 791 | 792 |
| 792 void | 793 void |
| 793 HttpBase::OnDocumentEvent(StreamInterface* stream, int events, int error) { | 794 HttpBase::OnDocumentEvent(StreamInterface* stream, int events, int error) { |
| 794 ASSERT(stream == data_->document.get()); | 795 RTC_DCHECK(stream == data_->document.get()); |
| 795 if ((events & SE_WRITE) && (mode_ == HM_RECV)) { | 796 if ((events & SE_WRITE) && (mode_ == HM_RECV)) { |
| 796 read_and_process_data(); | 797 read_and_process_data(); |
| 797 return; | 798 return; |
| 798 } | 799 } |
| 799 | 800 |
| 800 if ((events & SE_READ) && (mode_ == HM_SEND)) { | 801 if ((events & SE_READ) && (mode_ == HM_SEND)) { |
| 801 flush_data(); | 802 flush_data(); |
| 802 return; | 803 return; |
| 803 } | 804 } |
| 804 | 805 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 827 return PR_CONTINUE; | 828 return PR_CONTINUE; |
| 828 } | 829 } |
| 829 | 830 |
| 830 HttpParser::ProcessResult | 831 HttpParser::ProcessResult |
| 831 HttpBase::ProcessHeaderComplete(bool chunked, size_t& data_size, | 832 HttpBase::ProcessHeaderComplete(bool chunked, size_t& data_size, |
| 832 HttpError* error) { | 833 HttpError* error) { |
| 833 StreamInterface* old_docstream = doc_stream_; | 834 StreamInterface* old_docstream = doc_stream_; |
| 834 if (notify_) { | 835 if (notify_) { |
| 835 *error = notify_->onHttpHeaderComplete(chunked, data_size); | 836 *error = notify_->onHttpHeaderComplete(chunked, data_size); |
| 836 // The request must not be aborted as a result of this callback. | 837 // The request must not be aborted as a result of this callback. |
| 837 ASSERT(NULL != data_); | 838 RTC_DCHECK(NULL != data_); |
| 838 } | 839 } |
| 839 if ((HE_NONE == *error) && data_->document) { | 840 if ((HE_NONE == *error) && data_->document) { |
| 840 data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent); | 841 data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent); |
| 841 } | 842 } |
| 842 if (HE_NONE != *error) { | 843 if (HE_NONE != *error) { |
| 843 return PR_COMPLETE; | 844 return PR_COMPLETE; |
| 844 } | 845 } |
| 845 if (old_docstream != doc_stream_) { | 846 if (old_docstream != doc_stream_) { |
| 846 // Break out of Process loop, since our I/O model just changed. | 847 // Break out of Process loop, since our I/O model just changed. |
| 847 return PR_BLOCK; | 848 return PR_BLOCK; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 874 } | 875 } |
| 875 } | 876 } |
| 876 | 877 |
| 877 void | 878 void |
| 878 HttpBase::OnComplete(HttpError err) { | 879 HttpBase::OnComplete(HttpError err) { |
| 879 LOG_F(LS_VERBOSE); | 880 LOG_F(LS_VERBOSE); |
| 880 do_complete(err); | 881 do_complete(err); |
| 881 } | 882 } |
| 882 | 883 |
| 883 } // namespace rtc | 884 } // namespace rtc |
| OLD | NEW |