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 |