| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 // This file contains an implementation of the ResourceLoaderBridge class. | 5 // This file contains an implementation of the ResourceLoaderBridge class. |
| 6 // The class is implemented using URLRequest, meaning it is a "simple" version | 6 // The class is implemented using URLRequest, meaning it is a "simple" version |
| 7 // that directly issues requests. The more complicated one used in the | 7 // that directly issues requests. The more complicated one used in the |
| 8 // browser uses IPC. | 8 // browser uses IPC. |
| 9 // | 9 // |
| 10 // Because URLRequest only provides an asynchronous resource loading API, this | 10 // Because URLRequest only provides an asynchronous resource loading API, this |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 // perform URL loads. See renderer/resource_dispatcher.h for details on an | 30 // perform URL loads. See renderer/resource_dispatcher.h for details on an |
| 31 // alternate implementation that defers fetching to another process. | 31 // alternate implementation that defers fetching to another process. |
| 32 | 32 |
| 33 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" | 33 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" |
| 34 | 34 |
| 35 #include "base/message_loop.h" | 35 #include "base/message_loop.h" |
| 36 #include "base/ref_counted.h" | 36 #include "base/ref_counted.h" |
| 37 #include "base/thread.h" | 37 #include "base/thread.h" |
| 38 #include "base/waitable_event.h" | 38 #include "base/waitable_event.h" |
| 39 #include "net/base/cookie_monster.h" | 39 #include "net/base/cookie_monster.h" |
| 40 #include "net/base/io_buffer.h" |
| 40 #include "net/base/net_util.h" | 41 #include "net/base/net_util.h" |
| 41 #include "net/base/upload_data.h" | 42 #include "net/base/upload_data.h" |
| 42 #include "net/url_request/url_request.h" | 43 #include "net/url_request/url_request.h" |
| 43 #include "webkit/glue/resource_loader_bridge.h" | 44 #include "webkit/glue/resource_loader_bridge.h" |
| 44 #include "webkit/tools/test_shell/test_shell_request_context.h" | 45 #include "webkit/tools/test_shell/test_shell_request_context.h" |
| 45 | 46 |
| 46 using webkit_glue::ResourceLoaderBridge; | 47 using webkit_glue::ResourceLoaderBridge; |
| 47 using net::HttpResponseHeaders; | 48 using net::HttpResponseHeaders; |
| 48 | 49 |
| 49 namespace { | 50 namespace { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 scoped_refptr<net::UploadData> upload; | 98 scoped_refptr<net::UploadData> upload; |
| 98 }; | 99 }; |
| 99 | 100 |
| 100 // The RequestProxy does most of its work on the IO thread. The Start and | 101 // The RequestProxy does most of its work on the IO thread. The Start and |
| 101 // Cancel methods are proxied over to the IO thread, where an URLRequest object | 102 // Cancel methods are proxied over to the IO thread, where an URLRequest object |
| 102 // is instantiated. | 103 // is instantiated. |
| 103 class RequestProxy : public URLRequest::Delegate, | 104 class RequestProxy : public URLRequest::Delegate, |
| 104 public base::RefCountedThreadSafe<RequestProxy> { | 105 public base::RefCountedThreadSafe<RequestProxy> { |
| 105 public: | 106 public: |
| 106 // Takes ownership of the params. | 107 // Takes ownership of the params. |
| 107 RequestProxy() { | 108 RequestProxy() : buf_(new net::IOBuffer(kDataSize)) { |
| 108 } | 109 } |
| 109 | 110 |
| 110 virtual ~RequestProxy() { | 111 virtual ~RequestProxy() { |
| 111 // If we have a request, then we'd better be on the io thread! | 112 // If we have a request, then we'd better be on the io thread! |
| 112 DCHECK(!request_.get() || | 113 DCHECK(!request_.get() || |
| 113 MessageLoop::current() == io_thread->message_loop()); | 114 MessageLoop::current() == io_thread->message_loop()); |
| 114 } | 115 } |
| 115 | 116 |
| 116 void DropPeer() { | 117 void DropPeer() { |
| 117 peer_ = NULL; | 118 peer_ = NULL; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 148 if (peer_) | 149 if (peer_) |
| 149 peer_->OnReceivedResponse(info, content_filtered); | 150 peer_->OnReceivedResponse(info, content_filtered); |
| 150 } | 151 } |
| 151 | 152 |
| 152 void NotifyReceivedData(int bytes_read) { | 153 void NotifyReceivedData(int bytes_read) { |
| 153 if (!peer_) | 154 if (!peer_) |
| 154 return; | 155 return; |
| 155 | 156 |
| 156 // Make a local copy of buf_, since AsyncReadData reuses it. | 157 // Make a local copy of buf_, since AsyncReadData reuses it. |
| 157 scoped_array<char> buf_copy(new char[bytes_read]); | 158 scoped_array<char> buf_copy(new char[bytes_read]); |
| 158 memcpy(buf_copy.get(), buf_, bytes_read); | 159 memcpy(buf_copy.get(), buf_->data(), bytes_read); |
| 159 | 160 |
| 160 // Continue reading more data into buf_ | 161 // Continue reading more data into buf_ |
| 161 // Note: Doing this before notifying our peer ensures our load events get | 162 // Note: Doing this before notifying our peer ensures our load events get |
| 162 // dispatched in a manner consistent with DumpRenderTree (and also avoids a | 163 // dispatched in a manner consistent with DumpRenderTree (and also avoids a |
| 163 // race condition). If the order of the next 2 functions were reversed, the | 164 // race condition). If the order of the next 2 functions were reversed, the |
| 164 // peer could generate new requests in reponse to the received data, which | 165 // peer could generate new requests in reponse to the received data, which |
| 165 // when run on the io thread, could race against this function in doing | 166 // when run on the io thread, could race against this function in doing |
| 166 // another InvokeLater. See bug 769249. | 167 // another InvokeLater. See bug 769249. |
| 167 io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 168 io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 168 this, &RequestProxy::AsyncReadData)); | 169 this, &RequestProxy::AsyncReadData)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 Done(); | 205 Done(); |
| 205 } | 206 } |
| 206 | 207 |
| 207 void AsyncReadData() { | 208 void AsyncReadData() { |
| 208 // This can be null in cases where the request is already done. | 209 // This can be null in cases where the request is already done. |
| 209 if (!request_.get()) | 210 if (!request_.get()) |
| 210 return; | 211 return; |
| 211 | 212 |
| 212 if (request_->status().is_success()) { | 213 if (request_->status().is_success()) { |
| 213 int bytes_read; | 214 int bytes_read; |
| 214 if (request_->Read(buf_, sizeof(buf_), &bytes_read) && bytes_read) { | 215 if (request_->Read(buf_, kDataSize, &bytes_read) && bytes_read) { |
| 215 OnReceivedData(bytes_read); | 216 OnReceivedData(bytes_read); |
| 216 } else if (!request_->status().is_io_pending()) { | 217 } else if (!request_->status().is_io_pending()) { |
| 217 Done(); | 218 Done(); |
| 218 } // else wait for OnReadCompleted | 219 } // else wait for OnReadCompleted |
| 219 } else { | 220 } else { |
| 220 Done(); | 221 Done(); |
| 221 } | 222 } |
| 222 } | 223 } |
| 223 | 224 |
| 224 // -------------------------------------------------------------------------- | 225 // -------------------------------------------------------------------------- |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 OnCompletedRequest(request_->status()); | 290 OnCompletedRequest(request_->status()); |
| 290 request_.reset(); // destroy on the io thread | 291 request_.reset(); // destroy on the io thread |
| 291 } | 292 } |
| 292 | 293 |
| 293 scoped_ptr<URLRequest> request_; | 294 scoped_ptr<URLRequest> request_; |
| 294 | 295 |
| 295 // Size of our async IO data buffers | 296 // Size of our async IO data buffers |
| 296 static const int kDataSize = 16*1024; | 297 static const int kDataSize = 16*1024; |
| 297 | 298 |
| 298 // read buffer for async IO | 299 // read buffer for async IO |
| 299 char buf_[kDataSize]; | 300 scoped_refptr<net::IOBuffer> buf_; |
| 300 | 301 |
| 301 MessageLoop* owner_loop_; | 302 MessageLoop* owner_loop_; |
| 302 | 303 |
| 303 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do | 304 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do |
| 304 // not manage its lifetime, and we may only access it from the owner's | 305 // not manage its lifetime, and we may only access it from the owner's |
| 305 // message loop (owner_loop_). | 306 // message loop (owner_loop_). |
| 306 ResourceLoaderBridge::Peer* peer_; | 307 ResourceLoaderBridge::Peer* peer_; |
| 307 }; | 308 }; |
| 308 | 309 |
| 309 //----------------------------------------------------------------------------- | 310 //----------------------------------------------------------------------------- |
| (...skipping 16 matching lines...) Expand all Loading... |
| 326 result_->url = new_url; | 327 result_->url = new_url; |
| 327 } | 328 } |
| 328 | 329 |
| 329 virtual void OnReceivedResponse( | 330 virtual void OnReceivedResponse( |
| 330 const ResourceLoaderBridge::ResponseInfo& info, | 331 const ResourceLoaderBridge::ResponseInfo& info, |
| 331 bool content_filtered) { | 332 bool content_filtered) { |
| 332 *static_cast<ResourceLoaderBridge::ResponseInfo*>(result_) = info; | 333 *static_cast<ResourceLoaderBridge::ResponseInfo*>(result_) = info; |
| 333 } | 334 } |
| 334 | 335 |
| 335 virtual void OnReceivedData(int bytes_read) { | 336 virtual void OnReceivedData(int bytes_read) { |
| 336 result_->data.append(buf_, bytes_read); | 337 result_->data.append(buf_->data(), bytes_read); |
| 337 AsyncReadData(); // read more (may recurse) | 338 AsyncReadData(); // read more (may recurse) |
| 338 } | 339 } |
| 339 | 340 |
| 340 virtual void OnCompletedRequest(const URLRequestStatus& status) { | 341 virtual void OnCompletedRequest(const URLRequestStatus& status) { |
| 341 result_->status = status; | 342 result_->status = status; |
| 342 event_.Signal(); | 343 event_.Signal(); |
| 343 } | 344 } |
| 344 | 345 |
| 345 private: | 346 private: |
| 346 ResourceLoaderBridge::SyncLoadResponse* result_; | 347 ResourceLoaderBridge::SyncLoadResponse* result_; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 // static | 547 // static |
| 547 void SimpleResourceLoaderBridge::Shutdown() { | 548 void SimpleResourceLoaderBridge::Shutdown() { |
| 548 if (io_thread) { | 549 if (io_thread) { |
| 549 delete io_thread; | 550 delete io_thread; |
| 550 io_thread = NULL; | 551 io_thread = NULL; |
| 551 | 552 |
| 552 DCHECK(!request_context) << "should have been nulled by thread dtor"; | 553 DCHECK(!request_context) << "should have been nulled by thread dtor"; |
| 553 } | 554 } |
| 554 } | 555 } |
| 555 | 556 |
| OLD | NEW |