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 |