| 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/url_request/url_request.h" | 5 #include "net/url_request/url_request.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 SSLCertRequestInfo* cert_request_info) { | 152 SSLCertRequestInfo* cert_request_info) { |
| 153 request->CancelWithError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 153 request->CancelWithError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); |
| 154 } | 154 } |
| 155 | 155 |
| 156 void URLRequest::Delegate::OnSSLCertificateError(URLRequest* request, | 156 void URLRequest::Delegate::OnSSLCertificateError(URLRequest* request, |
| 157 const SSLInfo& ssl_info, | 157 const SSLInfo& ssl_info, |
| 158 bool is_hsts_ok) { | 158 bool is_hsts_ok) { |
| 159 request->Cancel(); | 159 request->Cancel(); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void URLRequest::Delegate::OnResponseStarted(URLRequest* request, |
| 163 int net_error) { |
| 164 OnResponseStarted(request); |
| 165 } |
| 166 |
| 167 void URLRequest::Delegate::OnResponseStarted(URLRequest* request) { |
| 168 NOTREACHED(); |
| 169 } |
| 170 |
| 162 /////////////////////////////////////////////////////////////////////////////// | 171 /////////////////////////////////////////////////////////////////////////////// |
| 163 // URLRequest | 172 // URLRequest |
| 164 | 173 |
| 165 URLRequest::~URLRequest() { | 174 URLRequest::~URLRequest() { |
| 166 Cancel(); | 175 Cancel(); |
| 167 | 176 |
| 168 if (network_delegate_) { | 177 if (network_delegate_) { |
| 169 network_delegate_->NotifyURLRequestDestroyed(this); | 178 network_delegate_->NotifyURLRequestDestroyed(this); |
| 170 if (job_.get()) | 179 if (job_.get()) |
| 171 job_->NotifyURLRequestDestroyed(); | 180 job_->NotifyURLRequestDestroyed(); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 | 498 |
| 490 void URLRequest::set_delegate(Delegate* delegate) { | 499 void URLRequest::set_delegate(Delegate* delegate) { |
| 491 DCHECK(!delegate_); | 500 DCHECK(!delegate_); |
| 492 DCHECK(delegate); | 501 DCHECK(delegate); |
| 493 delegate_ = delegate; | 502 delegate_ = delegate; |
| 494 } | 503 } |
| 495 | 504 |
| 496 void URLRequest::Start() { | 505 void URLRequest::Start() { |
| 497 DCHECK(delegate_); | 506 DCHECK(delegate_); |
| 498 | 507 |
| 508 if (!status_.is_success()) |
| 509 return; |
| 510 |
| 499 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. | 511 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. |
| 500 tracked_objects::ScopedTracker tracking_profile( | 512 tracked_objects::ScopedTracker tracking_profile( |
| 501 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start")); | 513 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start")); |
| 502 | 514 |
| 503 // Some values can be NULL, but the job factory must not be. | 515 // Some values can be NULL, but the job factory must not be. |
| 504 DCHECK(context_->job_factory()); | 516 DCHECK(context_->job_factory()); |
| 505 | 517 |
| 506 // Anything that sets |blocked_by_| before start should have cleaned up after | 518 // Anything that sets |blocked_by_| before start should have cleaned up after |
| 507 // itself. | 519 // itself. |
| 508 DCHECK(blocked_by_.empty()); | 520 DCHECK(blocked_by_.empty()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 network_delegate_(network_delegate ? network_delegate | 560 network_delegate_(network_delegate ? network_delegate |
| 549 : context->network_delegate()), | 561 : context->network_delegate()), |
| 550 net_log_( | 562 net_log_( |
| 551 BoundNetLog::Make(context->net_log(), NetLog::SOURCE_URL_REQUEST)), | 563 BoundNetLog::Make(context->net_log(), NetLog::SOURCE_URL_REQUEST)), |
| 552 url_chain_(1, url), | 564 url_chain_(1, url), |
| 553 method_("GET"), | 565 method_("GET"), |
| 554 referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE), | 566 referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE), |
| 555 first_party_url_policy_(NEVER_CHANGE_FIRST_PARTY_URL), | 567 first_party_url_policy_(NEVER_CHANGE_FIRST_PARTY_URL), |
| 556 load_flags_(LOAD_NORMAL), | 568 load_flags_(LOAD_NORMAL), |
| 557 delegate_(delegate), | 569 delegate_(delegate), |
| 570 status_(URLRequestStatus::FromError(OK)), |
| 558 is_pending_(false), | 571 is_pending_(false), |
| 559 is_redirecting_(false), | 572 is_redirecting_(false), |
| 560 redirect_limit_(kMaxRedirects), | 573 redirect_limit_(kMaxRedirects), |
| 561 priority_(priority), | 574 priority_(priority), |
| 562 identifier_(GenerateURLRequestIdentifier()), | 575 identifier_(GenerateURLRequestIdentifier()), |
| 563 calling_delegate_(false), | 576 calling_delegate_(false), |
| 564 use_blocked_by_as_load_param_(false), | 577 use_blocked_by_as_load_param_(false), |
| 565 before_request_callback_(base::Bind(&URLRequest::BeforeRequestComplete, | 578 before_request_callback_(base::Bind(&URLRequest::BeforeRequestComplete, |
| 566 base::Unretained(this))), | 579 base::Unretained(this))), |
| 567 has_notified_completion_(false), | 580 has_notified_completion_(false), |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 RestartWithJob( | 678 RestartWithJob( |
| 666 URLRequestJobManager::GetInstance()->CreateJob(this, network_delegate_)); | 679 URLRequestJobManager::GetInstance()->CreateJob(this, network_delegate_)); |
| 667 } | 680 } |
| 668 | 681 |
| 669 void URLRequest::RestartWithJob(URLRequestJob *job) { | 682 void URLRequest::RestartWithJob(URLRequestJob *job) { |
| 670 DCHECK(job->request() == this); | 683 DCHECK(job->request() == this); |
| 671 PrepareToRestart(); | 684 PrepareToRestart(); |
| 672 StartJob(job); | 685 StartJob(job); |
| 673 } | 686 } |
| 674 | 687 |
| 675 void URLRequest::Cancel() { | 688 int URLRequest::Cancel() { |
| 676 DoCancel(ERR_ABORTED, SSLInfo()); | 689 return DoCancel(ERR_ABORTED, SSLInfo()); |
| 677 } | 690 } |
| 678 | 691 |
| 679 void URLRequest::CancelWithError(int error) { | 692 int URLRequest::CancelWithError(int error) { |
| 680 DoCancel(error, SSLInfo()); | 693 return DoCancel(error, SSLInfo()); |
| 681 } | 694 } |
| 682 | 695 |
| 683 void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) { | 696 void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) { |
| 684 // This should only be called on a started request. | 697 // This should only be called on a started request. |
| 685 if (!is_pending_ || !job_.get() || job_->has_response_started()) { | 698 if (!is_pending_ || !job_.get() || job_->has_response_started()) { |
| 686 NOTREACHED(); | 699 NOTREACHED(); |
| 687 return; | 700 return; |
| 688 } | 701 } |
| 689 DoCancel(error, ssl_info); | 702 DoCancel(error, ssl_info); |
| 690 } | 703 } |
| 691 | 704 |
| 692 void URLRequest::DoCancel(int error, const SSLInfo& ssl_info) { | 705 int URLRequest::DoCancel(int error, const SSLInfo& ssl_info) { |
| 693 DCHECK(error < 0); | 706 DCHECK(error < 0); |
| 694 // If cancelled while calling a delegate, clear delegate info. | 707 // If cancelled while calling a delegate, clear delegate info. |
| 695 if (calling_delegate_) { | 708 if (calling_delegate_) { |
| 696 LogUnblocked(); | 709 LogUnblocked(); |
| 697 OnCallToDelegateComplete(); | 710 OnCallToDelegateComplete(); |
| 698 } | 711 } |
| 699 | 712 |
| 700 // If the URL request already has an error status, then canceling is a no-op. | 713 // If the URL request already has an error status, then canceling is a no-op. |
| 701 // Plus, we don't want to change the error status once it has been set. | 714 // Plus, we don't want to change the error status once it has been set. |
| 702 if (status_.is_success()) { | 715 if (status_.is_success()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 715 job_->Kill(); | 728 job_->Kill(); |
| 716 | 729 |
| 717 // We need to notify about the end of this job here synchronously. The | 730 // We need to notify about the end of this job here synchronously. The |
| 718 // Job sends an asynchronous notification but by the time this is processed, | 731 // Job sends an asynchronous notification but by the time this is processed, |
| 719 // our |context_| is NULL. | 732 // our |context_| is NULL. |
| 720 NotifyRequestCompleted(); | 733 NotifyRequestCompleted(); |
| 721 | 734 |
| 722 // The Job will call our NotifyDone method asynchronously. This is done so | 735 // The Job will call our NotifyDone method asynchronously. This is done so |
| 723 // that the Delegate implementation can call Cancel without having to worry | 736 // that the Delegate implementation can call Cancel without having to worry |
| 724 // about being called recursively. | 737 // about being called recursively. |
| 738 |
| 739 return status_.error(); |
| 725 } | 740 } |
| 726 | 741 |
| 727 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) { | 742 int URLRequest::Read(IOBuffer* dest, int dest_size) { |
| 728 DCHECK(job_.get()); | 743 DCHECK(job_.get()); |
| 729 DCHECK(bytes_read); | |
| 730 *bytes_read = 0; | |
| 731 | 744 |
| 732 // If this is the first read, end the delegate call that may have started in | 745 // If this is the first read, end the delegate call that may have started in |
| 733 // OnResponseStarted. | 746 // OnResponseStarted. |
| 734 OnCallToDelegateComplete(); | 747 OnCallToDelegateComplete(); |
| 735 | 748 |
| 736 // This handles a cancel that happens while paused. | 749 // If the request has failed, Read() will return actual network error code. |
| 750 if (!status_.is_success()) |
| 751 return status_.error(); |
| 752 |
| 753 // This handles reads after the request already completed successfully. |
| 737 // TODO(ahendrickson): DCHECK() that it is not done after | 754 // TODO(ahendrickson): DCHECK() that it is not done after |
| 738 // http://crbug.com/115705 is fixed. | 755 // http://crbug.com/115705 is fixed. |
| 739 if (job_->is_done()) | 756 if (job_->is_done()) |
| 740 return false; | 757 return status_.error(); |
| 741 | 758 |
| 742 if (dest_size == 0) { | 759 if (dest_size == 0) { |
| 743 // Caller is not too bright. I guess we've done what they asked. | 760 // Caller is not too bright. I guess we've done what they asked. |
| 744 return true; | 761 return OK; |
| 745 } | 762 } |
| 746 | 763 |
| 747 // Once the request fails or is cancelled, read will just return 0 bytes | 764 int rv = job_->Read(dest, dest_size); |
| 748 // to indicate end of stream. | 765 if (rv == ERR_IO_PENDING) |
| 749 if (!status_.is_success()) { | 766 set_status(URLRequestStatus::FromError(ERR_IO_PENDING)); |
| 750 return true; | |
| 751 } | |
| 752 | 767 |
| 753 bool rv = job_->Read(dest, dest_size, bytes_read); | 768 // If rv is not 0 or actual bytes read, the status cannot be success. |
| 754 if (*bytes_read < 0) { | 769 DCHECK(rv >= 0 || status_.status() != URLRequestStatus::SUCCESS); |
| 755 if (*bytes_read == ERR_IO_PENDING) { | |
| 756 set_status(URLRequestStatus::FromError(ERR_IO_PENDING)); | |
| 757 // Check the status was set correctly. | |
| 758 DCHECK_EQ(*bytes_read, status_.error()); | |
| 759 // Adjust to the previous behavior. If the error is ERR_IO_PENDING, | |
| 760 // |*bytes_read| should be 0. | |
| 761 *bytes_read = 0; | |
| 762 } else { | |
| 763 // Check the status was set correctly. | |
| 764 DCHECK_EQ(*bytes_read, status_.error()); | |
| 765 // Adjust to the previous behavior. If the error is other than | |
| 766 // ERR_IO_PENDING, |*bytes_read| should be -1. | |
| 767 *bytes_read = -1; | |
| 768 } | |
| 769 } | |
| 770 | 770 |
| 771 // If rv is false, the status cannot be success. | 771 if (rv == 0 && status_.is_success()) |
| 772 DCHECK(rv || status_.status() != URLRequestStatus::SUCCESS); | |
| 773 | |
| 774 if (rv && *bytes_read <= 0 && status_.is_success()) | |
| 775 NotifyRequestCompleted(); | 772 NotifyRequestCompleted(); |
| 776 return rv; | 773 return rv; |
| 777 } | 774 } |
| 778 | 775 |
| 776 // Deprecated. |
| 777 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) { |
| 778 int result = Read(dest, dest_size); |
| 779 if (result >= 0) { |
| 780 *bytes_read = result; |
| 781 return true; |
| 782 } |
| 783 |
| 784 if (result == ERR_IO_PENDING) { |
| 785 *bytes_read = 0; |
| 786 } else { |
| 787 *bytes_read = -1; |
| 788 } |
| 789 |
| 790 return false; |
| 791 } |
| 792 |
| 779 void URLRequest::StopCaching() { | 793 void URLRequest::StopCaching() { |
| 780 DCHECK(job_.get()); | 794 DCHECK(job_.get()); |
| 781 job_->StopCaching(); | 795 job_->StopCaching(); |
| 782 } | 796 } |
| 783 | 797 |
| 784 void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info, | 798 void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info, |
| 785 bool* defer_redirect) { | 799 bool* defer_redirect) { |
| 786 is_redirecting_ = true; | 800 is_redirecting_ = true; |
| 787 | 801 |
| 788 // TODO(davidben): Pass the full RedirectInfo down to MaybeInterceptRedirect? | 802 // TODO(davidben): Pass the full RedirectInfo down to MaybeInterceptRedirect? |
| (...skipping 30 matching lines...) Expand all Loading... |
| 819 URLRequestJob* job = | 833 URLRequestJob* job = |
| 820 URLRequestJobManager::GetInstance()->MaybeInterceptResponse( | 834 URLRequestJobManager::GetInstance()->MaybeInterceptResponse( |
| 821 this, network_delegate_); | 835 this, network_delegate_); |
| 822 if (job) { | 836 if (job) { |
| 823 RestartWithJob(job); | 837 RestartWithJob(job); |
| 824 } else { | 838 } else { |
| 825 // In some cases (e.g. an event was canceled), we might have sent the | 839 // In some cases (e.g. an event was canceled), we might have sent the |
| 826 // completion event and receive a NotifyResponseStarted() later. | 840 // completion event and receive a NotifyResponseStarted() later. |
| 827 if (!has_notified_completion_ && status_.is_success()) { | 841 if (!has_notified_completion_ && status_.is_success()) { |
| 828 if (network_delegate_) | 842 if (network_delegate_) |
| 829 network_delegate_->NotifyResponseStarted(this); | 843 network_delegate_->NotifyResponseStarted(this, net_error); |
| 830 } | 844 } |
| 831 | 845 |
| 832 // Notify in case the entire URL Request has been finished. | 846 // Notify in case the entire URL Request has been finished. |
| 833 if (!has_notified_completion_ && !status_.is_success()) | 847 if (!has_notified_completion_ && !status_.is_success()) |
| 834 NotifyRequestCompleted(); | 848 NotifyRequestCompleted(); |
| 835 | 849 |
| 836 OnCallToDelegate(); | 850 OnCallToDelegate(); |
| 837 delegate_->OnResponseStarted(this); | 851 delegate_->OnResponseStarted(this, net_error); |
| 838 // Nothing may appear below this line as OnResponseStarted may delete | 852 // Nothing may appear below this line as OnResponseStarted may delete |
| 839 // |this|. | 853 // |this|. |
| 840 } | 854 } |
| 841 } | 855 } |
| 842 | 856 |
| 843 void URLRequest::FollowDeferredRedirect() { | 857 void URLRequest::FollowDeferredRedirect() { |
| 844 DCHECK(job_.get()); | 858 DCHECK(job_.get()); |
| 845 DCHECK(status_.is_success()); | 859 DCHECK(status_.is_success()); |
| 846 | 860 |
| 847 status_ = URLRequestStatus::FromError(ERR_IO_PENDING); | 861 status_ = URLRequestStatus::FromError(ERR_IO_PENDING); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 } | 1147 } |
| 1134 | 1148 |
| 1135 | 1149 |
| 1136 void URLRequest::NotifyReadCompleted(int bytes_read) { | 1150 void URLRequest::NotifyReadCompleted(int bytes_read) { |
| 1137 if (bytes_read > 0) | 1151 if (bytes_read > 0) |
| 1138 set_status(URLRequestStatus()); | 1152 set_status(URLRequestStatus()); |
| 1139 // Notify in case the entire URL Request has been finished. | 1153 // Notify in case the entire URL Request has been finished. |
| 1140 if (bytes_read <= 0) | 1154 if (bytes_read <= 0) |
| 1141 NotifyRequestCompleted(); | 1155 NotifyRequestCompleted(); |
| 1142 | 1156 |
| 1157 // When URLRequestJob notices there was an error in URLRequest's |status_|, |
| 1158 // it calls this method with |bytes_read| set to -1. Set it to a real error |
| 1159 // here. |
| 1160 // TODO(maksims): NotifyReadCompleted take the error code as an argument on |
| 1161 // failure, rather than -1. |
| 1162 if (bytes_read == -1) |
| 1163 bytes_read = status_.error(); |
| 1164 |
| 1143 // Notify NetworkChangeNotifier that we just received network data. | 1165 // Notify NetworkChangeNotifier that we just received network data. |
| 1144 // This is to identify cases where the NetworkChangeNotifier thinks we | 1166 // This is to identify cases where the NetworkChangeNotifier thinks we |
| 1145 // are off-line but we are still receiving network data (crbug.com/124069), | 1167 // are off-line but we are still receiving network data (crbug.com/124069), |
| 1146 // and to get rough network connection measurements. | 1168 // and to get rough network connection measurements. |
| 1147 if (bytes_read > 0 && !was_cached()) | 1169 if (bytes_read > 0 && !was_cached()) |
| 1148 NetworkChangeNotifier::NotifyDataReceived(*this, bytes_read); | 1170 NetworkChangeNotifier::NotifyDataReceived(*this, bytes_read); |
| 1149 | 1171 |
| 1150 delegate_->OnReadCompleted(this, bytes_read); | 1172 delegate_->OnReadCompleted(this, bytes_read); |
| 1151 | 1173 |
| 1152 // Nothing below this line as OnReadCompleted may delete |this|. | 1174 // Nothing below this line as OnReadCompleted may delete |this|. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1177 void URLRequest::NotifyRequestCompleted() { | 1199 void URLRequest::NotifyRequestCompleted() { |
| 1178 // TODO(battre): Get rid of this check, according to willchan it should | 1200 // TODO(battre): Get rid of this check, according to willchan it should |
| 1179 // not be needed. | 1201 // not be needed. |
| 1180 if (has_notified_completion_) | 1202 if (has_notified_completion_) |
| 1181 return; | 1203 return; |
| 1182 | 1204 |
| 1183 is_pending_ = false; | 1205 is_pending_ = false; |
| 1184 is_redirecting_ = false; | 1206 is_redirecting_ = false; |
| 1185 has_notified_completion_ = true; | 1207 has_notified_completion_ = true; |
| 1186 if (network_delegate_) | 1208 if (network_delegate_) |
| 1187 network_delegate_->NotifyCompleted(this, job_.get() != NULL); | 1209 network_delegate_->NotifyCompleted(this, job_.get() != NULL, |
| 1210 status_.error()); |
| 1188 } | 1211 } |
| 1189 | 1212 |
| 1190 void URLRequest::OnCallToDelegate() { | 1213 void URLRequest::OnCallToDelegate() { |
| 1191 DCHECK(!calling_delegate_); | 1214 DCHECK(!calling_delegate_); |
| 1192 DCHECK(blocked_by_.empty()); | 1215 DCHECK(blocked_by_.empty()); |
| 1193 calling_delegate_ = true; | 1216 calling_delegate_ = true; |
| 1194 net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_DELEGATE); | 1217 net_log_.BeginEvent(NetLog::TYPE_URL_REQUEST_DELEGATE); |
| 1195 } | 1218 } |
| 1196 | 1219 |
| 1197 void URLRequest::OnCallToDelegateComplete() { | 1220 void URLRequest::OnCallToDelegateComplete() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1210 out->clear(); | 1233 out->clear(); |
| 1211 } | 1234 } |
| 1212 | 1235 |
| 1213 void URLRequest::set_status(URLRequestStatus status) { | 1236 void URLRequest::set_status(URLRequestStatus status) { |
| 1214 DCHECK(status_.is_io_pending() || status_.is_success() || | 1237 DCHECK(status_.is_io_pending() || status_.is_success() || |
| 1215 (!status.is_success() && !status.is_io_pending())); | 1238 (!status.is_success() && !status.is_io_pending())); |
| 1216 status_ = status; | 1239 status_ = status; |
| 1217 } | 1240 } |
| 1218 | 1241 |
| 1219 } // namespace net | 1242 } // namespace net |
| OLD | NEW |