| 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 | 8 |
| 9 #include "base/scoped_ptr.h" | 9 #include "base/scoped_ptr.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "chrome_frame/chrome_frame_activex_base.h" | 13 #include "chrome_frame/chrome_frame_activex_base.h" |
| 14 #include "chrome_frame/extra_system_apis.h" |
| 14 #include "chrome_frame/html_utils.h" | 15 #include "chrome_frame/html_utils.h" |
| 15 #include "chrome_frame/urlmon_upload_data_stream.h" | 16 #include "chrome_frame/urlmon_upload_data_stream.h" |
| 16 #include "chrome_frame/utils.h" | 17 #include "chrome_frame/utils.h" |
| 17 #include "net/http/http_util.h" | 18 #include "net/http/http_util.h" |
| 18 #include "net/http/http_response_headers.h" | 19 #include "net/http/http_response_headers.h" |
| 19 | 20 |
| 20 static const LARGE_INTEGER kZero = {0}; | 21 static const LARGE_INTEGER kZero = {0}; |
| 21 static const ULARGE_INTEGER kUnsignedZero = {0}; | 22 static const ULARGE_INTEGER kUnsignedZero = {0}; |
| 22 int UrlmonUrlRequest::instance_count_ = 0; | 23 int UrlmonUrlRequest::instance_count_ = 0; |
| 23 | 24 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 NOTREACHED() << __FUNCTION__ << " Urlmon request thread not initialized"; | 126 NOTREACHED() << __FUNCTION__ << " Urlmon request thread not initialized"; |
| 126 return false; | 127 return false; |
| 127 } | 128 } |
| 128 | 129 |
| 129 worker_thread_->message_loop()->PostTask( | 130 worker_thread_->message_loop()->PostTask( |
| 130 FROM_HERE, NewRunnableMethod(this, &UrlmonUrlRequest::ReadAsync, | 131 FROM_HERE, NewRunnableMethod(this, &UrlmonUrlRequest::ReadAsync, |
| 131 bytes_to_read)); | 132 bytes_to_read)); |
| 132 return true; | 133 return true; |
| 133 } | 134 } |
| 134 | 135 |
| 136 void UrlmonUrlRequest::TransferToHost(IUnknown* host) { |
| 137 DCHECK_EQ(PlatformThread::CurrentId(), thread_); |
| 138 DCHECK(host); |
| 139 |
| 140 DCHECK(moniker_); |
| 141 if (!moniker_) |
| 142 return; |
| 143 |
| 144 ScopedComPtr<IMoniker> moniker; |
| 145 moniker.Attach(moniker_.Detach()); |
| 146 |
| 147 // Create a new bind context that's not associated with our callback. |
| 148 // Calling RevokeBindStatusCallback doesn't disassociate the callback with |
| 149 // the bind context in IE7. The returned bind context has the same |
| 150 // implementation of GetRunningObjectTable as the bind context we held which |
| 151 // basically delegates to ole32's GetRunningObjectTable. The object table |
| 152 // is then used to determine if the moniker is already running and via |
| 153 // that mechanism is associated with the same internet request as has already |
| 154 // been issued. |
| 155 ScopedComPtr<IBindCtx> bind_context; |
| 156 CreateBindCtx(0, bind_context.Receive()); |
| 157 DCHECK(bind_context); |
| 158 |
| 159 LPOLESTR url = NULL; |
| 160 if (SUCCEEDED(moniker->GetDisplayName(bind_context, NULL, &url))) { |
| 161 DLOG(INFO) << __FUNCTION__ << " " << url; |
| 162 |
| 163 // TODO(tommi): See if we can get HlinkSimpleNavigateToMoniker to work |
| 164 // instead. Looks like we'll need to support IHTMLDocument2 (get_URL in |
| 165 // particular), access to IWebBrowser2 etc. |
| 166 // HlinkSimpleNavigateToMoniker(moniker, url, NULL, host, bind_context, |
| 167 // NULL, 0, 0); |
| 168 |
| 169 ScopedComPtr<IWebBrowser2> wb2; |
| 170 HRESULT hr = DoQueryService(SID_SWebBrowserApp, host, wb2.Receive()); |
| 171 DCHECK(wb2); |
| 172 DLOG_IF(WARNING, FAILED(hr)) << StringPrintf(L"SWebBrowserApp 0x%08X", hr); |
| 173 |
| 174 ScopedComPtr<IWebBrowserPriv> wbp; |
| 175 ScopedComPtr<IWebBrowserPriv2IE7> wbp2_ie7; |
| 176 ScopedComPtr<IWebBrowserPriv2IE8> wbp2_ie8; |
| 177 if (SUCCEEDED(hr = wbp.QueryFrom(wb2))) { |
| 178 ScopedVariant var_url(url); |
| 179 hr = wbp->NavigateWithBindCtx(var_url.AsInput(), NULL, NULL, NULL, NULL, |
| 180 bind_context, NULL); |
| 181 DLOG_IF(WARNING, FAILED(hr)) |
| 182 << StringPrintf(L"NavigateWithBindCtx 0x%08X", hr); |
| 183 } else { |
| 184 DLOG(WARNING) << StringPrintf(L"IWebBrowserPriv 0x%08X", hr); |
| 185 IWebBrowserPriv2IE7* common_wbp2 = NULL; |
| 186 if (SUCCEEDED(hr = wbp2_ie7.QueryFrom(wb2))) { |
| 187 common_wbp2 = wbp2_ie7; |
| 188 } else if (SUCCEEDED(hr = wbp2_ie8.QueryFrom(wb2))) { |
| 189 common_wbp2 = reinterpret_cast<IWebBrowserPriv2IE7*>(wbp2_ie8.get()); |
| 190 } |
| 191 |
| 192 if (common_wbp2) { |
| 193 typedef HRESULT (WINAPI* CreateUriFn)(LPCWSTR uri, DWORD flags, |
| 194 DWORD_PTR reserved, IUri** ret); |
| 195 |
| 196 CreateUriFn create_uri = reinterpret_cast<CreateUriFn>( |
| 197 ::GetProcAddress(::GetModuleHandleA("urlmon"), "CreateUri")); |
| 198 DCHECK(create_uri); |
| 199 if (create_uri) { |
| 200 ScopedComPtr<IUri> uri_obj; |
| 201 hr = create_uri(url, 0, 0, uri_obj.Receive()); |
| 202 DLOG_IF(WARNING, FAILED(hr)) |
| 203 << StringPrintf(L"create_uri 0x%08X", hr); |
| 204 hr = common_wbp2->NavigateWithBindCtx2(uri_obj, NULL, NULL, NULL, |
| 205 NULL, bind_context, NULL); |
| 206 DLOG_IF(WARNING, FAILED(hr)) |
| 207 << StringPrintf(L"NavigateWithBindCtx2 0x%08X", hr); |
| 208 } |
| 209 } else { |
| 210 DLOG(WARNING) << StringPrintf(L"IWebBrowserPriv2 0x%08X", hr); |
| 211 NOTREACHED(); |
| 212 } |
| 213 } |
| 214 |
| 215 DCHECK(wbp || wbp2_ie7 || wbp2_ie8); |
| 216 |
| 217 ::CoTaskMemFree(url); |
| 218 } |
| 219 } |
| 220 |
| 135 void UrlmonUrlRequest::ReadAsync(int bytes_to_read) { | 221 void UrlmonUrlRequest::ReadAsync(int bytes_to_read) { |
| 136 // Send cached data if available. | 222 // Send cached data if available. |
| 137 CComObjectStackEx<SendStream> send_stream; | 223 CComObjectStackEx<SendStream> send_stream; |
| 138 send_stream.Initialize(this); | 224 send_stream.Initialize(this); |
| 139 | 225 |
| 140 size_t bytes_copied = 0; | 226 size_t bytes_copied = 0; |
| 141 if (cached_data_.is_valid() && cached_data_.Read(&send_stream, bytes_to_read, | 227 if (cached_data_.is_valid() && cached_data_.Read(&send_stream, bytes_to_read, |
| 142 &bytes_copied)) { | 228 &bytes_copied)) { |
| 143 DLOG(INFO) << StringPrintf("URL: %s Obj: %X - bytes read from cache: %d", | 229 DLOG(INFO) << StringPrintf("URL: %s Obj: %X - bytes read from cache: %d", |
| 144 url().c_str(), this, bytes_copied); | 230 url().c_str(), this, bytes_copied); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 EndRequest(); | 314 EndRequest(); |
| 229 } else { | 315 } else { |
| 230 status_.set_status(URLRequestStatus::SUCCESS); | 316 status_.set_status(URLRequestStatus::SUCCESS); |
| 231 status_.set_os_error(0); | 317 status_.set_os_error(0); |
| 232 } | 318 } |
| 233 | 319 |
| 234 DLOG(INFO) << "OnStopBinding received for request id: " << id(); | 320 DLOG(INFO) << "OnStopBinding received for request id: " << id(); |
| 235 | 321 |
| 236 // Release these variables after reporting EndRequest since we might need to | 322 // Release these variables after reporting EndRequest since we might need to |
| 237 // access their state. | 323 // access their state. |
| 238 binding_ = NULL; | 324 binding_.Release(); |
| 239 bind_context_ = NULL; | 325 if (bind_context_) { |
| 326 ::RevokeBindStatusCallback(bind_context_, this); |
| 327 bind_context_.Release(); |
| 328 } |
| 240 | 329 |
| 241 return S_OK; | 330 return S_OK; |
| 242 } | 331 } |
| 243 | 332 |
| 244 STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags, | 333 STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags, |
| 245 BINDINFO *bind_info) { | 334 BINDINFO *bind_info) { |
| 246 DCHECK(worker_thread_ != NULL); | 335 DCHECK(worker_thread_ != NULL); |
| 247 DCHECK_EQ(PlatformThread::CurrentId(), worker_thread_->thread_id()); | 336 DCHECK_EQ(PlatformThread::CurrentId(), worker_thread_->thread_id()); |
| 248 | 337 |
| 249 if ((bind_info == NULL) || (bind_info->cbSize == 0) || (bind_flags == NULL)) | 338 if ((bind_info == NULL) || (bind_info->cbSize == 0) || (bind_flags == NULL)) |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 ret = net::ERR_ACCESS_DENIED; | 966 ret = net::ERR_ACCESS_DENIED; |
| 878 break; | 967 break; |
| 879 | 968 |
| 880 default: | 969 default: |
| 881 DLOG(WARNING) | 970 DLOG(WARNING) |
| 882 << StringPrintf("TODO: translate HRESULT 0x%08X to net::Error", hr); | 971 << StringPrintf("TODO: translate HRESULT 0x%08X to net::Error", hr); |
| 883 break; | 972 break; |
| 884 } | 973 } |
| 885 return ret; | 974 return ret; |
| 886 } | 975 } |
| OLD | NEW |