| 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 |