| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome_frame/urlmon_url_request.h" | 5 #include "chrome_frame/urlmon_url_request.h" |
| 6 | 6 |
| 7 #include <urlmon.h> |
| 7 #include <wininet.h> | 8 #include <wininet.h> |
| 8 #include <urlmon.h> | |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
| 14 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
| 15 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "chrome/common/automation_messages.h" |
| 17 #include "chrome_frame/bind_context_info.h" | 18 #include "chrome_frame/bind_context_info.h" |
| 18 #include "chrome_frame/chrome_frame_activex_base.h" | 19 #include "chrome_frame/chrome_frame_activex_base.h" |
| 19 #include "chrome_frame/extra_system_apis.h" | 20 #include "chrome_frame/extra_system_apis.h" |
| 20 #include "chrome_frame/html_utils.h" | 21 #include "chrome_frame/html_utils.h" |
| 22 #include "chrome_frame/urlmon_upload_data_stream.h" |
| 21 #include "chrome_frame/urlmon_url_request_private.h" | 23 #include "chrome_frame/urlmon_url_request_private.h" |
| 22 #include "chrome_frame/urlmon_upload_data_stream.h" | |
| 23 #include "chrome_frame/utils.h" | 24 #include "chrome_frame/utils.h" |
| 24 #include "chrome/common/automation_messages.h" | |
| 25 #include "net/base/load_flags.h" | 25 #include "net/base/load_flags.h" |
| 26 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
| 27 #include "net/http/http_util.h" | 27 #include "net/http/http_util.h" |
| 28 | 28 |
| 29 UrlmonUrlRequest::UrlmonUrlRequest() | 29 UrlmonUrlRequest::UrlmonUrlRequest() |
| 30 : pending_read_size_(0), | 30 : pending_read_size_(0), |
| 31 headers_received_(false), | 31 headers_received_(false), |
| 32 calling_delegate_(0), | 32 calling_delegate_(0), |
| 33 thread_(NULL), | 33 thread_(NULL), |
| 34 parent_window_(NULL), | 34 parent_window_(NULL), |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 terminate_bind_callback_.reset(callback); | 178 terminate_bind_callback_.reset(callback); |
| 179 if (pending_data_) { | 179 if (pending_data_) { |
| 180 // For downloads to work correctly, we must induce a call to | 180 // For downloads to work correctly, we must induce a call to |
| 181 // OnDataAvailable so that we can download INET_E_TERMINATED_BIND and | 181 // OnDataAvailable so that we can download INET_E_TERMINATED_BIND and |
| 182 // get IE into the correct state. | 182 // get IE into the correct state. |
| 183 // To accomplish this we read everything that's readily available in | 183 // To accomplish this we read everything that's readily available in |
| 184 // the current stream. Once we've reached the end of the stream we | 184 // the current stream. Once we've reached the end of the stream we |
| 185 // should get E_PENDING back and then later we'll get that call | 185 // should get E_PENDING back and then later we'll get that call |
| 186 // to OnDataAvailable. | 186 // to OnDataAvailable. |
| 187 std::string data; | 187 std::string data; |
| 188 ScopedComPtr<IStream> read_stream(pending_data_); | 188 base::win::ScopedComPtr<IStream> read_stream(pending_data_); |
| 189 HRESULT hr; | 189 HRESULT hr; |
| 190 while ((hr = ReadStream(read_stream, 0xffff, &data)) == S_OK) { | 190 while ((hr = ReadStream(read_stream, 0xffff, &data)) == S_OK) { |
| 191 // Just drop the data. | 191 // Just drop the data. |
| 192 } | 192 } |
| 193 DLOG_IF(WARNING, hr != E_PENDING) << __FUNCTION__ << | 193 DLOG_IF(WARNING, hr != E_PENDING) << __FUNCTION__ << |
| 194 base::StringPrintf(" expected E_PENDING but got 0x%08X", hr); | 194 base::StringPrintf(" expected E_PENDING but got 0x%08X", hr); |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 | 198 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 212 } | 212 } |
| 213 | 213 |
| 214 if (read_data.empty() && pending_data_) { | 214 if (read_data.empty() && pending_data_) { |
| 215 size_t pending_data_read_save = pending_read_size_; | 215 size_t pending_data_read_save = pending_read_size_; |
| 216 pending_read_size_ = 0; | 216 pending_read_size_ = 0; |
| 217 | 217 |
| 218 // AddRef the stream while we call Read to avoid a potential issue | 218 // AddRef the stream while we call Read to avoid a potential issue |
| 219 // where we can get a call to OnDataAvailable while inside Read and | 219 // where we can get a call to OnDataAvailable while inside Read and |
| 220 // in our OnDataAvailable call, we can release the stream object | 220 // in our OnDataAvailable call, we can release the stream object |
| 221 // while still using it. | 221 // while still using it. |
| 222 ScopedComPtr<IStream> pending(pending_data_); | 222 base::win::ScopedComPtr<IStream> pending(pending_data_); |
| 223 HRESULT hr = ReadStream(pending, bytes_to_read, &read_data); | 223 HRESULT hr = ReadStream(pending, bytes_to_read, &read_data); |
| 224 if (read_data.empty()) | 224 if (read_data.empty()) |
| 225 pending_read_size_ = pending_data_read_save; | 225 pending_read_size_ = pending_data_read_save; |
| 226 // If we received S_FALSE it indicates that there is no more data in the | 226 // If we received S_FALSE it indicates that there is no more data in the |
| 227 // stream. Clear it to ensure that OnStopBinding correctly sends over the | 227 // stream. Clear it to ensure that OnStopBinding correctly sends over the |
| 228 // response end notification to chrome. | 228 // response end notification to chrome. |
| 229 if (hr == S_FALSE) | 229 if (hr == S_FALSE) |
| 230 pending_data_.Release(); | 230 pending_data_.Release(); |
| 231 } | 231 } |
| 232 | 232 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 if (status_text) { | 291 if (status_text) { |
| 292 socket_address_.set_host(WideToUTF8(status_text)); | 292 socket_address_.set_host(WideToUTF8(status_text)); |
| 293 } | 293 } |
| 294 break; | 294 break; |
| 295 } | 295 } |
| 296 | 296 |
| 297 case BINDSTATUS_REDIRECTING: { | 297 case BINDSTATUS_REDIRECTING: { |
| 298 // If we receive a redirect for the initial pending request initiated | 298 // If we receive a redirect for the initial pending request initiated |
| 299 // when our document loads we should stash it away and inform Chrome | 299 // when our document loads we should stash it away and inform Chrome |
| 300 // accordingly when it requests data for the original URL. | 300 // accordingly when it requests data for the original URL. |
| 301 ScopedComPtr<BindContextInfo> info; | 301 base::win::ScopedComPtr<BindContextInfo> info; |
| 302 BindContextInfo::FromBindContext(bind_context_, info.Receive()); | 302 BindContextInfo::FromBindContext(bind_context_, info.Receive()); |
| 303 DCHECK(info); | 303 DCHECK(info); |
| 304 GURL previously_redirected(info ? info->GetUrl() : std::wstring()); | 304 GURL previously_redirected(info ? info->GetUrl() : std::wstring()); |
| 305 if (GURL(status_text) != previously_redirected) { | 305 if (GURL(status_text) != previously_redirected) { |
| 306 DVLOG(1) << __FUNCTION__ << me() << "redirect from " << url() | 306 DVLOG(1) << __FUNCTION__ << me() << "redirect from " << url() |
| 307 << " to " << status_text; | 307 << " to " << status_text; |
| 308 // Fetch the redirect status as they aren't all equal (307 in particular | 308 // Fetch the redirect status as they aren't all equal (307 in particular |
| 309 // retains the HTTP request verb). | 309 // retains the HTTP request verb). |
| 310 int http_code = GetHttpResponseStatusFromBinding(binding_); | 310 int http_code = GetHttpResponseStatusFromBinding(binding_); |
| 311 status_.SetRedirected(http_code, WideToUTF8(status_text)); | 311 status_.SetRedirected(http_code, WideToUTF8(status_text)); |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 hr = ::CreateAsyncBindCtxEx(NULL, 0, this, NULL, | 798 hr = ::CreateAsyncBindCtxEx(NULL, 0, this, NULL, |
| 799 bind_context_.Receive(), 0); | 799 bind_context_.Receive(), 0); |
| 800 DCHECK(SUCCEEDED(hr)) << "CreateAsyncBindCtxEx failed. Error: " << hr; | 800 DCHECK(SUCCEEDED(hr)) << "CreateAsyncBindCtxEx failed. Error: " << hr; |
| 801 } else { | 801 } else { |
| 802 // Use existing bind context. | 802 // Use existing bind context. |
| 803 hr = ::RegisterBindStatusCallback(bind_context_, this, NULL, 0); | 803 hr = ::RegisterBindStatusCallback(bind_context_, this, NULL, 0); |
| 804 DCHECK(SUCCEEDED(hr)) << "RegisterBindStatusCallback failed. Error: " << hr; | 804 DCHECK(SUCCEEDED(hr)) << "RegisterBindStatusCallback failed. Error: " << hr; |
| 805 } | 805 } |
| 806 | 806 |
| 807 if (SUCCEEDED(hr)) { | 807 if (SUCCEEDED(hr)) { |
| 808 ScopedComPtr<IStream> stream; | 808 base::win::ScopedComPtr<IStream> stream; |
| 809 | 809 |
| 810 // BindToStorage may complete synchronously. | 810 // BindToStorage may complete synchronously. |
| 811 // We still get all the callbacks - OnStart/StopBinding, this may result | 811 // We still get all the callbacks - OnStart/StopBinding, this may result |
| 812 // in destruction of our object. It's fine but we access some members | 812 // in destruction of our object. It's fine but we access some members |
| 813 // below for debug info. :) | 813 // below for debug info. :) |
| 814 ScopedComPtr<IHttpSecurity> self(this); | 814 base::win::ScopedComPtr<IHttpSecurity> self(this); |
| 815 | 815 |
| 816 // Inform our moniker patch this binding should not be tortured. | 816 // Inform our moniker patch this binding should not be tortured. |
| 817 ScopedComPtr<BindContextInfo> info; | 817 base::win::ScopedComPtr<BindContextInfo> info; |
| 818 BindContextInfo::FromBindContext(bind_context_, info.Receive()); | 818 BindContextInfo::FromBindContext(bind_context_, info.Receive()); |
| 819 DCHECK(info); | 819 DCHECK(info); |
| 820 if (info) | 820 if (info) |
| 821 info->set_chrome_request(true); | 821 info->set_chrome_request(true); |
| 822 | 822 |
| 823 hr = moniker_->BindToStorage(bind_context_, NULL, __uuidof(IStream), | 823 hr = moniker_->BindToStorage(bind_context_, NULL, __uuidof(IStream), |
| 824 reinterpret_cast<void**>(stream.Receive())); | 824 reinterpret_cast<void**>(stream.Receive())); |
| 825 if (hr == S_OK) | 825 if (hr == S_OK) |
| 826 DCHECK(binding_ != NULL || status_.get_state() == Status::DONE); | 826 DCHECK(binding_ != NULL || status_.get_state() == Status::DONE); |
| 827 | 827 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 // We return INET_E_TERMINATED_BIND from our OnDataAvailable implementation | 864 // We return INET_E_TERMINATED_BIND from our OnDataAvailable implementation |
| 865 // to ensure that the transaction stays around if Chrome decides to issue | 865 // to ensure that the transaction stays around if Chrome decides to issue |
| 866 // a download request when it finishes inspecting the headers received in | 866 // a download request when it finishes inspecting the headers received in |
| 867 // OnResponse. However this causes the urlmon transaction object to leak. | 867 // OnResponse. However this causes the urlmon transaction object to leak. |
| 868 // To workaround this we save away the IInternetProtocol interface which is | 868 // To workaround this we save away the IInternetProtocol interface which is |
| 869 // implemented by the urlmon CTransaction object in our BindContextInfo | 869 // implemented by the urlmon CTransaction object in our BindContextInfo |
| 870 // instance which is maintained per bind context. Invoking Terminate | 870 // instance which is maintained per bind context. Invoking Terminate |
| 871 // on this with the special flags 0x2000000 cleanly releases the | 871 // on this with the special flags 0x2000000 cleanly releases the |
| 872 // transaction. | 872 // transaction. |
| 873 static const int kUrlmonTerminateTransactionFlags = 0x2000000; | 873 static const int kUrlmonTerminateTransactionFlags = 0x2000000; |
| 874 ScopedComPtr<BindContextInfo> info; | 874 base::win::ScopedComPtr<BindContextInfo> info; |
| 875 BindContextInfo::FromBindContext(bind_context_, info.Receive()); | 875 BindContextInfo::FromBindContext(bind_context_, info.Receive()); |
| 876 DCHECK(info); | 876 DCHECK(info); |
| 877 if (info && info->protocol()) { | 877 if (info && info->protocol()) { |
| 878 info->protocol()->Terminate(kUrlmonTerminateTransactionFlags); | 878 info->protocol()->Terminate(kUrlmonTerminateTransactionFlags); |
| 879 } | 879 } |
| 880 } | 880 } |
| 881 bind_context_.Release(); | 881 bind_context_.Release(); |
| 882 } | 882 } |
| 883 | 883 |
| 884 void UrlmonUrlRequest::ReleaseBindings() { | 884 void UrlmonUrlRequest::ReleaseBindings() { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 | 957 |
| 958 void UrlmonUrlRequestManager::SetInfoForUrl(const std::wstring& url, | 958 void UrlmonUrlRequestManager::SetInfoForUrl(const std::wstring& url, |
| 959 IMoniker* moniker, LPBC bind_ctx) { | 959 IMoniker* moniker, LPBC bind_ctx) { |
| 960 CComObject<UrlmonUrlRequest>* new_request = NULL; | 960 CComObject<UrlmonUrlRequest>* new_request = NULL; |
| 961 CComObject<UrlmonUrlRequest>::CreateInstance(&new_request); | 961 CComObject<UrlmonUrlRequest>::CreateInstance(&new_request); |
| 962 if (new_request) { | 962 if (new_request) { |
| 963 GURL start_url(url); | 963 GURL start_url(url); |
| 964 DCHECK(start_url.is_valid()); | 964 DCHECK(start_url.is_valid()); |
| 965 DCHECK(pending_request_ == NULL); | 965 DCHECK(pending_request_ == NULL); |
| 966 | 966 |
| 967 ScopedComPtr<BindContextInfo> info; | 967 base::win::ScopedComPtr<BindContextInfo> info; |
| 968 BindContextInfo::FromBindContext(bind_ctx, info.Receive()); | 968 BindContextInfo::FromBindContext(bind_ctx, info.Receive()); |
| 969 DCHECK(info); | 969 DCHECK(info); |
| 970 IStream* cache = info ? info->cache() : NULL; | 970 IStream* cache = info ? info->cache() : NULL; |
| 971 pending_request_ = new_request; | 971 pending_request_ = new_request; |
| 972 pending_request_->InitPending(start_url, moniker, bind_ctx, | 972 pending_request_->InitPending(start_url, moniker, bind_ctx, |
| 973 enable_frame_busting_, privileged_mode_, | 973 enable_frame_busting_, privileged_mode_, |
| 974 notification_window_, cache); | 974 notification_window_, cache); |
| 975 // Start the request | 975 // Start the request |
| 976 bool is_started = pending_request_->Start(); | 976 bool is_started = pending_request_->Start(); |
| 977 DCHECK(is_started); | 977 DCHECK(is_started); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 privacy_info_.privacy_records[UTF8ToWide(url)]; | 1257 privacy_info_.privacy_records[UTF8ToWide(url)]; |
| 1258 | 1258 |
| 1259 privacy_entry.flags |= flags; | 1259 privacy_entry.flags |= flags; |
| 1260 privacy_entry.policy_ref = UTF8ToWide(policy_ref); | 1260 privacy_entry.policy_ref = UTF8ToWide(policy_ref); |
| 1261 | 1261 |
| 1262 if (fire_privacy_event && IsWindow(notification_window_)) { | 1262 if (fire_privacy_event && IsWindow(notification_window_)) { |
| 1263 PostMessage(notification_window_, WM_FIRE_PRIVACY_CHANGE_NOTIFICATION, 1, | 1263 PostMessage(notification_window_, WM_FIRE_PRIVACY_CHANGE_NOTIFICATION, 1, |
| 1264 0); | 1264 0); |
| 1265 } | 1265 } |
| 1266 } | 1266 } |
| OLD | NEW |