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 <urlmon.h> |
8 #include <wininet.h> | 8 #include <wininet.h> |
9 | 9 |
10 #include "base/callback_old.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
14 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
15 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
16 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
17 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
18 #include "chrome/common/automation_messages.h" | 19 #include "chrome/common/automation_messages.h" |
19 #include "chrome_frame/bind_context_info.h" | 20 #include "chrome_frame/bind_context_info.h" |
20 #include "chrome_frame/chrome_frame_activex_base.h" | 21 #include "chrome_frame/chrome_frame_activex_base.h" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 set_pending(true); | 156 set_pending(true); |
156 | 157 |
157 // Request has already started and data is fetched. We will get the | 158 // Request has already started and data is fetched. We will get the |
158 // GetBindInfo call as per contract but the return values are | 159 // GetBindInfo call as per contract but the return values are |
159 // ignored. So just set "get" as a method to make our GetBindInfo | 160 // ignored. So just set "get" as a method to make our GetBindInfo |
160 // implementation happy. | 161 // implementation happy. |
161 method_ = "get"; | 162 method_ = "get"; |
162 return S_OK; | 163 return S_OK; |
163 } | 164 } |
164 | 165 |
165 void UrlmonUrlRequest::TerminateBind(TerminateBindCallback* callback) { | 166 void UrlmonUrlRequest::TerminateBind(const TerminateBindCallback& callback) { |
166 DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); | 167 DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); |
167 DVLOG(1) << __FUNCTION__ << me(); | 168 DVLOG(1) << __FUNCTION__ << me(); |
168 cleanup_transaction_ = false; | 169 cleanup_transaction_ = false; |
169 if (status_.get_state() == Status::DONE) { | 170 if (status_.get_state() == Status::DONE) { |
170 // Binding is stopped. Note result could be an error. | 171 // Binding is stopped. Note result could be an error. |
171 callback->Run(moniker_, bind_context_, upload_data_, | 172 callback.Run(moniker_, bind_context_, upload_data_, |
172 request_headers_.c_str()); | 173 request_headers_.c_str()); |
173 delete callback; | |
174 } else { | 174 } else { |
175 // WORKING (ABORTING?). Save the callback. | 175 // WORKING (ABORTING?). Save the callback. |
176 // Now we will return INET_TERMINATE_BIND from ::OnDataAvailable() and in | 176 // Now we will return INET_TERMINATE_BIND from ::OnDataAvailable() and in |
177 // ::OnStopBinding will invoke the callback passing our moniker and | 177 // ::OnStopBinding will invoke the callback passing our moniker and |
178 // bind context. | 178 // bind context. |
179 terminate_bind_callback_.reset(callback); | 179 terminate_bind_callback_ = callback; |
180 if (pending_data_) { | 180 if (pending_data_) { |
181 // For downloads to work correctly, we must induce a call to | 181 // For downloads to work correctly, we must induce a call to |
182 // OnDataAvailable so that we can download INET_E_TERMINATED_BIND and | 182 // OnDataAvailable so that we can download INET_E_TERMINATED_BIND and |
183 // get IE into the correct state. | 183 // get IE into the correct state. |
184 // To accomplish this we read everything that's readily available in | 184 // To accomplish this we read everything that's readily available in |
185 // the current stream. Once we've reached the end of the stream we | 185 // the current stream. Once we've reached the end of the stream we |
186 // should get E_PENDING back and then later we'll get that call | 186 // should get E_PENDING back and then later we'll get that call |
187 // to OnDataAvailable. | 187 // to OnDataAvailable. |
188 std::string data; | 188 std::string data; |
189 base::win::ScopedComPtr<IStream> read_stream(pending_data_); | 189 base::win::ScopedComPtr<IStream> read_stream(pending_data_); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 DCHECK(status_.get_state() == Status::WORKING || | 362 DCHECK(status_.get_state() == Status::WORKING || |
363 status_.get_state() == Status::ABORTING); | 363 status_.get_state() == Status::ABORTING); |
364 | 364 |
365 Status::State state = status_.get_state(); | 365 Status::State state = status_.get_state(); |
366 | 366 |
367 // Mark we a are done. | 367 // Mark we a are done. |
368 status_.Done(); | 368 status_.Done(); |
369 | 369 |
370 if (result == INET_E_TERMINATED_BIND) { | 370 if (result == INET_E_TERMINATED_BIND) { |
371 if (terminate_requested()) { | 371 if (terminate_requested()) { |
372 terminate_bind_callback_->Run(moniker_, bind_context_, upload_data_, | 372 terminate_bind_callback_.Run(moniker_, bind_context_, upload_data_, |
373 request_headers_.c_str()); | 373 request_headers_.c_str()); |
374 } else { | 374 } else { |
375 cleanup_transaction_ = true; | 375 cleanup_transaction_ = true; |
376 } | 376 } |
377 // We may have returned INET_E_TERMINATED_BIND from OnDataAvailable. | 377 // We may have returned INET_E_TERMINATED_BIND from OnDataAvailable. |
378 result = S_OK; | 378 result = S_OK; |
379 } | 379 } |
380 | 380 |
381 if (state == Status::WORKING) { | 381 if (state == Status::WORKING) { |
382 status_.set_result(result); | 382 status_.set_result(result); |
383 | 383 |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 // Non frame requests like sub resources, images, etc are handled on the | 1013 // Non frame requests like sub resources, images, etc are handled on the |
1014 // background thread. | 1014 // background thread. |
1015 if (background_worker_thread_enabled_ && | 1015 if (background_worker_thread_enabled_ && |
1016 !ResourceType::IsFrame( | 1016 !ResourceType::IsFrame( |
1017 static_cast<ResourceType::Type>(request_info.resource_type))) { | 1017 static_cast<ResourceType::Type>(request_info.resource_type))) { |
1018 DLOG(INFO) << "Downloading resource type " | 1018 DLOG(INFO) << "Downloading resource type " |
1019 << request_info.resource_type | 1019 << request_info.resource_type |
1020 << " on background thread"; | 1020 << " on background thread"; |
1021 background_thread_->message_loop()->PostTask( | 1021 background_thread_->message_loop()->PostTask( |
1022 FROM_HERE, | 1022 FROM_HERE, |
1023 NewRunnableMethod(this, &UrlmonUrlRequestManager::StartRequestHelper, | 1023 base::Bind(&UrlmonUrlRequestManager::StartRequestHelper, |
1024 request_id, request_info, &background_request_map_, | 1024 base::Unretained(this), request_id, request_info, |
1025 &background_resource_map_lock_)); | 1025 &background_request_map_, &background_resource_map_lock_)); |
1026 return; | 1026 return; |
1027 } | 1027 } |
1028 StartRequestHelper(request_id, request_info, &request_map_, NULL); | 1028 StartRequestHelper(request_id, request_info, &request_map_, NULL); |
1029 } | 1029 } |
1030 | 1030 |
1031 void UrlmonUrlRequestManager::StartRequestHelper( | 1031 void UrlmonUrlRequestManager::StartRequestHelper( |
1032 int request_id, | 1032 int request_id, |
1033 const AutomationURLRequest& request_info, | 1033 const AutomationURLRequest& request_info, |
1034 RequestMap* request_map, | 1034 RequestMap* request_map, |
1035 base::Lock* request_map_lock) { | 1035 base::Lock* request_map_lock) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 // network error. | 1099 // network error. |
1100 scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, | 1100 scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, |
1101 &request_map_); | 1101 &request_map_); |
1102 if (request) { | 1102 if (request) { |
1103 request->Read(bytes_to_read); | 1103 request->Read(bytes_to_read); |
1104 } else if (background_worker_thread_enabled_) { | 1104 } else if (background_worker_thread_enabled_) { |
1105 base::AutoLock lock(background_resource_map_lock_); | 1105 base::AutoLock lock(background_resource_map_lock_); |
1106 request = LookupRequest(request_id, &background_request_map_); | 1106 request = LookupRequest(request_id, &background_request_map_); |
1107 if (request) { | 1107 if (request) { |
1108 background_thread_->message_loop()->PostTask( | 1108 background_thread_->message_loop()->PostTask( |
1109 FROM_HERE, | 1109 FROM_HERE, base::IgnoreReturn<bool>(base::Bind( |
1110 NewRunnableMethod(request.get(), | 1110 &UrlmonUrlRequest::Read, request.get(), bytes_to_read))); |
1111 &UrlmonUrlRequest::Read, bytes_to_read)); | |
1112 } | 1111 } |
1113 } | 1112 } |
1114 if (!request) | 1113 if (!request) |
1115 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; | 1114 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; |
1116 } | 1115 } |
1117 | 1116 |
1118 void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { | 1117 void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { |
1119 DVLOG(1) << __FUNCTION__ << " " << request_id; | 1118 DVLOG(1) << __FUNCTION__ << " " << request_id; |
1120 if (!IsWindow(notification_window_)) { | 1119 if (!IsWindow(notification_window_)) { |
1121 NOTREACHED() << "Cannot handle download if we don't have anyone to hand it " | 1120 NOTREACHED() << "Cannot handle download if we don't have anyone to hand it " |
1122 "to."; | 1121 "to."; |
1123 return; | 1122 return; |
1124 } | 1123 } |
1125 | 1124 |
1126 scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id, | 1125 scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id, |
1127 &request_map_)); | 1126 &request_map_)); |
1128 if (request) { | 1127 if (request) { |
1129 DownloadRequestInHostHelper(request); | 1128 DownloadRequestInHostHelper(request); |
1130 } else if (background_worker_thread_enabled_) { | 1129 } else if (background_worker_thread_enabled_) { |
1131 base::AutoLock lock(background_resource_map_lock_); | 1130 base::AutoLock lock(background_resource_map_lock_); |
1132 request = LookupRequest(request_id, &background_request_map_); | 1131 request = LookupRequest(request_id, &background_request_map_); |
1133 if (request) { | 1132 if (request) { |
1134 background_thread_->message_loop()->PostTask( | 1133 background_thread_->message_loop()->PostTask( |
1135 FROM_HERE, | 1134 FROM_HERE, |
1136 NewRunnableMethod( | 1135 base::Bind(&UrlmonUrlRequestManager::DownloadRequestInHostHelper, |
1137 this, | 1136 base::Unretained(this), request.get())); |
1138 &UrlmonUrlRequestManager::DownloadRequestInHostHelper, | |
1139 request.get())); | |
1140 } | 1137 } |
1141 } | 1138 } |
1142 if (!request) | 1139 if (!request) |
1143 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; | 1140 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; |
1144 } | 1141 } |
1145 | 1142 |
1146 void UrlmonUrlRequestManager::DownloadRequestInHostHelper( | 1143 void UrlmonUrlRequestManager::DownloadRequestInHostHelper( |
1147 UrlmonUrlRequest* request) { | 1144 UrlmonUrlRequest* request) { |
1148 DCHECK(request); | 1145 DCHECK(request); |
1149 UrlmonUrlRequest::TerminateBindCallback* callback = NewCallback(this, | 1146 UrlmonUrlRequest::TerminateBindCallback callback = |
1150 &UrlmonUrlRequestManager::BindTerminated); | 1147 base::Bind(&UrlmonUrlRequestManager::BindTerminated, |
| 1148 base::Unretained(this)); |
1151 request->TerminateBind(callback); | 1149 request->TerminateBind(callback); |
1152 } | 1150 } |
1153 | 1151 |
1154 void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker, | 1152 void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker, |
1155 IBindCtx* bind_ctx, | 1153 IBindCtx* bind_ctx, |
1156 IStream* post_data, | 1154 IStream* post_data, |
1157 const char* request_headers) { | 1155 const char* request_headers) { |
1158 DownloadInHostParams* download_params = new DownloadInHostParams; | 1156 DownloadInHostParams* download_params = new DownloadInHostParams; |
1159 download_params->bind_ctx = bind_ctx; | 1157 download_params->bind_ctx = bind_ctx; |
1160 download_params->moniker = moniker; | 1158 download_params->moniker = moniker; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 &request_map_); | 1224 &request_map_); |
1227 if (request) { | 1225 if (request) { |
1228 request_map_.erase(request_id); | 1226 request_map_.erase(request_id); |
1229 request->Stop(); | 1227 request->Stop(); |
1230 } else if (background_worker_thread_enabled_) { | 1228 } else if (background_worker_thread_enabled_) { |
1231 base::AutoLock lock(background_resource_map_lock_); | 1229 base::AutoLock lock(background_resource_map_lock_); |
1232 request = LookupRequest(request_id, &background_request_map_); | 1230 request = LookupRequest(request_id, &background_request_map_); |
1233 if (request) { | 1231 if (request) { |
1234 background_request_map_.erase(request_id); | 1232 background_request_map_.erase(request_id); |
1235 background_thread_->message_loop()->PostTask( | 1233 background_thread_->message_loop()->PostTask( |
1236 FROM_HERE, | 1234 FROM_HERE, base::Bind(&UrlmonUrlRequest::Stop, request.get())); |
1237 NewRunnableMethod(request.get(), &UrlmonUrlRequest::Stop)); | |
1238 } | 1235 } |
1239 } | 1236 } |
1240 if (!request) | 1237 if (!request) |
1241 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; | 1238 DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; |
1242 } | 1239 } |
1243 | 1240 |
1244 void UrlmonUrlRequestManager::StopAll() { | 1241 void UrlmonUrlRequestManager::StopAll() { |
1245 DVLOG(1) << __FUNCTION__; | 1242 DVLOG(1) << __FUNCTION__; |
1246 if (stopping_) | 1243 if (stopping_) |
1247 return; | 1244 return; |
1248 | 1245 |
1249 stopping_ = true; | 1246 stopping_ = true; |
1250 | 1247 |
1251 DVLOG(1) << __FUNCTION__ << " stopping " << request_map_.size() | 1248 DVLOG(1) << __FUNCTION__ << " stopping " << request_map_.size() |
1252 << " requests"; | 1249 << " requests"; |
1253 | 1250 |
1254 StopAllRequestsHelper(&request_map_, NULL); | 1251 StopAllRequestsHelper(&request_map_, NULL); |
1255 | 1252 |
1256 if (background_worker_thread_enabled_) { | 1253 if (background_worker_thread_enabled_) { |
1257 DCHECK(background_thread_.get()); | 1254 DCHECK(background_thread_.get()); |
1258 background_thread_->message_loop()->PostTask( | 1255 background_thread_->message_loop()->PostTask( |
1259 FROM_HERE, | 1256 FROM_HERE, base::Bind(&UrlmonUrlRequestManager::StopAllRequestsHelper, |
1260 NewRunnableMethod( | 1257 base::Unretained(this), &background_request_map_, |
1261 this, &UrlmonUrlRequestManager::StopAllRequestsHelper, | 1258 &background_resource_map_lock_)); |
1262 &background_request_map_, &background_resource_map_lock_)); | |
1263 background_thread_->Stop(); | 1259 background_thread_->Stop(); |
1264 background_thread_.reset(); | 1260 background_thread_.reset(); |
1265 } | 1261 } |
1266 } | 1262 } |
1267 | 1263 |
1268 void UrlmonUrlRequestManager::StopAllRequestsHelper( | 1264 void UrlmonUrlRequestManager::StopAllRequestsHelper( |
1269 RequestMap* request_map, | 1265 RequestMap* request_map, |
1270 base::Lock* request_map_lock) { | 1266 base::Lock* request_map_lock) { |
1271 DCHECK(request_map); | 1267 DCHECK(request_map); |
1272 | 1268 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 } | 1412 } |
1417 | 1413 |
1418 void UrlmonUrlRequestManager::ResourceFetcherThread::Init() { | 1414 void UrlmonUrlRequestManager::ResourceFetcherThread::Init() { |
1419 CoInitialize(NULL); | 1415 CoInitialize(NULL); |
1420 } | 1416 } |
1421 | 1417 |
1422 void UrlmonUrlRequestManager::ResourceFetcherThread::CleanUp() { | 1418 void UrlmonUrlRequestManager::ResourceFetcherThread::CleanUp() { |
1423 CoUninitialize(); | 1419 CoUninitialize(); |
1424 } | 1420 } |
1425 | 1421 |
OLD | NEW |