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 19 matching lines...) Expand all Loading... |
30 // Helpers | 30 // Helpers |
31 ////////////////////////////////////////////////////////////////////// | 31 ////////////////////////////////////////////////////////////////////// |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 const size_t kCacheHeader = 0; | 35 const size_t kCacheHeader = 0; |
36 const size_t kCacheBody = 1; | 36 const size_t kCacheBody = 1; |
37 | 37 |
38 // Convert decimal string to integer | 38 // Convert decimal string to integer |
39 bool HttpStringToUInt(const std::string& str, size_t* val) { | 39 bool HttpStringToUInt(const std::string& str, size_t* val) { |
40 ASSERT(NULL != val); | 40 RTC_DCHECK(NULL != val); |
41 char* eos = NULL; | 41 char* eos = NULL; |
42 *val = strtoul(str.c_str(), &eos, 10); | 42 *val = strtoul(str.c_str(), &eos, 10); |
43 return (*eos == '\0'); | 43 return (*eos == '\0'); |
44 } | 44 } |
45 | 45 |
46 bool HttpShouldCache(const HttpTransaction& t) { | 46 bool HttpShouldCache(const HttpTransaction& t) { |
47 bool verb_allows_cache = (t.request.verb == HV_GET) | 47 bool verb_allows_cache = (t.request.verb == HV_GET) |
48 || (t.request.verb == HV_HEAD); | 48 || (t.request.verb == HV_HEAD); |
49 bool is_range_response = t.response.hasHeader(HH_CONTENT_RANGE, NULL); | 49 bool is_range_response = t.response.hasHeader(HH_CONTENT_RANGE, NULL); |
50 bool has_expires = t.response.hasHeader(HH_EXPIRES, NULL); | 50 bool has_expires = t.response.hasHeader(HH_EXPIRES, NULL); |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 return base_.GetDocumentStream(); | 334 return base_.GetDocumentStream(); |
335 } | 335 } |
336 | 336 |
337 void HttpClient::start() { | 337 void HttpClient::start() { |
338 if (base_.mode() != HM_NONE) { | 338 if (base_.mode() != HM_NONE) { |
339 // call reset() to abort an in-progress request | 339 // call reset() to abort an in-progress request |
340 RTC_NOTREACHED(); | 340 RTC_NOTREACHED(); |
341 return; | 341 return; |
342 } | 342 } |
343 | 343 |
344 ASSERT(!IsCacheActive()); | 344 RTC_DCHECK(!IsCacheActive()); |
345 | 345 |
346 if (request().hasHeader(HH_TRANSFER_ENCODING, NULL)) { | 346 if (request().hasHeader(HH_TRANSFER_ENCODING, NULL)) { |
347 // Exact size must be known on the client. Instead of using chunked | 347 // Exact size must be known on the client. Instead of using chunked |
348 // encoding, wrap data with auto-caching file or memory stream. | 348 // encoding, wrap data with auto-caching file or memory stream. |
349 RTC_NOTREACHED(); | 349 RTC_NOTREACHED(); |
350 return; | 350 return; |
351 } | 351 } |
352 | 352 |
353 attempt_ = 0; | 353 attempt_ = 0; |
354 | 354 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 } | 396 } |
397 | 397 |
398 void HttpClient::connect() { | 398 void HttpClient::connect() { |
399 int stream_err; | 399 int stream_err; |
400 if (server_.IsUnresolvedIP()) { | 400 if (server_.IsUnresolvedIP()) { |
401 StartDNSLookup(); | 401 StartDNSLookup(); |
402 return; | 402 return; |
403 } | 403 } |
404 StreamInterface* stream = pool_->RequestConnectedStream(server_, &stream_err); | 404 StreamInterface* stream = pool_->RequestConnectedStream(server_, &stream_err); |
405 if (stream == NULL) { | 405 if (stream == NULL) { |
406 ASSERT(0 != stream_err); | 406 RTC_DCHECK(0 != stream_err); |
407 LOG(LS_ERROR) << "RequestConnectedStream error: " << stream_err; | 407 LOG(LS_ERROR) << "RequestConnectedStream error: " << stream_err; |
408 onHttpComplete(HM_CONNECT, HE_CONNECT_FAILED); | 408 onHttpComplete(HM_CONNECT, HE_CONNECT_FAILED); |
409 } else { | 409 } else { |
410 base_.attach(stream); | 410 base_.attach(stream); |
411 if (stream->GetState() == SS_OPEN) { | 411 if (stream->GetState() == SS_OPEN) { |
412 base_.send(&transaction_->request); | 412 base_.send(&transaction_->request); |
413 } | 413 } |
414 } | 414 } |
415 } | 415 } |
416 | 416 |
(...skipping 29 matching lines...) Expand all Loading... |
446 || !response().hasHeader(HH_LOCATION, location) | 446 || !response().hasHeader(HH_LOCATION, location) |
447 || (redirects_ >= kMaxRedirects)) | 447 || (redirects_ >= kMaxRedirects)) |
448 return false; | 448 return false; |
449 return (REDIRECT_ALWAYS == redirect_action_) | 449 return (REDIRECT_ALWAYS == redirect_action_) |
450 || (HC_SEE_OTHER == response().scode) | 450 || (HC_SEE_OTHER == response().scode) |
451 || (HV_HEAD == request().verb) | 451 || (HV_HEAD == request().verb) |
452 || (HV_GET == request().verb); | 452 || (HV_GET == request().verb); |
453 } | 453 } |
454 | 454 |
455 bool HttpClient::BeginCacheFile() { | 455 bool HttpClient::BeginCacheFile() { |
456 ASSERT(NULL != cache_); | 456 RTC_DCHECK(NULL != cache_); |
457 ASSERT(CS_READY == cache_state_); | 457 RTC_DCHECK(CS_READY == cache_state_); |
458 | 458 |
459 std::string id = GetCacheID(request()); | 459 std::string id = GetCacheID(request()); |
460 CacheLock lock(cache_, id, true); | 460 CacheLock lock(cache_, id, true); |
461 if (!lock.IsLocked()) { | 461 if (!lock.IsLocked()) { |
462 LOG_F(LS_WARNING) << "Couldn't lock cache"; | 462 LOG_F(LS_WARNING) << "Couldn't lock cache"; |
463 return false; | 463 return false; |
464 } | 464 } |
465 | 465 |
466 if (HE_NONE != WriteCacheHeaders(id)) { | 466 if (HE_NONE != WriteCacheHeaders(id)) { |
467 return false; | 467 return false; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 // Delete the tap and cache stream (which completes cache unlock) | 513 // Delete the tap and cache stream (which completes cache unlock) |
514 delete tap; | 514 delete tap; |
515 | 515 |
516 if (SR_SUCCESS != result) { | 516 if (SR_SUCCESS != result) { |
517 LOG(LS_ERROR) << "Cache file error: " << error; | 517 LOG(LS_ERROR) << "Cache file error: " << error; |
518 cache_->DeleteResource(GetCacheID(request())); | 518 cache_->DeleteResource(GetCacheID(request())); |
519 } | 519 } |
520 } | 520 } |
521 | 521 |
522 bool HttpClient::CheckCache() { | 522 bool HttpClient::CheckCache() { |
523 ASSERT(NULL != cache_); | 523 RTC_DCHECK(NULL != cache_); |
524 ASSERT(CS_READY == cache_state_); | 524 RTC_DCHECK(CS_READY == cache_state_); |
525 | 525 |
526 std::string id = GetCacheID(request()); | 526 std::string id = GetCacheID(request()); |
527 if (!cache_->HasResource(id)) { | 527 if (!cache_->HasResource(id)) { |
528 // No cache file available | 528 // No cache file available |
529 return false; | 529 return false; |
530 } | 530 } |
531 | 531 |
532 HttpError error = ReadCacheHeaders(id, true); | 532 HttpError error = ReadCacheHeaders(id, true); |
533 | 533 |
534 if (HE_NONE == error) { | 534 if (HE_NONE == error) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 response().document.get()); | 608 response().document.get()); |
609 if (SR_SUCCESS != result) { | 609 if (SR_SUCCESS != result) { |
610 error = HE_STREAM; | 610 error = HE_STREAM; |
611 } | 611 } |
612 } | 612 } |
613 | 613 |
614 return error; | 614 return error; |
615 } | 615 } |
616 | 616 |
617 bool HttpClient::PrepareValidate() { | 617 bool HttpClient::PrepareValidate() { |
618 ASSERT(CS_READY == cache_state_); | 618 RTC_DCHECK(CS_READY == cache_state_); |
619 // At this point, request() contains the pending request, and response() | 619 // At this point, request() contains the pending request, and response() |
620 // contains the cached response headers. Reformat the request to validate | 620 // contains the cached response headers. Reformat the request to validate |
621 // the cached content. | 621 // the cached content. |
622 HttpValidatorStrength vs_required = HttpRequestValidatorLevel(request()); | 622 HttpValidatorStrength vs_required = HttpRequestValidatorLevel(request()); |
623 HttpValidatorStrength vs_available = HttpResponseValidatorLevel(response()); | 623 HttpValidatorStrength vs_available = HttpResponseValidatorLevel(response()); |
624 if (vs_available < vs_required) { | 624 if (vs_available < vs_required) { |
625 return false; | 625 return false; |
626 } | 626 } |
627 std::string value; | 627 std::string value; |
628 if (response().hasHeader(HH_ETAG, &value)) { | 628 if (response().hasHeader(HH_ETAG, &value)) { |
629 request().addHeader(HH_IF_NONE_MATCH, value); | 629 request().addHeader(HH_IF_NONE_MATCH, value); |
630 } | 630 } |
631 if (response().hasHeader(HH_LAST_MODIFIED, &value)) { | 631 if (response().hasHeader(HH_LAST_MODIFIED, &value)) { |
632 request().addHeader(HH_IF_MODIFIED_SINCE, value); | 632 request().addHeader(HH_IF_MODIFIED_SINCE, value); |
633 } | 633 } |
634 response().clear(false); | 634 response().clear(false); |
635 cache_state_ = CS_VALIDATING; | 635 cache_state_ = CS_VALIDATING; |
636 return true; | 636 return true; |
637 } | 637 } |
638 | 638 |
639 HttpError HttpClient::CompleteValidate() { | 639 HttpError HttpClient::CompleteValidate() { |
640 ASSERT(CS_VALIDATING == cache_state_); | 640 RTC_DCHECK(CS_VALIDATING == cache_state_); |
641 | 641 |
642 std::string id = GetCacheID(request()); | 642 std::string id = GetCacheID(request()); |
643 | 643 |
644 // Merge cached headers with new headers | 644 // Merge cached headers with new headers |
645 HttpError error = ReadCacheHeaders(id, false); | 645 HttpError error = ReadCacheHeaders(id, false); |
646 if (HE_NONE != error) { | 646 if (HE_NONE != error) { |
647 // Rewrite merged headers to cache | 647 // Rewrite merged headers to cache |
648 CacheLock lock(cache_, id); | 648 CacheLock lock(cache_, id); |
649 error = WriteCacheHeaders(id); | 649 error = WriteCacheHeaders(id); |
650 } | 650 } |
(...skipping 28 matching lines...) Expand all Loading... |
679 if (CS_VALIDATING == cache_state_) { | 679 if (CS_VALIDATING == cache_state_) { |
680 if (HC_NOT_MODIFIED == response().scode) { | 680 if (HC_NOT_MODIFIED == response().scode) { |
681 return CompleteValidate(); | 681 return CompleteValidate(); |
682 } | 682 } |
683 // Should we remove conditional headers from request? | 683 // Should we remove conditional headers from request? |
684 cache_state_ = CS_READY; | 684 cache_state_ = CS_READY; |
685 cache_->DeleteResource(GetCacheID(request())); | 685 cache_->DeleteResource(GetCacheID(request())); |
686 // Continue processing response as normal | 686 // Continue processing response as normal |
687 } | 687 } |
688 | 688 |
689 ASSERT(!IsCacheActive()); | 689 RTC_DCHECK(!IsCacheActive()); |
690 if ((request().verb == HV_HEAD) || !HttpCodeHasBody(response().scode)) { | 690 if ((request().verb == HV_HEAD) || !HttpCodeHasBody(response().scode)) { |
691 // HEAD requests and certain response codes contain no body | 691 // HEAD requests and certain response codes contain no body |
692 data_size = 0; | 692 data_size = 0; |
693 } | 693 } |
694 if (ShouldRedirect(NULL) | 694 if (ShouldRedirect(NULL) |
695 || ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode) | 695 || ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode) |
696 && (PROXY_HTTPS == proxy_.type))) { | 696 && (PROXY_HTTPS == proxy_.type))) { |
697 // We're going to issue another request, so ignore the incoming data. | 697 // We're going to issue another request, so ignore the incoming data. |
698 base_.set_ignore_data(true); | 698 base_.set_ignore_data(true); |
699 } | 699 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 Url<char> purl(location); | 750 Url<char> purl(location); |
751 set_server(SocketAddress(purl.host(), purl.port())); | 751 set_server(SocketAddress(purl.host(), purl.port())); |
752 request().path = purl.full_path(); | 752 request().path = purl.full_path(); |
753 if (response().scode == HC_SEE_OTHER) { | 753 if (response().scode == HC_SEE_OTHER) { |
754 request().verb = HV_GET; | 754 request().verb = HV_GET; |
755 request().clearHeader(HH_CONTENT_TYPE); | 755 request().clearHeader(HH_CONTENT_TYPE); |
756 request().clearHeader(HH_CONTENT_LENGTH); | 756 request().clearHeader(HH_CONTENT_LENGTH); |
757 request().document.reset(); | 757 request().document.reset(); |
758 } else if (request().document && !request().document->Rewind()) { | 758 } else if (request().document && !request().document->Rewind()) { |
759 // Unable to replay the request document. | 759 // Unable to replay the request document. |
760 ASSERT(REDIRECT_ALWAYS == redirect_action_); | 760 RTC_DCHECK(REDIRECT_ALWAYS == redirect_action_); |
761 err = HE_STREAM; | 761 err = HE_STREAM; |
762 } | 762 } |
763 if (err == HE_NONE) { | 763 if (err == HE_NONE) { |
764 ++redirects_; | 764 ++redirects_; |
765 context_.reset(); | 765 context_.reset(); |
766 response().clear(false); | 766 response().clear(false); |
767 release(); | 767 release(); |
768 start(); | 768 start(); |
769 return; | 769 return; |
770 } | 770 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 const std::string& agent, | 827 const std::string& agent, |
828 HttpTransaction* transaction) | 828 HttpTransaction* transaction) |
829 : ReuseSocketPool(factory ? factory : Thread::Current()->socketserver()), | 829 : ReuseSocketPool(factory ? factory : Thread::Current()->socketserver()), |
830 HttpClient(agent, NULL, transaction) { | 830 HttpClient(agent, NULL, transaction) { |
831 set_pool(this); | 831 set_pool(this); |
832 } | 832 } |
833 | 833 |
834 ////////////////////////////////////////////////////////////////////// | 834 ////////////////////////////////////////////////////////////////////// |
835 | 835 |
836 } // namespace rtc | 836 } // namespace rtc |
OLD | NEW |