OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <wininet.h> | 7 #include <wininet.h> |
8 #include <urlmon.h> | 8 #include <urlmon.h> |
9 | 9 |
10 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 cached_data_.Append(cache); | 131 cached_data_.Append(cache); |
132 | 132 |
133 // Request has already started and data is fetched. We will get the | 133 // Request has already started and data is fetched. We will get the |
134 // GetBindInfo call as per contract but the return values are | 134 // GetBindInfo call as per contract but the return values are |
135 // ignored. So just set "get" as a method to make our GetBindInfo | 135 // ignored. So just set "get" as a method to make our GetBindInfo |
136 // implementation happy. | 136 // implementation happy. |
137 method_ = "get"; | 137 method_ = "get"; |
138 return S_OK; | 138 return S_OK; |
139 } | 139 } |
140 | 140 |
141 void UrlmonUrlRequest::StealMoniker(IMoniker** moniker, IBindCtx** bctx) { | 141 void UrlmonUrlRequest::TerminateBind(TerminateBindCallback* callback) { |
142 // Could be called in any thread. There should be no race | 142 DCHECK_EQ(thread_, PlatformThread::CurrentId()); |
143 // since moniker_ is not released while we are in manager's request map. | |
144 DLOG(INFO) << __FUNCTION__ << " id: " << id(); | 143 DLOG(INFO) << __FUNCTION__ << " id: " << id(); |
145 DLOG_IF(WARNING, moniker == NULL) << __FUNCTION__ << " no moniker"; | 144 |
146 *moniker = moniker_.Detach(); | 145 if (status_.get_state() == Status::DONE) { |
147 *bctx = bind_context_.Detach(); | 146 // Binding is stopped. Note result could be an error. |
| 147 callback->Run(moniker_, bind_context_); |
| 148 delete callback; |
| 149 } else { |
| 150 // WORKING (ABORTING?). Save the callback. |
| 151 // Now we will return INET_TERMINATE_BIND from ::OnDataAvailable() and in |
| 152 // ::OnStopBinding will invoke the callback passing our moniker and |
| 153 // bind context. |
| 154 terminate_bind_callback_.reset(callback); |
| 155 } |
148 } | 156 } |
149 | 157 |
150 size_t UrlmonUrlRequest::SendDataToDelegate(size_t bytes_to_read) { | 158 size_t UrlmonUrlRequest::SendDataToDelegate(size_t bytes_to_read) { |
151 size_t bytes_copied = 0; | 159 size_t bytes_copied = 0; |
152 if (delegate_) { | 160 if (delegate_) { |
153 // We can optimize a bit by setting this string as a class member | 161 // We can optimize a bit by setting this string as a class member |
154 // and avoid frequent memory reallocations. | 162 // and avoid frequent memory reallocations. |
155 std::string data; | 163 std::string data; |
156 | 164 |
157 size_t bytes = std::min(static_cast<size_t>(bytes_to_read), | 165 size_t bytes = std::min(static_cast<size_t>(bytes_to_read), |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 DLOG(INFO) << StringPrintf("URL: %s Obj: %X", url().c_str(), this) << | 273 DLOG(INFO) << StringPrintf("URL: %s Obj: %X", url().c_str(), this) << |
266 " - Request stopped, Result: " << std::hex << result; | 274 " - Request stopped, Result: " << std::hex << result; |
267 DCHECK(status_.get_state() == Status::WORKING || | 275 DCHECK(status_.get_state() == Status::WORKING || |
268 status_.get_state() == Status::ABORTING); | 276 status_.get_state() == Status::ABORTING); |
269 | 277 |
270 Status::State state = status_.get_state(); | 278 Status::State state = status_.get_state(); |
271 | 279 |
272 // Mark we a are done. | 280 // Mark we a are done. |
273 status_.Done(); | 281 status_.Done(); |
274 | 282 |
| 283 if (result == INET_E_TERMINATED_BIND && terminate_requested()) { |
| 284 terminate_bind_callback_->Run(moniker_, bind_context_); |
| 285 } |
| 286 |
275 // We always return INET_E_TERMINATED_BIND from OnDataAvailable | 287 // We always return INET_E_TERMINATED_BIND from OnDataAvailable |
276 if (result == INET_E_TERMINATED_BIND) | 288 if (result == INET_E_TERMINATED_BIND) |
277 result = S_OK; | 289 result = S_OK; |
278 | 290 |
279 if (state == Status::WORKING) { | 291 if (state == Status::WORKING) { |
280 status_.set_result(result); | 292 status_.set_result(result); |
281 | 293 |
282 // Special case. If the last request was a redirect and the current OS | 294 // Special case. If the last request was a redirect and the current OS |
283 // error value is E_ACCESSDENIED, that means an unsafe redirect was | 295 // error value is E_ACCESSDENIED, that means an unsafe redirect was |
284 // attempted. In that case, correct the OS error value to be the more | 296 // attempted. In that case, correct the OS error value to be the more |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 401 |
390 return S_OK; | 402 return S_OK; |
391 } | 403 } |
392 | 404 |
393 STDMETHODIMP UrlmonUrlRequest::OnDataAvailable(DWORD flags, DWORD size, | 405 STDMETHODIMP UrlmonUrlRequest::OnDataAvailable(DWORD flags, DWORD size, |
394 FORMATETC* formatetc, | 406 FORMATETC* formatetc, |
395 STGMEDIUM* storage) { | 407 STGMEDIUM* storage) { |
396 DLOG(INFO) << StringPrintf("URL: %s Obj: %X - Bytes available: %d", | 408 DLOG(INFO) << StringPrintf("URL: %s Obj: %X - Bytes available: %d", |
397 url().c_str(), this, size); | 409 url().c_str(), this, size); |
398 | 410 |
| 411 if (terminate_requested()) |
| 412 return INET_E_TERMINATED_BIND; |
| 413 |
399 if (!storage || (storage->tymed != TYMED_ISTREAM)) { | 414 if (!storage || (storage->tymed != TYMED_ISTREAM)) { |
400 NOTREACHED(); | 415 NOTREACHED(); |
401 return E_INVALIDARG; | 416 return E_INVALIDARG; |
402 } | 417 } |
403 | 418 |
404 IStream* read_stream = storage->pstm; | 419 IStream* read_stream = storage->pstm; |
405 if (!read_stream) { | 420 if (!read_stream) { |
406 NOTREACHED(); | 421 NOTREACHED(); |
407 return E_UNEXPECTED; | 422 return E_UNEXPECTED; |
408 } | 423 } |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 if (request) { | 1033 if (request) { |
1019 request->Read(bytes_to_read); | 1034 request->Read(bytes_to_read); |
1020 } | 1035 } |
1021 } | 1036 } |
1022 | 1037 |
1023 void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { | 1038 void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { |
1024 DLOG(INFO) << __FUNCTION__ << " " << request_id; | 1039 DLOG(INFO) << __FUNCTION__ << " " << request_id; |
1025 if (IsWindow(notification_window_)) { | 1040 if (IsWindow(notification_window_)) { |
1026 scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id)); | 1041 scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id)); |
1027 if (request) { | 1042 if (request) { |
1028 ScopedComPtr<IMoniker> moniker; | 1043 UrlmonUrlRequest::TerminateBindCallback* callback = NewCallback(this, |
1029 ScopedComPtr<IBindCtx> bind_context; | 1044 &UrlmonUrlRequestManager::BindTerminated); |
1030 request->StealMoniker(moniker.Receive(), bind_context.Receive()); | 1045 request->TerminateBind(callback); |
1031 DLOG_IF(ERROR, moniker == NULL) << __FUNCTION__ << " No moniker!"; | |
1032 if (moniker) { | |
1033 // We use SendMessage and not PostMessage to make sure that if the | |
1034 // notification window does not handle the message we won't leak | |
1035 // the moniker. | |
1036 ::SendMessage(notification_window_, WM_DOWNLOAD_IN_HOST, | |
1037 reinterpret_cast<WPARAM>(bind_context.get()), | |
1038 reinterpret_cast<LPARAM>(moniker.get())); | |
1039 } | |
1040 } | 1046 } |
1041 } else { | 1047 } else { |
1042 NOTREACHED() | 1048 NOTREACHED() |
1043 << "Cannot handle download if we don't have anyone to hand it to."; | 1049 << "Cannot handle download if we don't have anyone to hand it to."; |
1044 } | 1050 } |
1045 } | 1051 } |
1046 | 1052 |
| 1053 void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker, |
| 1054 IBindCtx* bind_ctx) { |
| 1055 // We use SendMessage and not PostMessage to make sure that if the |
| 1056 // notification window does not handle the message we won't leak |
| 1057 // the moniker. |
| 1058 ::SendMessage(notification_window_, WM_DOWNLOAD_IN_HOST, |
| 1059 reinterpret_cast<WPARAM>(bind_ctx), |
| 1060 reinterpret_cast<LPARAM>(moniker)); |
| 1061 } |
| 1062 |
| 1063 |
1047 void UrlmonUrlRequestManager::GetCookiesForUrl(const GURL& url, int cookie_id) { | 1064 void UrlmonUrlRequestManager::GetCookiesForUrl(const GURL& url, int cookie_id) { |
1048 DWORD cookie_size = 0; | 1065 DWORD cookie_size = 0; |
1049 bool success = true; | 1066 bool success = true; |
1050 std::string cookie_string; | 1067 std::string cookie_string; |
1051 | 1068 |
1052 int32 cookie_action = COOKIEACTION_READ; | 1069 int32 cookie_action = COOKIEACTION_READ; |
1053 BOOL result = InternetGetCookieA(url.spec().c_str(), NULL, NULL, | 1070 BOOL result = InternetGetCookieA(url.spec().c_str(), NULL, NULL, |
1054 &cookie_size); | 1071 &cookie_size); |
1055 DWORD error = 0; | 1072 DWORD error = 0; |
1056 if (cookie_size) { | 1073 if (cookie_size) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 privacy_info_.privacy_records[UTF8ToWide(url)]; | 1228 privacy_info_.privacy_records[UTF8ToWide(url)]; |
1212 | 1229 |
1213 privacy_entry.flags |= flags; | 1230 privacy_entry.flags |= flags; |
1214 privacy_entry.policy_ref = UTF8ToWide(policy_ref); | 1231 privacy_entry.policy_ref = UTF8ToWide(policy_ref); |
1215 | 1232 |
1216 if (fire_privacy_event && IsWindow(notification_window_)) { | 1233 if (fire_privacy_event && IsWindow(notification_window_)) { |
1217 PostMessage(notification_window_, WM_FIRE_PRIVACY_CHANGE_NOTIFICATION, 1, | 1234 PostMessage(notification_window_, WM_FIRE_PRIVACY_CHANGE_NOTIFICATION, 1, |
1218 0); | 1235 0); |
1219 } | 1236 } |
1220 } | 1237 } |
OLD | NEW |