OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_http_job.h" | 5 #include "net/url_request/url_request_http_job.h" |
6 | 6 |
7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/file_version_info.h" | 11 #include "base/file_version_info.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "base/utf_string_conversions.h" |
15 #include "net/base/cert_status_flags.h" | 16 #include "net/base/cert_status_flags.h" |
16 #include "net/base/cookie_policy.h" | 17 #include "net/base/cookie_policy.h" |
17 #include "net/base/cookie_store.h" | 18 #include "net/base/cookie_store.h" |
18 #include "net/base/filter.h" | 19 #include "net/base/filter.h" |
19 #include "net/base/transport_security_state.h" | 20 #include "net/base/transport_security_state.h" |
20 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
22 #include "net/base/net_util.h" | 23 #include "net/base/net_util.h" |
23 #include "net/base/sdch_manager.h" | 24 #include "net/base/sdch_manager.h" |
24 #include "net/base/ssl_cert_request_info.h" | 25 #include "net/base/ssl_cert_request_info.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 const bool include_subdomains_; | 76 const bool include_subdomains_; |
76 scoped_refptr<TransportSecurityState> sts_; | 77 scoped_refptr<TransportSecurityState> sts_; |
77 }; | 78 }; |
78 | 79 |
79 } // namespace | 80 } // namespace |
80 | 81 |
81 // TODO(darin): make sure the port blocking code is not lost | 82 // TODO(darin): make sure the port blocking code is not lost |
82 // static | 83 // static |
83 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, | 84 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, |
84 const std::string& scheme) { | 85 const std::string& scheme) { |
85 DCHECK(scheme == "http" || scheme == "https"); | 86 DCHECK(scheme == "http" || scheme == "https" || scheme == "httpsv"); |
86 | 87 |
87 int port = request->url().IntPort(); | 88 int port = request->url().IntPort(); |
88 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) | 89 if (!IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) |
89 return new URLRequestErrorJob(request, ERR_UNSAFE_PORT); | 90 return new URLRequestErrorJob(request, ERR_UNSAFE_PORT); |
90 | 91 |
91 if (!request->context() || | 92 if (!request->context() || |
92 !request->context()->http_transaction_factory()) { | 93 !request->context()->http_transaction_factory()) { |
93 NOTREACHED() << "requires a valid context"; | 94 NOTREACHED() << "requires a valid context"; |
94 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); | 95 return new URLRequestErrorJob(request, ERR_INVALID_ARGUMENT); |
95 } | 96 } |
(...skipping 21 matching lines...) Expand all Loading... |
117 return new URLRequestHttpJob(request); | 118 return new URLRequestHttpJob(request); |
118 } | 119 } |
119 | 120 |
120 | 121 |
121 URLRequestHttpJob::URLRequestHttpJob(URLRequest* request) | 122 URLRequestHttpJob::URLRequestHttpJob(URLRequest* request) |
122 : URLRequestJob(request), | 123 : URLRequestJob(request), |
123 response_info_(NULL), | 124 response_info_(NULL), |
124 response_cookies_save_index_(0), | 125 response_cookies_save_index_(0), |
125 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 126 proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
126 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), | 127 server_auth_state_(AUTH_STATE_DONT_NEED_AUTH), |
| 128 tls_login_auth_data_(request->GetTLSLoginAuthData()), |
127 ALLOW_THIS_IN_INITIALIZER_LIST(can_get_cookies_callback_( | 129 ALLOW_THIS_IN_INITIALIZER_LIST(can_get_cookies_callback_( |
128 this, &URLRequestHttpJob::OnCanGetCookiesCompleted)), | 130 this, &URLRequestHttpJob::OnCanGetCookiesCompleted)), |
129 ALLOW_THIS_IN_INITIALIZER_LIST(can_set_cookie_callback_( | 131 ALLOW_THIS_IN_INITIALIZER_LIST(can_set_cookie_callback_( |
130 this, &URLRequestHttpJob::OnCanSetCookieCompleted)), | 132 this, &URLRequestHttpJob::OnCanSetCookieCompleted)), |
131 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( | 133 ALLOW_THIS_IN_INITIALIZER_LIST(start_callback_( |
132 this, &URLRequestHttpJob::OnStartCompleted)), | 134 this, &URLRequestHttpJob::OnStartCompleted)), |
133 ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_( | 135 ALLOW_THIS_IN_INITIALIZER_LIST(read_callback_( |
134 this, &URLRequestHttpJob::OnReadCompleted)), | 136 this, &URLRequestHttpJob::OnReadCompleted)), |
135 read_in_progress_(false), | 137 read_in_progress_(false), |
136 transaction_(NULL), | 138 transaction_(NULL), |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 rv = transaction_->RestartWithAuth(username_, password_, &start_callback_); | 214 rv = transaction_->RestartWithAuth(username_, password_, &start_callback_); |
213 username_.clear(); | 215 username_.clear(); |
214 password_.clear(); | 216 password_.clear(); |
215 } else { | 217 } else { |
216 DCHECK(request_->context()); | 218 DCHECK(request_->context()); |
217 DCHECK(request_->context()->http_transaction_factory()); | 219 DCHECK(request_->context()->http_transaction_factory()); |
218 | 220 |
219 rv = request_->context()->http_transaction_factory()->CreateTransaction( | 221 rv = request_->context()->http_transaction_factory()->CreateTransaction( |
220 &transaction_); | 222 &transaction_); |
221 if (rv == OK) { | 223 if (rv == OK) { |
| 224 if (tls_login_auth_data_->state == AUTH_STATE_HAVE_AUTH) { |
| 225 transaction_->SetTLSLoginAuthData(tls_login_auth_data_); |
| 226 } |
| 227 |
222 rv = transaction_->Start( | 228 rv = transaction_->Start( |
223 &request_info_, &start_callback_, request_->net_log()); | 229 &request_info_, &start_callback_, request_->net_log()); |
224 // Make sure the context is alive for the duration of the | 230 // Make sure the context is alive for the duration of the |
225 // transaction. | 231 // transaction. |
226 context_ = request_->context(); | 232 context_ = request_->context(); |
227 } | 233 } |
228 } | 234 } |
229 | 235 |
230 if (rv == ERR_IO_PENDING) | 236 if (rv == ERR_IO_PENDING) |
231 return; | 237 return; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 } else if (ShouldTreatAsCertificateError(result)) { | 566 } else if (ShouldTreatAsCertificateError(result)) { |
561 // We encountered an SSL certificate error. Ask our delegate to decide | 567 // We encountered an SSL certificate error. Ask our delegate to decide |
562 // what we should do. | 568 // what we should do. |
563 // TODO(wtc): also pass ssl_info.cert_status, or just pass the whole | 569 // TODO(wtc): also pass ssl_info.cert_status, or just pass the whole |
564 // ssl_info. | 570 // ssl_info. |
565 request_->delegate()->OnSSLCertificateError( | 571 request_->delegate()->OnSSLCertificateError( |
566 request_, result, transaction_->GetResponseInfo()->ssl_info.cert); | 572 request_, result, transaction_->GetResponseInfo()->ssl_info.cert); |
567 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 573 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
568 request_->delegate()->OnCertificateRequested( | 574 request_->delegate()->OnCertificateRequested( |
569 request_, transaction_->GetResponseInfo()->cert_request_info); | 575 request_, transaction_->GetResponseInfo()->cert_request_info); |
| 576 } else if (result == ERR_TLS_CLIENT_LOGIN_NEEDED || |
| 577 result == ERR_TLS_CLIENT_LOGIN_FAILED) { |
| 578 DCHECK(transaction_->GetResponseInfo()); |
| 579 DCHECK(transaction_->GetResponseInfo()->login_request_info.get()); |
| 580 request_->delegate()->OnTLSLoginRequired( |
| 581 request_, transaction_->GetResponseInfo()->login_request_info); |
570 } else { | 582 } else { |
571 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); | 583 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
572 } | 584 } |
573 } | 585 } |
574 | 586 |
575 void URLRequestHttpJob::OnReadCompleted(int result) { | 587 void URLRequestHttpJob::OnReadCompleted(int result) { |
576 read_in_progress_ = false; | 588 read_in_progress_ = false; |
577 | 589 |
578 if (result == 0) { | 590 if (result == 0) { |
579 NotifyDone(URLRequestStatus()); | 591 NotifyDone(URLRequestStatus()); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 // We only allow redirects to certain "safe" protocols. This does not | 770 // We only allow redirects to certain "safe" protocols. This does not |
759 // restrict redirects to externally handled protocols. Our consumer would | 771 // restrict redirects to externally handled protocols. Our consumer would |
760 // need to take care of those. | 772 // need to take care of those. |
761 | 773 |
762 if (!URLRequest::IsHandledURL(location)) | 774 if (!URLRequest::IsHandledURL(location)) |
763 return true; | 775 return true; |
764 | 776 |
765 static const char* kSafeSchemes[] = { | 777 static const char* kSafeSchemes[] = { |
766 "http", | 778 "http", |
767 "https", | 779 "https", |
| 780 "httpsv", |
768 "ftp" | 781 "ftp" |
769 }; | 782 }; |
770 | 783 |
771 for (size_t i = 0; i < arraysize(kSafeSchemes); ++i) { | 784 for (size_t i = 0; i < arraysize(kSafeSchemes); ++i) { |
772 if (location.SchemeIs(kSafeSchemes[i])) | 785 if (location.SchemeIs(kSafeSchemes[i])) |
773 return true; | 786 return true; |
774 } | 787 } |
775 | 788 |
776 return false; | 789 return false; |
777 } | 790 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 // OnAuthRequired. | 860 // OnAuthRequired. |
848 // | 861 // |
849 // We have to do this via InvokeLater to avoid "recursing" the consumer. | 862 // We have to do this via InvokeLater to avoid "recursing" the consumer. |
850 // | 863 // |
851 MessageLoop::current()->PostTask( | 864 MessageLoop::current()->PostTask( |
852 FROM_HERE, | 865 FROM_HERE, |
853 method_factory_.NewRunnableMethod( | 866 method_factory_.NewRunnableMethod( |
854 &URLRequestHttpJob::OnStartCompleted, OK)); | 867 &URLRequestHttpJob::OnStartCompleted, OK)); |
855 } | 868 } |
856 | 869 |
| 870 void URLRequestHttpJob::CancelTLSLogin() { |
| 871 // These will be reset in OnStartCompleted. |
| 872 response_info_ = NULL; |
| 873 |
| 874 MessageLoop::current()->PostTask( |
| 875 FROM_HERE, |
| 876 method_factory_.NewRunnableMethod( |
| 877 &URLRequestHttpJob::OnStartCompleted, |
| 878 ERR_ABORTED)); |
| 879 } |
| 880 |
857 void URLRequestHttpJob::ContinueWithCertificate( | 881 void URLRequestHttpJob::ContinueWithCertificate( |
858 X509Certificate* client_cert) { | 882 X509Certificate* client_cert) { |
859 DCHECK(transaction_.get()); | 883 DCHECK(transaction_.get()); |
860 | 884 |
861 DCHECK(!response_info_) << "should not have a response yet"; | 885 DCHECK(!response_info_) << "should not have a response yet"; |
862 | 886 |
863 // No matter what, we want to report our status as IO pending since we will | 887 // No matter what, we want to report our status as IO pending since we will |
864 // be notifying our consumer asynchronously via OnStartCompleted. | 888 // be notifying our consumer asynchronously via OnStartCompleted. |
865 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 889 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
866 | 890 |
867 int rv = transaction_->RestartWithCertificate(client_cert, &start_callback_); | 891 int rv = transaction_->RestartWithCertificate(client_cert, &start_callback_); |
868 if (rv == ERR_IO_PENDING) | 892 if (rv == ERR_IO_PENDING) |
869 return; | 893 return; |
870 | 894 |
871 // The transaction started synchronously, but we need to notify the | 895 // The transaction started synchronously, but we need to notify the |
872 // URLRequest delegate via the message loop. | 896 // URLRequest delegate via the message loop. |
873 MessageLoop::current()->PostTask( | 897 MessageLoop::current()->PostTask( |
874 FROM_HERE, | 898 FROM_HERE, |
875 method_factory_.NewRunnableMethod( | 899 method_factory_.NewRunnableMethod( |
876 &URLRequestHttpJob::OnStartCompleted, rv)); | 900 &URLRequestHttpJob::OnStartCompleted, rv)); |
877 } | 901 } |
878 | 902 |
| 903 void URLRequestHttpJob::ContinueWithTLSLogin() { |
| 904 DCHECK(tls_login_auth_data_->state == AUTH_STATE_HAVE_AUTH); |
| 905 |
| 906 transaction_->SetTLSLoginAuthData(tls_login_auth_data_); |
| 907 |
| 908 DCHECK(transaction_.get()); |
| 909 |
| 910 DCHECK(!response_info_) << "should not have a response yet"; |
| 911 |
| 912 // No matter what, we want to report our status as IO pending since we will |
| 913 // be notifying our consumer asynchronously via OnStartCompleted. |
| 914 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 915 |
| 916 int rv = transaction_->RestartWithTLSLogin(&start_callback_); |
| 917 if (rv == ERR_IO_PENDING) |
| 918 return; |
| 919 |
| 920 // The transaction started synchronously, but we need to notify the |
| 921 // URLRequest delegate via the message loop. |
| 922 MessageLoop::current()->PostTask( |
| 923 FROM_HERE, |
| 924 method_factory_.NewRunnableMethod( |
| 925 &URLRequestHttpJob::OnStartCompleted, rv)); |
| 926 } |
| 927 |
879 void URLRequestHttpJob::ContinueDespiteLastError() { | 928 void URLRequestHttpJob::ContinueDespiteLastError() { |
880 // If the transaction was destroyed, then the job was cancelled. | 929 // If the transaction was destroyed, then the job was cancelled. |
881 if (!transaction_.get()) | 930 if (!transaction_.get()) |
882 return; | 931 return; |
883 | 932 |
884 DCHECK(!response_info_) << "should not have a response yet"; | 933 DCHECK(!response_info_) << "should not have a response yet"; |
885 | 934 |
886 // No matter what, we want to report our status as IO pending since we will | 935 // No matter what, we want to report our status as IO pending since we will |
887 // be notifying our consumer asynchronously via OnStartCompleted. | 936 // be notifying our consumer asynchronously via OnStartCompleted. |
888 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 937 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 // At shutdown time, care is taken to be sure that we don't delete this | 997 // At shutdown time, care is taken to be sure that we don't delete this |
949 // globally useful instance "too soon," so this check is just defensive | 998 // globally useful instance "too soon," so this check is just defensive |
950 // coding to assure that IF the system is shutting down, we don't have any | 999 // coding to assure that IF the system is shutting down, we don't have any |
951 // problem if the manager was deleted ahead of time. | 1000 // problem if the manager was deleted ahead of time. |
952 if (manager) // Defensive programming. | 1001 if (manager) // Defensive programming. |
953 manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); | 1002 manager->FetchDictionary(request_info_.url, sdch_dictionary_url_); |
954 } | 1003 } |
955 } | 1004 } |
956 | 1005 |
957 } // namespace net | 1006 } // namespace net |
OLD | NEW |