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