diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 01:54:05 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 01:54:05 +0000 |
commit | 1f8859ad6ec7ea807c0330ddf5559e13be5fb26c (patch) | |
tree | 68887107d0d40f1b22c7a7a07ccd9d7e4caf157a | |
parent | 13dc122db24457653d57ff07791043d518eb05e7 (diff) | |
download | chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.zip chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.tar.gz chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.tar.bz2 |
Change URLRequest to use a ref-counted buffer for actual IO.The ref-counting will prevent the deletion / reuse of memorywhile the buffer is actually being used by pending IO.This seems a very intrusive change, but at least we will be ableto make sure that it works without having to chase every singledestruction of an URLRequest to make sure that any pending IOwas cancelled, and also allows us to avoid blocking onthe object destruction.BUG=5325
Review URL: http://codereview.chromium.org/18390
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8603 0039d316-1c4b-4281-b951-d872f2087c98
70 files changed, 408 insertions, 231 deletions
diff --git a/chrome/browser/automation/url_request_slow_download_job.cc b/chrome/browser/automation/url_request_slow_download_job.cc index e1a2c84f0..71f71ca 100644 --- a/chrome/browser/automation/url_request_slow_download_job.cc +++ b/chrome/browser/automation/url_request_slow_download_job.cc @@ -72,7 +72,7 @@ void URLRequestSlowDownloadJob::StartAsync() { NotifyHeadersComplete(); } -bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, +bool URLRequestSlowDownloadJob::ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read) { if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str())) { @@ -83,7 +83,7 @@ bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, if (should_send_second_chunk_) { DCHECK(buf_size > kSecondDownloadSize); for (int i = 0; i < kSecondDownloadSize; ++i) { - buf[i] = '*'; + buf->data()[i] = '*'; } *bytes_read = kSecondDownloadSize; should_send_second_chunk_ = false; @@ -93,7 +93,7 @@ bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, if (first_download_size_remaining_ > 0) { int send_size = std::min(first_download_size_remaining_, buf_size); for (int i = 0; i < send_size; ++i) { - buf[i] = '*'; + buf->data()[i] = '*'; } *bytes_read = send_size; first_download_size_remaining_ -= send_size; diff --git a/chrome/browser/automation/url_request_slow_download_job.h b/chrome/browser/automation/url_request_slow_download_job.h index cf0156d..847121e 100644 --- a/chrome/browser/automation/url_request_slow_download_job.h +++ b/chrome/browser/automation/url_request_slow_download_job.h @@ -25,7 +25,7 @@ class URLRequestSlowDownloadJob : public URLRequestJob { virtual void Start(); virtual bool GetMimeType(std::string* mime_type); virtual void GetResponseInfo(net::HttpResponseInfo* info); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); static URLRequestJob* Factory(URLRequest* request, const std::string& scheme); diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc index f501764..7d8832e 100644 --- a/chrome/browser/chrome_plugin_host.cc +++ b/chrome/browser/chrome_plugin_host.cc @@ -145,7 +145,7 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { } PluginRequestHandler(ChromePluginLib* plugin, ScopableCPRequest* cprequest) - : PluginHelper(plugin), cprequest_(cprequest) { + : PluginHelper(plugin), cprequest_(cprequest), user_buffer_(NULL) { cprequest_->data = this; // see FromCPRequest(). URLRequestContext* context = CPBrowsingContextManager::Instance()-> @@ -163,6 +163,25 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { URLRequest* request() { return request_.get(); } + // Wraper of URLRequest::Read() + bool Read(char* dest, int dest_size, int *bytes_read) { + CHECK(!my_buffer_.get()); + // We'll use our own buffer until the read actually completes. + user_buffer_ = dest; + my_buffer_ = new net::IOBuffer(dest_size); + + if (request_->Read(my_buffer_, dest_size, bytes_read)) { + memcpy(dest, my_buffer_->data(), *bytes_read); + my_buffer_ = NULL; + return true; + } + + if (!request_->status().is_io_pending()) + my_buffer_ = NULL; + + return false; + } + // URLRequest::Delegate virtual void OnReceivedRedirect(URLRequest* request, const GURL& new_url) { plugin_->functions().response_funcs->received_redirect( @@ -178,16 +197,24 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { } virtual void OnReadCompleted(URLRequest* request, int bytes_read) { - // TODO(mpcomplete): better error codes - if (bytes_read < 0) + CHECK(my_buffer_.get()); + CHECK(user_buffer_); + if (bytes_read > 0) { + memcpy(user_buffer_, my_buffer_->data(), bytes_read); + } else if (bytes_read < 0) { + // TODO(mpcomplete): better error codes bytes_read = CPERR_FAILURE; + } + my_buffer_ = NULL; plugin_->functions().response_funcs->read_completed( - cprequest_.get(), bytes_read); + cprequest_.get(), bytes_read); } private: scoped_ptr<ScopableCPRequest> cprequest_; scoped_ptr<URLRequest> request_; + scoped_refptr<net::IOBuffer> my_buffer_; + char* user_buffer_; }; // This class manages plugins that want to handle UI commands. Right now, we @@ -614,7 +641,7 @@ int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) { CHECK(handler); int bytes_read; - if (handler->request()->Read(static_cast<char*>(buf), buf_size, &bytes_read)) + if (handler->Read(static_cast<char*>(buf), buf_size, &bytes_read)) return bytes_read; // 0 == CPERR_SUCESS if (handler->request()->status().is_io_pending()) diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.cc b/chrome/browser/dom_ui/chrome_url_data_manager.cc index a180280..ce533dd 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.cc +++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc @@ -42,7 +42,7 @@ class URLRequestChromeJob : public URLRequestJob { // URLRequestJob implementation. virtual void Start(); virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual bool GetMimeType(std::string* mime_type); // Called by ChromeURLDataManager to notify us that the data blob is ready @@ -60,7 +60,7 @@ class URLRequestChromeJob : public URLRequestJob { // Do the actual copy from data_ (the data we're serving) into |buf|. // Separate from ReadRawData so we can handle async I/O. - void CompleteRead(char* buf, int buf_size, int* bytes_read); + void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read); // The actual data we're serving. NULL until it's been fetched. scoped_refptr<RefCountedBytes> data_; @@ -70,7 +70,7 @@ class URLRequestChromeJob : public URLRequestJob { // For async reads, we keep around a pointer to the buffer that // we're reading into. - char* pending_buf_; + scoped_refptr<net::IOBuffer> pending_buf_; int pending_buf_size_; std::string mime_type_; @@ -249,7 +249,7 @@ URLRequestJob* ChromeURLDataManager::Factory(URLRequest* request, } URLRequestChromeJob::URLRequestChromeJob(URLRequest* request) - : URLRequestJob(request), data_offset_(0), pending_buf_(NULL) {} + : URLRequestJob(request), data_offset_(0) {} URLRequestChromeJob::~URLRequestChromeJob() { } @@ -278,9 +278,10 @@ void URLRequestChromeJob::DataAvailable(RefCountedBytes* bytes) { data_ = bytes; int bytes_read; - if (pending_buf_) { + if (pending_buf_.get()) { CompleteRead(pending_buf_, pending_buf_size_, &bytes_read); NotifyReadComplete(bytes_read); + pending_buf_ = NULL; } } else { // The request failed. @@ -288,10 +289,11 @@ void URLRequestChromeJob::DataAvailable(RefCountedBytes* bytes) { } } -bool URLRequestChromeJob::ReadRawData(char* buf, int buf_size, +bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) { if (!data_.get()) { SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); + DCHECK(!pending_buf_.get()); pending_buf_ = buf; pending_buf_size_ = buf_size; return false; // Tell the caller we're still waiting for data. @@ -302,13 +304,13 @@ bool URLRequestChromeJob::ReadRawData(char* buf, int buf_size, return true; } -void URLRequestChromeJob::CompleteRead(char* buf, int buf_size, +void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read) { int remaining = static_cast<int>(data_->data.size()) - data_offset_; if (buf_size > remaining) buf_size = remaining; if (buf_size > 0) { - memcpy(buf, &data_->data[0] + data_offset_, buf_size); + memcpy(buf->data(), &data_->data[0] + data_offset_, buf_size); data_offset_ += buf_size; } *bytes_read = buf_size; diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc index 70d733d..5d7b5e5c 100644 --- a/chrome/browser/download/download_file.cc +++ b/chrome/browser/download/download_file.cc @@ -23,6 +23,7 @@ #include "chrome/common/win_util.h" #include "chrome/common/win_safe_util.h" #include "googleurl/src/gurl.h" +#include "net/base/io_buffer.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" @@ -265,11 +266,11 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { DownloadFile* download = LookupDownload(id); for (size_t i = 0; i < contents.size(); ++i) { - char* data = contents[i].first; + net::IOBuffer* data = contents[i].first; const int data_len = contents[i].second; if (download) - download->AppendDataToFile(data, data_len); - delete [] data; + download->AppendDataToFile(data->data(), data_len); + data->Release(); } if (download) { diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h index ea74318..f1ffcea 100644 --- a/chrome/browser/download/download_file.h +++ b/chrome/browser/download/download_file.h @@ -52,6 +52,9 @@ #include "base/timer.h" #include "chrome/browser/history/download_types.h" +namespace net { +class IOBuffer; +} class DownloadManager; class FilePath; class GURL; @@ -70,7 +73,7 @@ class URLRequestContext; struct DownloadBuffer { Lock lock; - typedef std::pair<char *, int> Contents; + typedef std::pair<net::IOBuffer*, int> Contents; std::vector<Contents> contents; }; diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc index fbf5782..64984de 100644 --- a/chrome/browser/download/save_file_manager.cc +++ b/chrome/browser/download/save_file_manager.cc @@ -25,6 +25,7 @@ #include "chrome/common/win_safe_util.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" +#include "net/base/io_buffer.h" #include "net/url_request/url_request_context.h" SaveFileManager::SaveFileManager(MessageLoop* ui_loop, @@ -271,12 +272,12 @@ void SaveFileManager::StartSave(SaveFileCreateInfo* info) { // thread). We may receive a few more updates before the IO thread gets the // cancel message. We just delete the data since the SaveFile has been deleted. void SaveFileManager::UpdateSaveProgress(int save_id, - char* data, + net::IOBuffer* data, int data_len) { DCHECK(MessageLoop::current() == GetSaveLoop()); SaveFile* save_file = LookupSaveFile(save_id); if (save_file) { - bool write_success = save_file->AppendDataToFile(data, data_len); + bool write_success = save_file->AppendDataToFile(data->data(), data_len); ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &SaveFileManager::OnUpdateSaveProgress, @@ -284,7 +285,7 @@ void SaveFileManager::UpdateSaveProgress(int save_id, save_file->bytes_so_far(), write_success)); } - delete [] data; + data->Release(); } // The IO thread will call this when saving is completed or it got error when diff --git a/chrome/browser/download/save_file_manager.h b/chrome/browser/download/save_file_manager.h index 8bd6e89..cf29e1c 100644 --- a/chrome/browser/download/save_file_manager.h +++ b/chrome/browser/download/save_file_manager.h @@ -66,6 +66,9 @@ #include "base/thread.h" #include "chrome/browser/download/save_types.h" +namespace net { +class IOBuffer; +} class GURL; class SaveFile; class SavePackage; @@ -101,7 +104,7 @@ class SaveFileManager // Notifications sent from the IO thread and run on the file thread: void StartSave(SaveFileCreateInfo* info); - void UpdateSaveProgress(int save_id, char* data, int size); + void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size); void SaveFinished(int save_id, std::wstring save_url, int render_process_id, bool is_success); diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 1127017..1eea9e5 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -31,6 +31,7 @@ #include "chrome/common/pref_service.h" #include "chrome/common/stl_util-inl.h" #include "chrome/common/win_util.h" +#include "net/base/io_buffer.h" #include "net/base/mime_util.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" @@ -812,8 +813,8 @@ void SavePackage::OnReceivedSerializedHtmlData(const GURL& frame_url, if (!data.empty()) { // Prepare buffer for saving HTML data. - char* new_data = static_cast<char*>(new char[data.size()]); - memcpy(new_data, data.data(), data.size()); + net::IOBuffer* new_data = new net::IOBuffer(data.size()); + memcpy(new_data->data(), data.data(), data.size()); // Call write file functionality in file thread. file_manager_->GetSaveLoop()->PostTask(FROM_HERE, diff --git a/chrome/browser/net/url_fetcher.cc b/chrome/browser/net/url_fetcher.cc index b7ea8cd..9e41f22 100644 --- a/chrome/browser/net/url_fetcher.cc +++ b/chrome/browser/net/url_fetcher.cc @@ -11,6 +11,9 @@ #include "chrome/browser/chrome_thread.h" #include "googleurl/src/gurl.h" #include "net/base/load_flags.h" +#include "net/base/io_buffer.h" + +static const int kBufferSize = 4096; URLFetcher::URLFetcher(const GURL& url, RequestType request_type, @@ -36,6 +39,7 @@ URLFetcher::Core::Core(URLFetcher* fetcher, request_(NULL), load_flags_(net::LOAD_NORMAL), response_code_(-1), + buffer_(new net::IOBuffer(kBufferSize)), protect_entry_(URLFetcherProtectManager::GetInstance()->Register( original_url_.host())), num_retries_(0) { @@ -71,7 +75,7 @@ void URLFetcher::Core::OnResponseStarted(URLRequest* request) { // completed immediately, without trying to read any data back (all we care // about is the response code and headers, which we already have). if (request_->status().is_success() && (request_type_ != HEAD)) - request_->Read(buffer_, sizeof(buffer_), &bytes_read); + request_->Read(buffer_, kBufferSize, &bytes_read); OnReadCompleted(request_, bytes_read); } @@ -84,8 +88,8 @@ void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) { do { if (!request_->status().is_success() || bytes_read <= 0) break; - data_.append(buffer_, bytes_read); - } while (request_->Read(buffer_, sizeof(buffer_), &bytes_read)); + data_.append(buffer_->data(), bytes_read); + } while (request_->Read(buffer_, kBufferSize, &bytes_read)); if (request_->status().is_success()) request_->GetResponseCookies(&cookies_); diff --git a/chrome/browser/net/url_fetcher.h b/chrome/browser/net/url_fetcher.h index 7e4c132..044e61b 100644 --- a/chrome/browser/net/url_fetcher.h +++ b/chrome/browser/net/url_fetcher.h @@ -185,7 +185,8 @@ class URLFetcher { int load_flags_; // Flags for the load operation int response_code_; // HTTP status code for the request std::string data_; // Results of the request - char buffer_[4096]; // Read buffer + scoped_refptr<net::IOBuffer> buffer_; + // Read buffer scoped_refptr<URLRequestContext> request_context_; // Cookie/cache info for the request ResponseCookies cookies_; // Response cookies diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 7c272a5..aeff2d0 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -36,6 +36,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/win_util.h" #include "net/base/cookie_monster.h" +#include "net/base/io_buffer.h" #include "net/proxy/proxy_service.h" #include "net/url_request/url_request.h" #include "sandbox/src/sandbox.h" @@ -127,7 +128,7 @@ class PluginDownloadUrlHelper : public URLRequest::Delegate { // The full path of the downloaded file. std::wstring download_file_path_; // The buffer passed off to URLRequest::Read. - char download_file_buffer_[kDownloadFileBufferSize]; + scoped_refptr<net::IOBuffer> download_file_buffer_; // The window handle for sending the WM_COPYDATA notification, // indicating that the download completed. HWND download_file_caller_window_; @@ -142,12 +143,13 @@ PluginDownloadUrlHelper::PluginDownloadUrlHelper( const std::string& download_url, int source_pid, HWND caller_window) : download_url_(download_url), - download_file_caller_window_(caller_window), - download_source_pid_(source_pid), download_file_request_(NULL), - download_file_(INVALID_HANDLE_VALUE) { + download_file_(INVALID_HANDLE_VALUE), + download_file_buffer_(new net::IOBuffer(kDownloadFileBufferSize)), + download_file_caller_window_(caller_window), + download_source_pid_(source_pid) { DCHECK(::IsWindow(caller_window)); - memset(download_file_buffer_, 0, arraysize(download_file_buffer_)); + memset(download_file_buffer_->data(), 0, kDownloadFileBufferSize); } PluginDownloadUrlHelper::~PluginDownloadUrlHelper() { @@ -210,7 +212,7 @@ void PluginDownloadUrlHelper::OnResponseStarted(URLRequest* request) { } else { // Initiate a read. int bytes_read = 0; - if (!request->Read(download_file_buffer_, arraysize(download_file_buffer_), + if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, &bytes_read)) { // If the error is not an IO pending, then we're done // reading. @@ -238,7 +240,8 @@ void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, while (request->status().is_success()) { unsigned long bytes_written = 0; - BOOL write_result = WriteFile(download_file_, download_file_buffer_, + BOOL write_result = WriteFile(download_file_, + download_file_buffer_->data(), request_bytes_read, &bytes_written, NULL); DCHECK(!write_result || (bytes_written == request_bytes_read)); @@ -249,7 +252,7 @@ void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, // Start reading request_bytes_read = 0; - if (!request->Read(download_file_buffer_, arraysize(download_file_buffer_), + if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, &request_bytes_read)) { if (!request->status().is_io_pending()) { // If the error is not an IO pending, then we're done diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index a59f61e..814415e 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -5,8 +5,31 @@ #include "chrome/browser/renderer_host/async_resource_handler.h" #include "base/process.h" +#include "net/base/io_buffer.h" + +SharedIOBuffer* AsyncResourceHandler::spare_read_buffer_; + +// Our version of IOBuffer that uses shared memory. +class SharedIOBuffer : public net::IOBuffer { + public: + SharedIOBuffer(int buffer_size) : net::IOBuffer(NULL), ok_(false) { + if (shared_memory_.Create(std::wstring(), false, false, buffer_size) && + shared_memory_.Map(buffer_size)) { + ok_ = true; + data_ = reinterpret_cast<char*>(shared_memory_.memory()); + } + } + ~SharedIOBuffer() { + data_ = NULL; + } -base::SharedMemory* AsyncResourceHandler::spare_read_buffer_; + base::SharedMemory* shared_memory() { return &shared_memory_; } + bool ok() { return ok_; } + + private: + base::SharedMemory shared_memory_; + bool ok_; +}; AsyncResourceHandler::AsyncResourceHandler( ResourceDispatcherHost::Receiver* receiver, @@ -44,22 +67,19 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, return true; } -bool AsyncResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(min_size == -1); static const int kReadBufSize = 32768; if (spare_read_buffer_) { - read_buffer_.reset(spare_read_buffer_); + read_buffer_ = spare_read_buffer_; spare_read_buffer_ = NULL; } else { - read_buffer_.reset(new base::SharedMemory); - if (!read_buffer_->Create(std::wstring(), false, false, kReadBufSize)) - return false; - if (!read_buffer_->Map(kReadBufSize)) + read_buffer_ = new SharedIOBuffer(kReadBufSize); + if (!read_buffer_->ok()) return false; } - *buf = static_cast<char*>(read_buffer_->memory()); + *buf = read_buffer_.get(); *buf_size = kReadBufSize; return true; } @@ -75,7 +95,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { } base::SharedMemoryHandle handle; - if (!read_buffer_->GiveToProcess(render_process_, &handle)) { + if (!read_buffer_->shared_memory()->GiveToProcess(render_process_, &handle)) { // We wrongfully incremented the pending data count. Fake an ACK message // to fix this. We can't move this call above the WillSendData because // it's killing our read_buffer_, and we don't want that when we pause @@ -97,15 +117,14 @@ bool AsyncResourceHandler::OnResponseCompleted(int request_id, // If we still have a read buffer, then see about caching it for later... if (spare_read_buffer_) { - read_buffer_.reset(); - } else if (read_buffer_.get() && read_buffer_->memory()) { - spare_read_buffer_ = read_buffer_.release(); + read_buffer_ = NULL; + } else if (read_buffer_.get() && read_buffer_->data()) { + read_buffer_.swap(&spare_read_buffer_); } return true; } // static void AsyncResourceHandler::GlobalCleanup() { - delete spare_read_buffer_; spare_read_buffer_ = NULL; } diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 618e518..e966a80 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -9,9 +9,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" -namespace base { -class SharedMemory; -} +class SharedIOBuffer; // Used to complete an asynchronous resource request in response to resource // load events from the resource dispatcher host. @@ -28,7 +26,8 @@ class AsyncResourceHandler : public ResourceHandler { bool OnUploadProgress(int request_id, uint64 position, uint64 size); bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); @@ -38,9 +37,9 @@ class AsyncResourceHandler : public ResourceHandler { // When reading, we don't know if we are going to get EOF (0 bytes read), so // we typically have a buffer that we allocated but did not use. We keep // this buffer around for the next read as a small optimization. - static base::SharedMemory* spare_read_buffer_; + static SharedIOBuffer* spare_read_buffer_; - scoped_ptr<base::SharedMemory> read_buffer_; + scoped_refptr<SharedIOBuffer> read_buffer_; ResourceDispatcherHost::Receiver* receiver_; int render_process_host_id_; int routing_id_; diff --git a/chrome/browser/renderer_host/buffered_resource_handler.cc b/chrome/browser/renderer_host/buffered_resource_handler.cc index ea7d69d..458dc8c 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.cc +++ b/chrome/browser/renderer_host/buffered_resource_handler.cc @@ -8,9 +8,13 @@ #include "net/base/mime_sniffer.h" #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "net/base/mime_sniffer.h" +#include "net/base/io_buffer.h" namespace { +const int kMaxBytesToSniff = 512; + void RecordSnifferMetrics(bool sniffing_blocked, bool we_would_like_to_sniff, const std::string& mime_type) { @@ -71,13 +75,13 @@ bool BufferedResourceHandler::OnResponseCompleted( // We'll let the original event handler provide a buffer, and reuse it for // subsequent reads until we're done buffering. -bool BufferedResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { if (buffering_) { - *buf = read_buffer_ + bytes_read_; - *buf_size = read_buffer_size_ - bytes_read_; - DCHECK(*buf_size > 0); + DCHECK(!my_buffer_.get()); + my_buffer_ = new net::IOBuffer(kMaxBytesToSniff); + *buf = my_buffer_.get(); + *buf_size = kMaxBytesToSniff; return true; } @@ -87,6 +91,7 @@ bool BufferedResourceHandler::OnWillRead(int request_id, bool ret = real_handler_->OnWillRead(request_id, buf, buf_size, min_size); read_buffer_ = *buf; read_buffer_size_ = *buf_size; + DCHECK(read_buffer_size_ >= kMaxBytesToSniff * 2); bytes_read_ = 0; return ret; } @@ -168,6 +173,12 @@ bool BufferedResourceHandler::ShouldBuffer(const GURL& url, bool BufferedResourceHandler::KeepBuffering(int bytes_read) { DCHECK(read_buffer_); + if (my_buffer_) { + // We are using our own buffer to read, update the main buffer. + CHECK(bytes_read + bytes_read_ < read_buffer_size_); + memcpy(read_buffer_->data() + bytes_read_, my_buffer_->data(), bytes_read); + my_buffer_ = NULL; + } bytes_read_ += bytes_read; finished_ = (bytes_read == 0); @@ -175,12 +186,12 @@ bool BufferedResourceHandler::KeepBuffering(int bytes_read) { std::string type_hint, new_type; request_->GetMimeType(&type_hint); - if (!net::SniffMimeType(read_buffer_, bytes_read_, request_->url(), - type_hint, &new_type)) { + if (!net::SniffMimeType(read_buffer_->data(), bytes_read_, + request_->url(), type_hint, &new_type)) { // SniffMimeType() returns false if there is not enough data to determine // the mime type. However, even if it returns false, it returns a new type // that is probably better than the current one. - DCHECK(bytes_read_ < 512 /*kMaxBytesToSniff*/); + DCHECK(bytes_read_ < kMaxBytesToSniff); if (!finished_) { buffering_ = true; return true; @@ -243,11 +254,11 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, if (bytes_read_) { // a Read has already occurred and we need to copy the data into the // EventHandler. - char *buf = NULL; + net::IOBuffer* buf = NULL; int buf_len = 0; download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); - memcpy(buf, read_buffer_, bytes_read_); + memcpy(buf->data(), read_buffer_->data(), bytes_read_); } // Update the renderer with the response headers which will cause it to // cancel the request. diff --git a/chrome/browser/renderer_host/buffered_resource_handler.h b/chrome/browser/renderer_host/buffered_resource_handler.h index 0b832a9..a612722 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.h +++ b/chrome/browser/renderer_host/buffered_resource_handler.h @@ -22,7 +22,8 @@ class BufferedResourceHandler : public ResourceHandler { bool OnUploadProgress(int request_id, uint64 position, uint64 size); bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); @@ -48,7 +49,8 @@ class BufferedResourceHandler : public ResourceHandler { scoped_refptr<ResourceResponse> response_; ResourceDispatcherHost* host_; URLRequest* request_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; + scoped_refptr<net::IOBuffer> my_buffer_; int read_buffer_size_; int bytes_read_; bool sniff_content_; diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.cc b/chrome/browser/renderer_host/cross_site_resource_handler.cc index a172352..363d451 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.cc +++ b/chrome/browser/renderer_host/cross_site_resource_handler.cc @@ -114,9 +114,8 @@ bool CrossSiteResourceHandler::OnResponseStarted(int request_id, return true; } -bool CrossSiteResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool CrossSiteResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); } diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.h b/chrome/browser/renderer_host/cross_site_resource_handler.h index 7801352..7d57c76 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.h +++ b/chrome/browser/renderer_host/cross_site_resource_handler.h @@ -24,7 +24,8 @@ class CrossSiteResourceHandler : public ResourceHandler { bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc index 13e7457..01704e7 100644 --- a/chrome/browser/renderer_host/download_resource_handler.cc +++ b/chrome/browser/renderer_host/download_resource_handler.cc @@ -7,6 +7,7 @@ #include "chrome/browser/download/download_file.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "net/base/io_buffer.h" DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, int render_process_host_id, @@ -20,7 +21,6 @@ DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, global_id_(ResourceDispatcherHost::GlobalRequestID(render_process_host_id, request_id)), render_view_id_(render_view_id), - read_buffer_(NULL), url_(UTF8ToWide(url)), content_length_(0), download_manager_(manager), @@ -72,15 +72,14 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, // Create a new buffer, which will be handed to the download thread for file // writing and deletion. -bool DownloadResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool DownloadResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(buf && buf_size); if (!read_buffer_) { *buf_size = min_size < 0 ? kReadBufSize : min_size; - read_buffer_ = new char[*buf_size]; + read_buffer_ = new net::IOBuffer(*buf_size); } - *buf = read_buffer_; + *buf = read_buffer_.get(); return true; } @@ -91,7 +90,11 @@ bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { DCHECK(read_buffer_); AutoLock auto_lock(buffer_->lock); bool need_update = buffer_->contents.empty(); - buffer_->contents.push_back(std::make_pair(read_buffer_, *bytes_read)); + + // We are passing ownership of this buffer to the download file manager. + net::IOBuffer* buffer = NULL; + read_buffer_.swap(&buffer); + buffer_->contents.push_back(std::make_pair(buffer, *bytes_read)); if (need_update) { download_manager_->file_loop()->PostTask(FROM_HERE, NewRunnableMethod(download_manager_, @@ -99,7 +102,6 @@ bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { download_id_, buffer_)); } - read_buffer_ = NULL; // We schedule a pause outside of the read loop if there is too much file // writing work to do. @@ -117,7 +119,7 @@ bool DownloadResourceHandler::OnResponseCompleted( &DownloadFileManager::DownloadFinished, download_id_, buffer_)); - delete [] read_buffer_; + read_buffer_ = NULL; // 'buffer_' is deleted by the DownloadFileManager. buffer_ = NULL; diff --git a/chrome/browser/renderer_host/download_resource_handler.h b/chrome/browser/renderer_host/download_resource_handler.h index b666df6..0dbeef0 100644 --- a/chrome/browser/renderer_host/download_resource_handler.h +++ b/chrome/browser/renderer_host/download_resource_handler.h @@ -32,7 +32,8 @@ class DownloadResourceHandler : public ResourceHandler { // Create a new buffer, which will be handed to the download thread for file // writing and deletion. - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); @@ -53,7 +54,7 @@ class DownloadResourceHandler : public ResourceHandler { int download_id_; ResourceDispatcherHost::GlobalRequestID global_id_; int render_view_id_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; std::string content_disposition_; std::wstring url_; int64 content_length_; diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.cc b/chrome/browser/renderer_host/download_throttling_resource_handler.cc index 07b8164..ea4fdbb 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.cc +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.cc @@ -5,6 +5,7 @@ #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" #include "chrome/browser/renderer_host/download_resource_handler.h" +#include "net/base/io_buffer.h" DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler( ResourceDispatcherHost* host, @@ -57,7 +58,7 @@ bool DownloadThrottlingResourceHandler::OnResponseStarted( } bool DownloadThrottlingResourceHandler::OnWillRead(int request_id, - char** buf, + net::IOBuffer** buf, int* buf_size, int min_size) { if (download_handler_.get()) @@ -68,7 +69,7 @@ bool DownloadThrottlingResourceHandler::OnWillRead(int request_id, DCHECK(!tmp_buffer_.get()); if (min_size < 0) min_size = 1024; - tmp_buffer_.reset(new char[min_size]); + tmp_buffer_ = new net::IOBuffer(min_size); *buf = tmp_buffer_.get(); *buf_size = min_size; return true; @@ -132,14 +133,14 @@ void DownloadThrottlingResourceHandler::ContinueDownload() { void DownloadThrottlingResourceHandler::CopyTmpBufferToDownloadHandler() { // Copy over the tmp buffer. - char* buffer; + net::IOBuffer* buffer; int buf_size; if (download_handler_->OnWillRead(request_id_, &buffer, &buf_size, tmp_buffer_length_)) { CHECK(buf_size >= tmp_buffer_length_); - memcpy(buffer, tmp_buffer_.get(), tmp_buffer_length_); + memcpy(buffer->data(), tmp_buffer_->data(), tmp_buffer_length_); download_handler_->OnReadCompleted(request_id_, &tmp_buffer_length_); } tmp_buffer_length_ = 0; - tmp_buffer_.reset(); + tmp_buffer_ = NULL; } diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.h b/chrome/browser/renderer_host/download_throttling_resource_handler.h index 177f4fd..97b2942 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.h +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.h @@ -40,9 +40,7 @@ class DownloadThrottlingResourceHandler uint64 size); virtual bool OnRequestRedirected(int request_id, const GURL& url); virtual bool OnResponseStarted(int request_id, ResourceResponse* response); - virtual bool OnWillRead(int request_id, - char** buf, - int* buf_size, + virtual bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); virtual bool OnReadCompleted(int request_id, int* bytes_read); virtual bool OnResponseCompleted(int request_id, @@ -72,7 +70,7 @@ class DownloadThrottlingResourceHandler // If we're created by way of BufferedEventHandler we'll get one request for // a buffer. This is that buffer. - scoped_array<char> tmp_buffer_; + scoped_refptr<net::IOBuffer> tmp_buffer_; int tmp_buffer_length_; // If true the next call to OnReadCompleted is ignored. This is used if we're diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 261d1c1..2864d88 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -928,7 +928,7 @@ bool ResourceDispatcherHost::Read(URLRequest* request, int* bytes_read) { ExtraRequestInfo* info = ExtraInfoForRequest(request); DCHECK(!info->is_paused); - char* buf; + net::IOBuffer* buf; int buf_size; if (!info->resource_handler->OnWillRead(info->request_id, &buf, &buf_size, -1)) { diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h index a6955c7..9813094 100644 --- a/chrome/browser/renderer_host/resource_handler.h +++ b/chrome/browser/renderer_host/resource_handler.h @@ -49,7 +49,7 @@ class ResourceHandler : public base::RefCounted<ResourceHandler> { // out-params. This call will be followed by either OnReadCompleted or // OnResponseCompleted, at which point the buffer may be recycled. virtual bool OnWillRead(int request_id, - char** buf, + net::IOBuffer** buf, int* buf_size, int min_size) = 0; diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc index 3ca7b38..7ee4661 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc @@ -77,7 +77,7 @@ void SafeBrowsingResourceHandler::OnGetHashTimeout() { } bool SafeBrowsingResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, + net::IOBuffer** buf, int* buf_size, int min_size) { if (in_safe_browsing_check_ && pause_time_.is_null()) { pause_time_ = base::Time::Now(); diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.h b/chrome/browser/renderer_host/safe_browsing_resource_handler.h index 244df8b..92e0040 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.h +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.h @@ -28,7 +28,8 @@ class SafeBrowsingResourceHandler : public ResourceHandler, bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); void OnGetHashTimeout(); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); diff --git a/chrome/browser/renderer_host/save_file_resource_handler.cc b/chrome/browser/renderer_host/save_file_resource_handler.cc index 420b28a..2520961 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.cc +++ b/chrome/browser/renderer_host/save_file_resource_handler.cc @@ -5,6 +5,7 @@ #include "chrome/browser/renderer_host/save_file_resource_handler.h" #include "chrome/browser/download/save_file_manager.h" +#include "net/base/io_buffer.h" SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id, int render_view_id, @@ -13,7 +14,6 @@ SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id, : save_id_(-1), render_process_id_(render_process_host_id), render_view_id_(render_view_id), - read_buffer_(NULL), url_(UTF8ToWide(url)), content_length_(0), save_manager_(manager) { @@ -46,27 +46,28 @@ bool SaveFileResourceHandler::OnResponseStarted(int request_id, return true; } -bool SaveFileResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool SaveFileResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(buf && buf_size); if (!read_buffer_) { *buf_size = min_size < 0 ? kReadBufSize : min_size; - read_buffer_ = new char[*buf_size]; + read_buffer_ = new net::IOBuffer(*buf_size); } - *buf = read_buffer_; + *buf = read_buffer_.get(); return true; } bool SaveFileResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { DCHECK(read_buffer_); + // We are passing ownership of this buffer to the save file manager. + net::IOBuffer* buffer = NULL; + read_buffer_.swap(&buffer); save_manager_->GetSaveLoop()->PostTask(FROM_HERE, NewRunnableMethod(save_manager_, &SaveFileManager::UpdateSaveProgress, save_id_, - read_buffer_, + buffer, *bytes_read)); - read_buffer_ = NULL; return true; } @@ -80,6 +81,6 @@ bool SaveFileResourceHandler::OnResponseCompleted( url_, render_process_id_, status.is_success() && !status.is_io_pending())); - delete [] read_buffer_; + read_buffer_ = NULL; return true; } diff --git a/chrome/browser/renderer_host/save_file_resource_handler.h b/chrome/browser/renderer_host/save_file_resource_handler.h index 87f06ae..30fc074 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.h +++ b/chrome/browser/renderer_host/save_file_resource_handler.h @@ -28,7 +28,8 @@ class SaveFileResourceHandler : public ResourceHandler { // Creates a new buffer, which will be handed to the download thread for file // writing and deletion. - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); // Passes the buffer to the download file writer. bool OnReadCompleted(int request_id, int* bytes_read); @@ -50,7 +51,7 @@ class SaveFileResourceHandler : public ResourceHandler { int save_id_; int render_process_id_; int render_view_id_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; std::string content_disposition_; std::wstring url_; std::wstring final_url_; diff --git a/chrome/browser/renderer_host/sync_resource_handler.cc b/chrome/browser/renderer_host/sync_resource_handler.cc index aace1c1..a30f10f 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.cc +++ b/chrome/browser/renderer_host/sync_resource_handler.cc @@ -8,7 +8,8 @@ SyncResourceHandler::SyncResourceHandler( ResourceDispatcherHost::Receiver* receiver, const GURL& url, IPC::Message* result_message) - : receiver_(receiver), + : read_buffer_(new net::IOBuffer(kReadBufSize)), + receiver_(receiver), result_message_(result_message) { result_.final_url = url; result_.filter_policy = FilterPolicy::DONT_FILTER; @@ -29,10 +30,10 @@ bool SyncResourceHandler::OnResponseStarted(int request_id, return true; } -bool SyncResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, int min_size) { +bool SyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(min_size == -1); - *buf = read_buffer_; + *buf = read_buffer_.get(); *buf_size = kReadBufSize; return true; } @@ -40,7 +41,7 @@ bool SyncResourceHandler::OnWillRead(int request_id, bool SyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { if (!*bytes_read) return true; - result_.data.append(read_buffer_, *bytes_read); + result_.data.append(read_buffer_->data(), *bytes_read); return true; } diff --git a/chrome/browser/renderer_host/sync_resource_handler.h b/chrome/browser/renderer_host/sync_resource_handler.h index 81a6078..012ab9e 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.h +++ b/chrome/browser/renderer_host/sync_resource_handler.h @@ -7,6 +7,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" +#include "net/base/io_buffer.h" // Used to complete a synchronous resource request in response to resource load // events from the resource dispatcher host. @@ -18,13 +19,14 @@ class SyncResourceHandler : public ResourceHandler { bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); private: enum { kReadBufSize = 3840 }; - char read_buffer_[kReadBufSize]; + scoped_refptr<net::IOBuffer> read_buffer_; ViewHostMsg_SyncLoad_Result result_; ResourceDispatcherHost::Receiver* receiver_; diff --git a/chrome/common/chrome_plugin_unittest.cc b/chrome/common/chrome_plugin_unittest.cc index bf901b3..d7c581f 100644 --- a/chrome/common/chrome_plugin_unittest.cc +++ b/chrome/common/chrome_plugin_unittest.cc @@ -11,6 +11,7 @@ #include "chrome/browser/profile.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/test/chrome_plugin/test_chrome_plugin.h" +#include "net/base/io_buffer.h" #include "net/url_request/url_request_test_job.h" #include "net/url_request/url_request_unittest.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,11 +20,13 @@ namespace { const wchar_t kDocRoot[] = L"chrome/test/data"; const char kPluginFilename[] = "test_chrome_plugin.dll"; +const int kResponseBufferSize = 4096; class ChromePluginTest : public testing::Test, public URLRequest::Delegate { public: ChromePluginTest() : request_(NULL), + response_buffer_(new net::IOBuffer(kResponseBufferSize)), plugin_(NULL), expected_payload_(NULL), request_context_(new TestURLRequestContext()) { @@ -75,7 +78,7 @@ class ChromePluginTest : public testing::Test, public URLRequest::Delegate { // Note: we use URLRequest (instead of URLFetcher) because this allows the // request to be intercepted. scoped_ptr<URLRequest> request_; - char response_buffer_[4096]; + scoped_refptr<net::IOBuffer> response_buffer_; std::string response_data_; ChromePluginLib* plugin_; @@ -155,7 +158,7 @@ void ChromePluginTest::OnResponseStarted(URLRequest* request) { int bytes_read = 0; if (request_->status().is_success()) - request_->Read(response_buffer_, sizeof(response_buffer_), &bytes_read); + request_->Read(response_buffer_, kResponseBufferSize, &bytes_read); OnReadCompleted(request_.get(), bytes_read); } @@ -165,9 +168,8 @@ void ChromePluginTest::OnReadCompleted(URLRequest* request, int bytes_read) { do { if (!request_->status().is_success() || bytes_read <= 0) break; - response_data_.append(response_buffer_, bytes_read); - } while (request_->Read(response_buffer_, sizeof(response_buffer_), - &bytes_read)); + response_data_.append(response_buffer_->data(), bytes_read); + } while (request_->Read(response_buffer_, kResponseBufferSize, &bytes_read)); if (!request_->status().is_io_pending()) { OnURLRequestComplete(); diff --git a/chrome/common/net/url_request_intercept_job.cc b/chrome/common/net/url_request_intercept_job.cc index b11fbb2..01f4e29 100644 --- a/chrome/common/net/url_request_intercept_job.cc +++ b/chrome/common/net/url_request_intercept_job.cc @@ -66,7 +66,7 @@ void URLRequestInterceptJob::Kill() { URLRequestJob::Kill(); } -bool URLRequestInterceptJob::ReadRawData(char* dest, int dest_size, +bool URLRequestInterceptJob::ReadRawData(net::IOBuffer* dest, int dest_size, int* bytes_read) { DCHECK_NE(dest_size, 0); DCHECK(bytes_read); @@ -75,7 +75,7 @@ bool URLRequestInterceptJob::ReadRawData(char* dest, int dest_size, return false; int rv = plugin_->functions().request_funcs->read(cprequest_.get(), - dest, dest_size); + dest->data(), dest_size); if (rv >= 0) { *bytes_read = rv; return true; diff --git a/chrome/common/net/url_request_intercept_job.h b/chrome/common/net/url_request_intercept_job.h index b8f3dde..1537281 100644 --- a/chrome/common/net/url_request_intercept_job.h +++ b/chrome/common/net/url_request_intercept_job.h @@ -34,7 +34,7 @@ class URLRequestInterceptJob // URLRequestJob virtual void Start(); virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int* bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read); virtual bool GetMimeType(std::string* mime_type); virtual bool GetCharset(std::string* charset); virtual void GetResponseInfo(net::HttpResponseInfo* info); @@ -53,7 +53,7 @@ class URLRequestInterceptJob scoped_ptr<ScopableCPRequest> cprequest_; ChromePluginLib* plugin_; bool got_headers_; - char* read_buffer_; + net::IOBuffer* read_buffer_; int read_buffer_size_; DISALLOW_EVIL_CONSTRUCTORS(URLRequestInterceptJob); diff --git a/net/base/bzip2_filter_unittest.cc b/net/base/bzip2_filter_unittest.cc index e246726..ae80305 100644 --- a/net/base/bzip2_filter_unittest.cc +++ b/net/base/bzip2_filter_unittest.cc @@ -122,7 +122,7 @@ class BZip2FilterUnitTest : public PlatformTest { break; encode_data_len = std::min(encode_avail_size, filter->stream_buffer_size()); - memcpy(filter->stream_buffer(), encode_next, encode_data_len); + memcpy(filter->stream_buffer()->data(), encode_next, encode_data_len); filter->FlushStreamBuffer(encode_data_len); encode_next += encode_data_len; encode_avail_size -= encode_data_len; @@ -162,7 +162,7 @@ class BZip2FilterUnitTest : public PlatformTest { int source_len, char* dest, int* dest_len) { - memcpy(filter->stream_buffer(), source, source_len); + memcpy(filter->stream_buffer()->data(), source, source_len); filter->FlushStreamBuffer(source_len); return filter->ReadData(dest, dest_len); } @@ -186,7 +186,8 @@ TEST_F(BZip2FilterUnitTest, DecodeBZip2) { filter_types.push_back(Filter::FILTER_TYPE_BZIP2); scoped_ptr<Filter> filter(Filter::Factory(filter_types, kDefaultBufferSize)); ASSERT_TRUE(filter.get()); - memcpy(filter->stream_buffer(), bzip2_encode_buffer_, bzip2_encode_len_); + memcpy(filter->stream_buffer()->data(), bzip2_encode_buffer_, + bzip2_encode_len_); filter->FlushStreamBuffer(bzip2_encode_len_); char bzip2_decode_buffer[kDefaultBufferSize]; diff --git a/net/base/completion_callback.h b/net/base/completion_callback.h index 4013f71..f9bb233 100644 --- a/net/base/completion_callback.h +++ b/net/base/completion_callback.h @@ -6,6 +6,7 @@ #define NET_BASE_COMPLETION_CALLBACK_H__ #include "base/task.h" +#include "net/base/io_buffer.h" namespace net { @@ -41,8 +42,23 @@ class CancelableCompletionCallback : is_canceled_ = true; } + // Attaches the given buffer to this callback so it is valid until the + // operation completes. TODO(rvargas): This is a temporal fix for bug 5325 + // while I send IOBuffer to the lower layers of code. + void UseBuffer(net::IOBuffer* buffer) { + DCHECK(!buffer_.get()); + buffer_ = buffer; + } + + // The callback is not expected anymore so release the buffer. + void ReleaseBuffer() { + DCHECK(buffer_.get()); + buffer_ = NULL; + } + virtual void RunWithParams(const Tuple1<int>& params) { if (is_canceled_) { + CancelableCompletionCallback<T>::ReleaseBuffer(); base::RefCounted<CancelableCompletionCallback<T> >::Release(); } else { CompletionCallbackImpl<T>::RunWithParams(params); @@ -50,6 +66,7 @@ class CancelableCompletionCallback : } private: + scoped_refptr<net::IOBuffer> buffer_; bool is_canceled_; }; diff --git a/net/base/filter.cc b/net/base/filter.cc index 57a13ef..76ee9d9 100644 --- a/net/base/filter.cc +++ b/net/base/filter.cc @@ -228,7 +228,7 @@ bool Filter::InitBuffer(int buffer_size) { if (buffer_size < 0 || stream_buffer()) return false; - stream_buffer_.reset(new char[buffer_size]); + stream_buffer_ = new net::IOBuffer(buffer_size); if (stream_buffer()) { stream_buffer_size_ = buffer_size; @@ -275,9 +275,9 @@ Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) { return next_filter_->ReadData(dest_buffer, dest_len); if (next_filter_->last_status() == FILTER_NEED_MORE_DATA) { // Push data into next filter's input. - char* next_buffer = next_filter_->stream_buffer(); + net::IOBuffer* next_buffer = next_filter_->stream_buffer(); int next_size = next_filter_->stream_buffer_size(); - last_status_ = ReadFilteredData(next_buffer, &next_size); + last_status_ = ReadFilteredData(next_buffer->data(), &next_size); next_filter_->FlushStreamBuffer(next_size); switch (last_status_) { case FILTER_ERROR: @@ -306,7 +306,7 @@ bool Filter::FlushStreamBuffer(int stream_data_len) { if (!stream_buffer() || stream_data_len_) return false; - next_stream_data_ = stream_buffer(); + next_stream_data_ = stream_buffer()->data(); stream_data_len_ = stream_data_len; return true; } diff --git a/net/base/filter.h b/net/base/filter.h index 71dc438..87ef6fd 100644 --- a/net/base/filter.h +++ b/net/base/filter.h @@ -35,6 +35,7 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/time.h" +#include "net/base/io_buffer.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest_prod.h" @@ -91,8 +92,8 @@ class Filter { // next_filter_, then it obtains data from this specific filter. FilterStatus ReadData(char* dest_buffer, int* dest_len); - // Returns a pointer to the beginning of stream_buffer_. - char* stream_buffer() const { return stream_buffer_.get(); } + // Returns a pointer to the stream_buffer_. + net::IOBuffer* stream_buffer() const { return stream_buffer_.get(); } // Returns the maximum size of stream_buffer_ in number of chars. int stream_buffer_size() const { return stream_buffer_size_; } @@ -177,7 +178,7 @@ class Filter { bool was_cached() const { return was_cached_; } // Buffer to hold the data to be filtered. - scoped_array<char> stream_buffer_; + scoped_refptr<net::IOBuffer> stream_buffer_; // Maximum size of stream_buffer_ in number of chars. int stream_buffer_size_; diff --git a/net/base/gzip_filter_unittest.cc b/net/base/gzip_filter_unittest.cc index 1fe4ee4..654ef40 100644 --- a/net/base/gzip_filter_unittest.cc +++ b/net/base/gzip_filter_unittest.cc @@ -174,7 +174,7 @@ class GZipUnitTest : public PlatformTest { int encode_data_len; encode_data_len = std::min(encode_avail_size, filter->stream_buffer_size()); - memcpy(filter->stream_buffer(), encode_next, encode_data_len); + memcpy(filter->stream_buffer()->data(), encode_next, encode_data_len); filter->FlushStreamBuffer(encode_data_len); encode_next += encode_data_len; encode_avail_size -= encode_data_len; @@ -208,7 +208,7 @@ class GZipUnitTest : public PlatformTest { // into the buffer. int DecodeAllWithFilter(Filter* filter, const char* source, int source_len, char* dest, int* dest_len) { - memcpy(filter->stream_buffer(), source, source_len); + memcpy(filter->stream_buffer()->data(), source, source_len); filter->FlushStreamBuffer(source_len); return filter->ReadData(dest, dest_len); } @@ -232,7 +232,8 @@ TEST_F(GZipUnitTest, DecodeDeflate) { filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); scoped_ptr<Filter> filter(Filter::Factory(filter_types, kDefaultBufferSize)); ASSERT_TRUE(filter.get()); - memcpy(filter->stream_buffer(), deflate_encode_buffer_, deflate_encode_len_); + memcpy(filter->stream_buffer()->data(), deflate_encode_buffer_, + deflate_encode_len_); filter->FlushStreamBuffer(deflate_encode_len_); char deflate_decode_buffer[kDefaultBufferSize]; @@ -251,7 +252,8 @@ TEST_F(GZipUnitTest, DecodeGZip) { filter_types.push_back(Filter::FILTER_TYPE_GZIP); scoped_ptr<Filter> filter(Filter::Factory(filter_types, kDefaultBufferSize)); ASSERT_TRUE(filter.get()); - memcpy(filter->stream_buffer(), gzip_encode_buffer_, gzip_encode_len_); + memcpy(filter->stream_buffer()->data(), gzip_encode_buffer_, + gzip_encode_len_); filter->FlushStreamBuffer(gzip_encode_len_); char gzip_decode_buffer[kDefaultBufferSize]; @@ -275,7 +277,8 @@ TEST_F(GZipUnitTest, DecodeGZipWithMistakenSdch) { filter_types.push_back(Filter::FILTER_TYPE_GZIP); scoped_ptr<Filter> filter(Filter::Factory(filter_types, kDefaultBufferSize)); ASSERT_TRUE(filter.get()); - memcpy(filter->stream_buffer(), gzip_encode_buffer_, gzip_encode_len_); + memcpy(filter->stream_buffer()->data(), gzip_encode_buffer_, + gzip_encode_len_); filter->FlushStreamBuffer(gzip_encode_len_); char gzip_decode_buffer[kDefaultBufferSize]; diff --git a/net/base/io_buffer.h b/net/base/io_buffer.h new file mode 100644 index 0000000..b390103 --- /dev/null +++ b/net/base/io_buffer.h @@ -0,0 +1,32 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_IO_BUFFER_H_ +#define NET_BASE_IO_BUFFER_H_ + +#include "base/ref_counted.h" + +namespace net { + +// This is a simple wrapper around a buffer that provides ref counting for +// easier asynchronous IO handling. +class IOBuffer : public base::RefCountedThreadSafe<IOBuffer> { + public: + explicit IOBuffer(int buffer_size) { + data_ = new char[buffer_size]; + } + explicit IOBuffer(char* buffer) : data_(buffer) {} + virtual ~IOBuffer() { + delete[] data_; + } + + char* data() { return data_; } + + protected: + char* data_; +}; + +} // namespace net + +#endif // NET_BASE_IO_BUFFER_H_ diff --git a/net/base/sdch_filter_unittest.cc b/net/base/sdch_filter_unittest.cc index 21d9aee..b5c31c2 100644 --- a/net/base/sdch_filter_unittest.cc +++ b/net/base/sdch_filter_unittest.cc @@ -101,7 +101,7 @@ static bool FilterTestData(const std::string& source, do { int copy_amount = std::min(input_amount, source.size() - source_index); if (copy_amount > 0 && status == Filter::FILTER_NEED_MORE_DATA) { - memcpy(filter->stream_buffer(), source.data() + source_index, + memcpy(filter->stream_buffer()->data(), source.data() + source_index, copy_amount); filter->FlushStreamBuffer(copy_amount); source_index += copy_amount; @@ -152,7 +152,7 @@ TEST_F(SdchFilterTest, BasicBadDictionary) { // Dictionary hash is 8 characters followed by a null. std::string dictionary_hash_prefix("123"); - char* input_buffer = filter->stream_buffer(); + char* input_buffer = filter->stream_buffer()->data(); int input_buffer_size = filter->stream_buffer_size(); EXPECT_EQ(kInputBufferSize, input_buffer_size); diff --git a/net/build/net.vcproj b/net/build/net.vcproj index 7faf5c7..811eb1b 100644 --- a/net/build/net.vcproj +++ b/net/build/net.vcproj @@ -309,6 +309,10 @@ > </File> <File + RelativePath="..\base\io_buffer.h" + > + </File> + <File RelativePath="..\base\listen_socket.cc" > </File> diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 7edc0a8..fe0a130 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -190,7 +190,7 @@ class HttpCache::Transaction : public HttpTransaction { virtual int RestartWithAuth(const std::wstring& username, const std::wstring& password, CompletionCallback* callback); - virtual int Read(char* buf, int buf_len, CompletionCallback*); + virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback*); virtual const HttpResponseInfo* GetResponseInfo() const; virtual LoadState GetLoadState() const; virtual uint64 GetUploadProgress(void) const; @@ -411,7 +411,7 @@ int HttpCache::Transaction::RestartWithAuth( return rv; } -int HttpCache::Transaction::Read(char* buf, int buf_len, +int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, CompletionCallback* callback) { DCHECK(buf); DCHECK(buf_len > 0); @@ -435,20 +435,23 @@ int HttpCache::Transaction::Read(char* buf, int buf_len, case WRITE: DCHECK(network_trans_.get()); rv = network_trans_->Read(buf, buf_len, &network_read_callback_); - read_buf_ = buf; + read_buf_ = buf->data(); if (rv >= 0) OnNetworkReadCompleted(rv); break; case READ: DCHECK(entry_); - cache_read_callback_->AddRef(); // Balanced in OnCacheReadCompleted + cache_read_callback_->AddRef(); // Balanced in OnCacheReadCompleted. + cache_read_callback_->UseBuffer(buf); rv = entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, - buf, buf_len, cache_read_callback_); - read_buf_ = buf; + buf->data(), buf_len, + cache_read_callback_); + read_buf_ = buf->data(); if (rv >= 0) { OnCacheReadCompleted(rv); } else if (rv != ERR_IO_PENDING) { cache_read_callback_->Release(); + cache_read_callback_->ReleaseBuffer(); } break; default: @@ -903,7 +906,8 @@ void HttpCache::Transaction::OnNetworkReadCompleted(int result) { void HttpCache::Transaction::OnCacheReadCompleted(int result) { DCHECK(cache_); - cache_read_callback_->Release(); // Balance the AddRef() from Start() + cache_read_callback_->Release(); // Balance the AddRef() from Start(). + cache_read_callback_->ReleaseBuffer(); if (result > 0) { read_offset_ += result; diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index be6986e..0a71854 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -676,8 +676,8 @@ TEST(HttpCache, SimpleGET_AbandonedCacheRead) { rv = callback.WaitForResult(); ASSERT_EQ(net::OK, rv); - char buf[256]; - rv = trans->Read(buf, sizeof(buf), &callback); + scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(256); + rv = trans->Read(buf, 256, &callback); EXPECT_EQ(net::ERR_IO_PENDING, rv); // Test that destroying the transaction while it is reading from the cache diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 9d6ed1b..2e96deb 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -52,7 +52,6 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, header_buf_http_offset_(-1), content_length_(-1), // -1 means unspecified. content_read_(0), - read_buf_(NULL), read_buf_len_(0), next_state_(STATE_NONE) { #if defined(OS_WIN) @@ -134,7 +133,7 @@ void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { ResetStateForRestart(); } -int HttpNetworkTransaction::Read(char* buf, int buf_len, +int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, CompletionCallback* callback) { DCHECK(response_.headers); DCHECK(buf); @@ -726,7 +725,7 @@ int HttpNetworkTransaction::DoReadBody() { // We may have some data remaining in the header buffer. if (header_buf_.get() && header_buf_body_offset_ < header_buf_len_) { int n = std::min(read_buf_len_, header_buf_len_ - header_buf_body_offset_); - memcpy(read_buf_, header_buf_.get() + header_buf_body_offset_, n); + memcpy(read_buf_->data(), header_buf_.get() + header_buf_body_offset_, n); header_buf_body_offset_ += n; if (header_buf_body_offset_ == header_buf_len_) { header_buf_.reset(); @@ -737,7 +736,8 @@ int HttpNetworkTransaction::DoReadBody() { return n; } - return connection_.socket()->Read(read_buf_, read_buf_len_, &io_callback_); + return connection_.socket()->Read(read_buf_->data(), read_buf_len_, + &io_callback_); } int HttpNetworkTransaction::DoReadBodyComplete(int result) { @@ -747,7 +747,7 @@ int HttpNetworkTransaction::DoReadBodyComplete(int result) { // Filter incoming data if appropriate. FilterBuf may return an error. if (result > 0 && chunked_decoder_.get()) { - result = chunked_decoder_->FilterBuf(read_buf_, result); + result = chunked_decoder_->FilterBuf(read_buf_->data(), result); if (result == 0 && !chunked_decoder_->reached_eof()) { // Don't signal completion of the Read call yet or else it'll look like // we received end-of-file. Wait for more data. diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 487ddd3..9a4c619 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -39,7 +39,7 @@ class HttpNetworkTransaction : public HttpTransaction { virtual int RestartWithAuth(const std::wstring& username, const std::wstring& password, CompletionCallback* callback); - virtual int Read(char* buf, int buf_len, CompletionCallback* callback); + virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); virtual const HttpResponseInfo* GetResponseInfo() const; virtual LoadState GetLoadState() const; virtual uint64 GetUploadProgress() const; @@ -259,7 +259,7 @@ class HttpNetworkTransaction : public HttpTransaction { scoped_ptr<HttpChunkedDecoder> chunked_decoder_; // User buffer and length passed to the Read method. - char* read_buf_; + scoped_refptr<IOBuffer> read_buf_; int read_buf_len_; enum State { diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h index ba2cf29..46c7671 100644 --- a/net/http/http_transaction.h +++ b/net/http/http_transaction.h @@ -66,8 +66,11 @@ class HttpTransaction { // could not be read. // // NOTE: The transaction is not responsible for deleting the callback object. + // If the operation is not completed immediately, the transaction must acquire + // a reference to the provided buffer. // - virtual int Read(char* buf, int buf_len, CompletionCallback* callback) = 0; + virtual int Read(IOBuffer* buf, int buf_len, + CompletionCallback* callback) = 0; // Returns the response info for this transaction or NULL if the response // info is not available. diff --git a/net/http/http_transaction_unittest.cc b/net/http/http_transaction_unittest.cc index fdcceff..e22c398 100644 --- a/net/http/http_transaction_unittest.cc +++ b/net/http/http_transaction_unittest.cc @@ -137,12 +137,12 @@ int ReadTransaction(net::HttpTransaction* trans, std::string* result) { std::string content; do { - char buf[256]; - rv = trans->Read(buf, sizeof(buf), &callback); + scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(256); + rv = trans->Read(buf, 256, &callback); if (rv == net::ERR_IO_PENDING) rv = callback.WaitForResult(); if (rv > 0) { - content.append(buf, rv); + content.append(buf->data(), rv); } else if (rv < 0) { return rv; } diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h index ccdb954..0c26178 100644 --- a/net/http/http_transaction_unittest.h +++ b/net/http/http_transaction_unittest.h @@ -149,7 +149,7 @@ class TestTransactionConsumer : public CallbackRunner< Tuple1<int> > { if (result <= 0) { DidFinish(result); } else { - content_.append(read_buf_, result); + content_.append(read_buf_->data(), result); Read(); } } @@ -163,7 +163,8 @@ class TestTransactionConsumer : public CallbackRunner< Tuple1<int> > { void Read() { state_ = READING; - int result = trans_->Read(read_buf_, sizeof(read_buf_), this); + read_buf_ = new net::IOBuffer(1024); + int result = trans_->Read(read_buf_, 1024, this); if (result != net::ERR_IO_PENDING) DidRead(result); } @@ -177,7 +178,7 @@ class TestTransactionConsumer : public CallbackRunner< Tuple1<int> > { scoped_ptr<net::HttpTransaction> trans_; std::string content_; - char read_buf_[1024]; + scoped_refptr<net::IOBuffer> read_buf_; int error_; static int quit_counter_; @@ -237,11 +238,12 @@ class MockNetworkTransaction : public net::HttpTransaction { return net::ERR_FAILED; } - virtual int Read(char* buf, int buf_len, net::CompletionCallback* callback) { + virtual int Read(net::IOBuffer* buf, int buf_len, + net::CompletionCallback* callback) { int data_len = static_cast<int>(data_.size()); int num = std::min(buf_len, data_len - data_cursor_); if (num) { - memcpy(buf, data_.data() + data_cursor_, num); + memcpy(buf->data(), data_.data() + data_cursor_, num); data_cursor_ += num; } if (test_mode_ & TEST_MODE_SYNC_NET_READ) diff --git a/net/net_lib.scons b/net/net_lib.scons index 043db5c..099c46b 100644 --- a/net/net_lib.scons +++ b/net/net_lib.scons @@ -62,6 +62,7 @@ input_files = ChromeFileList([ 'base/gzip_header.h', 'base/host_resolver.cc', 'base/host_resolver.h', + 'base/io_buffer.h', 'base/listen_socket.cc', 'base/listen_socket.h', 'base/load_flags.h', diff --git a/net/proxy/proxy_script_fetcher.cc b/net/proxy/proxy_script_fetcher.cc index 4f9f603..b48ee1a 100644 --- a/net/proxy/proxy_script_fetcher.cc +++ b/net/proxy/proxy_script_fetcher.cc @@ -6,7 +6,9 @@ #include "base/compiler_specific.h" #include "base/message_loop.h" +#include "base/ref_counted.h" #include "base/string_util.h" +#include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/url_request/url_request.h" @@ -77,7 +79,7 @@ class ProxyScriptFetcherImpl : public ProxyScriptFetcher, // Buffer that URLRequest writes into. enum { kBufSize = 4096 }; - char buf_[kBufSize]; + scoped_refptr<net::IOBuffer> buf_; // The next ID to use for |cur_request_| (monotonically increasing). int next_id_; @@ -105,6 +107,7 @@ ProxyScriptFetcherImpl::ProxyScriptFetcherImpl( URLRequestContext* url_request_context) : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), url_request_context_(url_request_context), + buf_(new net::IOBuffer(kBufSize)), next_id_(0), cur_request_(NULL), cur_request_id_(0), @@ -217,7 +220,7 @@ void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request, request->Cancel(); return; } - result_bytes_->append(buf_, num_bytes); + result_bytes_->append(buf_->data(), num_bytes); ReadBody(request); } else { // Error while reading, or EOF OnResponseCompleted(request); diff --git a/net/url_request/mime_sniffer_proxy.cc b/net/url_request/mime_sniffer_proxy.cc index 24b1fbe..3a8d9a9 100644 --- a/net/url_request/mime_sniffer_proxy.cc +++ b/net/url_request/mime_sniffer_proxy.cc @@ -6,10 +6,13 @@ #include "net/base/mime_sniffer.h" +static const int kBufferSize = 1024; + MimeSnifferProxy::MimeSnifferProxy(URLRequest* request, URLRequest::Delegate* delegate) : request_(request), delegate_(delegate), - sniff_content_(false), error_(false) { + sniff_content_(false), error_(false), + buf_(new net::IOBuffer(kBufferSize)) { request->set_delegate(this); } @@ -20,7 +23,7 @@ void MimeSnifferProxy::OnResponseStarted(URLRequest* request) { // We need to read content before we know the mime type, // so we don't call OnResponseStarted. sniff_content_ = true; - if (request_->Read(buf_, sizeof(buf_), &bytes_read_) && bytes_read_) { + if (request_->Read(buf_, kBufferSize, &bytes_read_) && bytes_read_) { OnReadCompleted(request, bytes_read_); } else if (!request_->status().is_io_pending()) { error_ = true; @@ -32,7 +35,8 @@ void MimeSnifferProxy::OnResponseStarted(URLRequest* request) { delegate_->OnResponseStarted(request); } -bool MimeSnifferProxy::Read(char* buf, int max_bytes, int *bytes_read) { +bool MimeSnifferProxy::Read(net::IOBuffer* buf, int max_bytes, + int *bytes_read) { if (sniff_content_) { // This is the first call to Read() after we've sniffed content. // Return our local buffer or the error we ran into. @@ -43,7 +47,7 @@ bool MimeSnifferProxy::Read(char* buf, int max_bytes, int *bytes_read) { return false; } - memcpy(buf, buf_, bytes_read_); + memcpy(buf->data(), buf_->data(), bytes_read_); *bytes_read = bytes_read_; return true; } @@ -57,8 +61,8 @@ void MimeSnifferProxy::OnReadCompleted(URLRequest* request, int bytes_read) { std::string type_hint; request_->GetMimeType(&type_hint); bytes_read_ = bytes_read; - net::SniffMimeType( - buf_, bytes_read_, request_->url(), type_hint, &mime_type_); + net::SniffMimeType(buf_->data(), bytes_read_, request_->url(), + type_hint, &mime_type_); } else { error_ = true; } diff --git a/net/url_request/mime_sniffer_proxy.h b/net/url_request/mime_sniffer_proxy.h index 0029a80..898ea60 100644 --- a/net/url_request/mime_sniffer_proxy.h +++ b/net/url_request/mime_sniffer_proxy.h @@ -19,6 +19,10 @@ // 2) ms_->mime_type() -- returns the sniffed mime type of the data; // valid after OnResponseStarted() is called. +#ifndef NET_URL_REQUEST_MIME_SNIFFER_PROXY_H_ +#define NET_URL_REQUEST_MIME_SNIFFER_PROXY_H_ + +#include "net/base/io_buffer.h" #include "net/url_request/url_request.h" class MimeSnifferProxy : public URLRequest::Delegate { @@ -48,7 +52,7 @@ class MimeSnifferProxy : public URLRequest::Delegate { } // Wrapper around URLRequest::Read. - bool Read(char* buf, int max_bytes, int *bytes_read); + bool Read(net::IOBuffer* buf, int max_bytes, int *bytes_read); // Return the sniffed mime type of the request. Valid after // OnResponseStarted() has been called on the delegate. @@ -69,8 +73,9 @@ class MimeSnifferProxy : public URLRequest::Delegate { bool error_; // A buffer for the first bit of the request. - char buf_[1024]; + scoped_refptr<net::IOBuffer> buf_; // The number of bytes we've read into the buffer. int bytes_read_; }; +#endif // NET_URL_REQUEST_MIME_SNIFFER_PROXY_H_ diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 87facba..19c9810 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -252,7 +252,7 @@ void URLRequest::CancelWithError(int os_error) { // about being called recursively. } -bool URLRequest::Read(char* dest, int dest_size, int *bytes_read) { +bool URLRequest::Read(net::IOBuffer* dest, int dest_size, int *bytes_read) { DCHECK(job_); DCHECK(bytes_read); DCHECK(!job_->is_done()); diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index 5dfc711..f697362 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h @@ -21,6 +21,9 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_status.h" +namespace net { +class IOBuffer; +} class URLRequestJob; // This stores the values of the Set-Cookie headers received during the request. @@ -367,16 +370,14 @@ class URLRequest { // successful status. // If data is available, Read will return true, and the data and length will // be returned immediately. If data is not available, Read returns false, - // and an asynchronous Read is initiated. The caller guarantees the - // buffer provided will be available until the Read is finished. The - // Read is finished when the caller receives the OnReadComplete - // callback. OnReadComplete will be always be called, even if there - // was a failure. + // and an asynchronous Read is initiated. The Read is finished when + // the caller receives the OnReadComplete callback. OnReadComplete will be + // always be called, even if there was a failure. // - // The buf parameter is a buffer to receive the data. Once the read is - // initiated, the caller guarantees availability of this buffer until - // the OnReadComplete is received. The buffer must be at least - // max_bytes in length. + // The buf parameter is a buffer to receive the data. If the operation + // completes asynchronously, the implementation will reference the buffer + // until OnReadComplete is called. The buffer must be at least max_bytes in + // length. // // The max_bytes parameter is the maximum number of bytes to read. // @@ -386,7 +387,7 @@ class URLRequest { // // If a read error occurs, Read returns false and the request->status // will be set to an error. - bool Read(char* buf, int max_bytes, int *bytes_read); + bool Read(net::IOBuffer* buf, int max_bytes, int *bytes_read); // One of the following two methods should be called in response to an // OnAuthRequired() callback (and only then). diff --git a/net/url_request/url_request_file_dir_job.cc b/net/url_request/url_request_file_dir_job.cc index df24eab..1608684 100644 --- a/net/url_request/url_request_file_dir_job.cc +++ b/net/url_request/url_request_file_dir_job.cc @@ -26,7 +26,6 @@ URLRequestFileDirJob::URLRequestFileDirJob(URLRequest* request, list_complete_(false), wrote_header_(false), read_pending_(false), - read_buffer_(NULL), read_buffer_length_(0) { } @@ -68,7 +67,7 @@ void URLRequestFileDirJob::Kill() { lister_->Cancel(); } -bool URLRequestFileDirJob::ReadRawData(char* buf, int buf_size, +bool URLRequestFileDirJob::ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read) { DCHECK(bytes_read); *bytes_read = 0; @@ -76,7 +75,7 @@ bool URLRequestFileDirJob::ReadRawData(char* buf, int buf_size, if (is_done()) return true; - if (FillReadBuffer(buf, buf_size, bytes_read)) + if (FillReadBuffer(buf->data(), buf_size, bytes_read)) return true; // We are waiting for more data @@ -183,7 +182,8 @@ bool URLRequestFileDirJob::FillReadBuffer(char *buf, int buf_size, void URLRequestFileDirJob::CompleteRead() { if (read_pending_) { int bytes_read; - if (FillReadBuffer(read_buffer_, read_buffer_length_, &bytes_read)) { + if (FillReadBuffer(read_buffer_->data(), read_buffer_length_, + &bytes_read)) { // We completed the read, so reset the read buffer. read_pending_ = false; read_buffer_ = NULL; diff --git a/net/url_request/url_request_file_dir_job.h b/net/url_request/url_request_file_dir_job.h index 882f967..c3881dc 100644 --- a/net/url_request/url_request_file_dir_job.h +++ b/net/url_request/url_request_file_dir_job.h @@ -21,7 +21,7 @@ class URLRequestFileDirJob virtual void Start(); virtual void StartAsync(); virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual bool GetMimeType(std::string* mime_type); virtual bool GetCharset(std::string* charset); virtual bool IsRedirectResponse(GURL* location, int* http_status_code); @@ -55,7 +55,7 @@ class URLRequestFileDirJob // we wait for IO to complete. When done, we fill the buffer // manually. bool read_pending_; - char *read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; int read_buffer_length_; DISALLOW_EVIL_CONSTRUCTORS(URLRequestFileDirJob); diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index 994a58c..92e7f87 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc @@ -128,12 +128,12 @@ void URLRequestFileJob::Kill() { URLRequestJob::Kill(); } -bool URLRequestFileJob::ReadRawData( - char* dest, int dest_size, int *bytes_read) { +bool URLRequestFileJob::ReadRawData(net::IOBuffer* dest, int dest_size, + int *bytes_read) { DCHECK_NE(dest_size, 0); DCHECK(bytes_read); - int rv = stream_.Read(dest, dest_size, &io_callback_); + int rv = stream_.Read(dest->data(), dest_size, &io_callback_); if (rv >= 0) { // Data is immediately available. *bytes_read = rv; diff --git a/net/url_request/url_request_file_job.h b/net/url_request/url_request_file_job.h index a00e439..0ccaa5a 100644 --- a/net/url_request/url_request_file_job.h +++ b/net/url_request/url_request_file_job.h @@ -20,7 +20,7 @@ class URLRequestFileJob : public URLRequestJob { virtual void Start(); virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual bool IsRedirectResponse(GURL* location, int* http_status_code); virtual bool GetMimeType(std::string* mime_type); diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 7728f6c..7a74500 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -348,7 +348,8 @@ bool URLRequestHttpJob::GetMoreData() { return transaction_.get() && !read_in_progress_; } -bool URLRequestHttpJob::ReadRawData(char* buf, int buf_size, int *bytes_read) { +bool URLRequestHttpJob::ReadRawData(net::IOBuffer* buf, int buf_size, + int *bytes_read) { DCHECK_NE(buf_size, 0); DCHECK(bytes_read); DCHECK(!read_in_progress_); diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index eda4b4b..e53db48 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h @@ -53,7 +53,7 @@ class URLRequestHttpJob : public URLRequestJob { virtual void CancelAuth(); virtual void ContinueDespiteLastError(); virtual bool GetMoreData(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); // Shadows URLRequestJob's version of this method so we can grab cookies. void NotifyHeadersComplete(); diff --git a/net/url_request/url_request_inet_job.cc b/net/url_request/url_request_inet_job.cc index 2d45526..09abfa2 100644 --- a/net/url_request/url_request_inet_job.cc +++ b/net/url_request/url_request_inet_job.cc @@ -185,7 +185,7 @@ void URLRequestInetJob::OnIOComplete(const AsyncResult& result) { } } -bool URLRequestInetJob::ReadRawData(char* dest, int dest_size, +bool URLRequestInetJob::ReadRawData(net::IOBuffer* dest, int dest_size, int *bytes_read) { if (is_done()) return 0; @@ -196,7 +196,7 @@ bool URLRequestInetJob::ReadRawData(char* dest, int dest_size, *bytes_read = 0; - int result = CallInternetRead(dest, dest_size, bytes_read); + int result = CallInternetRead(dest->data(), dest_size, bytes_read); if (result == ERROR_SUCCESS) { DLOG(INFO) << "read " << *bytes_read << " bytes"; if (*bytes_read == 0) diff --git a/net/url_request/url_request_inet_job.h b/net/url_request/url_request_inet_job.h index 6341105..bef0c4f 100644 --- a/net/url_request/url_request_inet_job.h +++ b/net/url_request/url_request_inet_job.h @@ -29,7 +29,7 @@ class URLRequestInetJob : public URLRequestJob { } virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); // URLRequestJob Authentication methods virtual void SetAuth(const std::wstring& username, diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 6e6a1df..659156b 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc @@ -8,6 +8,7 @@ #include "base/string_util.h" #include "googleurl/src/gurl.h" #include "net/base/auth.h" +#include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job_metrics.h" @@ -97,7 +98,7 @@ void URLRequestJob::ContinueDespiteLastError() { // This function calls ReadData to get stream data. If a filter exists, passes // the data to the attached filter. Then returns the output from filter back to // the caller. -bool URLRequestJob::Read(char* buf, int buf_size, int *bytes_read) { +bool URLRequestJob::Read(net::IOBuffer* buf, int buf_size, int *bytes_read) { bool rv = false; DCHECK_LT(buf_size, 1000000); // sanity check @@ -140,7 +141,7 @@ bool URLRequestJob::ReadRawDataForFilter(int *bytes_read) { // TODO(mbelshe): is it possible that the filter needs *MORE* data // when there is some data already in the buffer? if (!filter_->stream_data_len() && !is_done()) { - char* stream_buffer = filter_->stream_buffer(); + net::IOBuffer* stream_buffer = filter_->stream_buffer(); int stream_buffer_size = filter_->stream_buffer_size(); rv = ReadRawData(stream_buffer, stream_buffer_size, bytes_read); if (rv && *bytes_read > 0) @@ -186,7 +187,7 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { // Get filtered data int filtered_data_len = read_buffer_len_; Filter::FilterStatus status; - status = filter_->ReadData(read_buffer_, &filtered_data_len); + status = filter_->ReadData(read_buffer_->data(), &filtered_data_len); switch (status) { case Filter::FILTER_DONE: { *bytes_read = filtered_data_len; @@ -242,7 +243,8 @@ bool URLRequestJob::ReadFilteredData(int *bytes_read) { return rv; } -bool URLRequestJob::ReadRawData(char* buf, int buf_size, int *bytes_read) { +bool URLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, + int *bytes_read) { DCHECK(bytes_read); *bytes_read = 0; NotifyDone(URLRequestStatus()); diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index 43fa866..0a5744b 100644 --- a/net/url_request/url_request_job.h +++ b/net/url_request/url_request_job.h @@ -17,6 +17,7 @@ namespace net { class HttpResponseInfo; +class IOBuffer; class UploadData; } @@ -78,7 +79,7 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob> { // bytes read, 0 when there is no more data, or -1 if there was an error. // This is just the backend for URLRequest::Read, see that function for more // info. - bool Read(char* buf, int buf_size, int *bytes_read); + bool Read(net::IOBuffer* buf, int buf_size, int *bytes_read); // Called to fetch the current load state for the job. virtual net::LoadState GetLoadState() const { return net::LOAD_STATE_IDLE; } @@ -231,7 +232,7 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob> { // If async IO is pending, the status of the request will be // URLRequestStatus::IO_PENDING, and buf must remain available until the // operation is completed. See comments on URLRequest::Read for more info. - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); // Informs the filter that data has been read into its buffer void FilteredDataRead(int bytes_read); @@ -289,7 +290,7 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob> { // processing the filtered data, we return the data in the caller's buffer. // While the async IO is in progress, we save the user buffer here, and // when the IO completes, we fill this in. - char *read_buffer_; + net::IOBuffer *read_buffer_; int read_buffer_len_; // Used by HandleResponseIfNecessary to track whether we've sent the diff --git a/net/url_request/url_request_simple_job.cc b/net/url_request/url_request_simple_job.cc index ae078b3..a4ef4e1 100644 --- a/net/url_request/url_request_simple_job.cc +++ b/net/url_request/url_request_simple_job.cc @@ -29,13 +29,13 @@ bool URLRequestSimpleJob::GetCharset(std::string* charset) { return true; } -bool URLRequestSimpleJob::ReadRawData(char* buf, int buf_size, +bool URLRequestSimpleJob::ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) { DCHECK(bytes_read); int remaining = static_cast<int>(data_.size()) - data_offset_; if (buf_size > remaining) buf_size = remaining; - memcpy(buf, data_.data() + data_offset_, buf_size); + memcpy(buf->data(), data_.data() + data_offset_, buf_size); data_offset_ += buf_size; *bytes_read = buf_size; return true; diff --git a/net/url_request/url_request_simple_job.h b/net/url_request/url_request_simple_job.h index 4cb847c..183598a 100644 --- a/net/url_request/url_request_simple_job.h +++ b/net/url_request/url_request_simple_job.h @@ -13,7 +13,7 @@ class URLRequestSimpleJob : public URLRequestJob { URLRequestSimpleJob(URLRequest* request); virtual void Start(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual bool GetMimeType(std::string* mime_type); virtual bool GetCharset(std::string* charset); diff --git a/net/url_request/url_request_test_job.cc b/net/url_request/url_request_test_job.cc index d544ce4..eda77a7 100644 --- a/net/url_request/url_request_test_job.cc +++ b/net/url_request/url_request_test_job.cc @@ -93,7 +93,8 @@ void URLRequestTestJob::StartAsync() { this->NotifyHeadersComplete(); } -bool URLRequestTestJob::ReadRawData(char* buf, int buf_size, int *bytes_read) { +bool URLRequestTestJob::ReadRawData(net::IOBuffer* buf, int buf_size, + int *bytes_read) { if (stage_ == WAITING) { async_buf_ = buf; async_buf_size_ = buf_size; @@ -112,7 +113,7 @@ bool URLRequestTestJob::ReadRawData(char* buf, int buf_size, int *bytes_read) { if (to_read + offset_ > static_cast<int>(data_.length())) to_read = static_cast<int>(data_.length()) - offset_; - memcpy(buf, &data_.c_str()[offset_], to_read); + memcpy(buf->data(), &data_.c_str()[offset_], to_read); offset_ += to_read; *bytes_read = to_read; diff --git a/net/url_request/url_request_test_job.h b/net/url_request/url_request_test_job.h index ad69123..4cbf37e 100644 --- a/net/url_request/url_request_test_job.h +++ b/net/url_request/url_request_test_job.h @@ -51,7 +51,7 @@ class URLRequestTestJob : public URLRequestJob { // Job functions virtual void Start(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual void Kill(); virtual bool GetMimeType(std::string* mime_type); virtual void GetResponseInfo(net::HttpResponseInfo* info); @@ -78,7 +78,7 @@ class URLRequestTestJob : public URLRequestJob { int offset_; // Holds the buffer for an asynchronous ReadRawData call - char* async_buf_; + net::IOBuffer* async_buf_; int async_buf_size_; }; diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h index 58a0218..9389ce8 100644 --- a/net/url_request/url_request_unittest.h +++ b/net/url_request/url_request_unittest.h @@ -21,6 +21,7 @@ #include "base/thread.h" #include "base/time.h" #include "base/waitable_event.h" +#include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/http/http_network_layer.h" #include "net/url_request/url_request.h" @@ -62,7 +63,8 @@ class TestDelegate : public URLRequest::Delegate { received_bytes_count_(0), received_redirect_count_(0), received_data_before_response_(false), - request_failed_(false) { + request_failed_(false), + buf_(new net::IOBuffer(kBufferSize)) { } virtual void OnReceivedRedirect(URLRequest* request, const GURL& new_url) { @@ -87,7 +89,7 @@ class TestDelegate : public URLRequest::Delegate { } else { // Initiate the first read. int bytes_read = 0; - if (request->Read(buf_, sizeof(buf_), &bytes_read)) + if (request->Read(buf_, kBufferSize, &bytes_read)) OnReadCompleted(request, bytes_read); else if (!request->status().is_io_pending()) OnResponseCompleted(request); @@ -109,15 +111,15 @@ class TestDelegate : public URLRequest::Delegate { received_bytes_count_ += bytes_read; // consume the data - data_received_.append(buf_, bytes_read); + data_received_.append(buf_->data(), bytes_read); } // If it was not end of stream, request to read more. if (request->status().is_success() && bytes_read > 0) { bytes_read = 0; - while (request->Read(buf_, sizeof(buf_), &bytes_read)) { + while (request->Read(buf_, kBufferSize, &bytes_read)) { if (bytes_read > 0) { - data_received_.append(buf_, bytes_read); + data_received_.append(buf_->data(), bytes_read); received_bytes_count_ += bytes_read; } else { break; @@ -173,6 +175,7 @@ class TestDelegate : public URLRequest::Delegate { bool request_failed() const { return request_failed_; } private: + static const int kBufferSize = 4096; // options for controlling behavior bool cancel_in_rr_; bool cancel_in_rs_; @@ -192,7 +195,7 @@ class TestDelegate : public URLRequest::Delegate { std::string data_received_; // our read buffer - char buf_[4096]; + scoped_refptr<net::IOBuffer> buf_; }; // This object bounds the lifetime of an external python-based HTTP/FTP server diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 2f66f75..e5b1aff 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -37,6 +37,7 @@ #include "base/thread.h" #include "base/waitable_event.h" #include "net/base/cookie_monster.h" +#include "net/base/io_buffer.h" #include "net/base/net_util.h" #include "net/base/upload_data.h" #include "net/url_request/url_request.h" @@ -104,7 +105,7 @@ class RequestProxy : public URLRequest::Delegate, public base::RefCountedThreadSafe<RequestProxy> { public: // Takes ownership of the params. - RequestProxy() { + RequestProxy() : buf_(new net::IOBuffer(kDataSize)) { } virtual ~RequestProxy() { @@ -155,7 +156,7 @@ class RequestProxy : public URLRequest::Delegate, // Make a local copy of buf_, since AsyncReadData reuses it. scoped_array<char> buf_copy(new char[bytes_read]); - memcpy(buf_copy.get(), buf_, bytes_read); + memcpy(buf_copy.get(), buf_->data(), bytes_read); // Continue reading more data into buf_ // Note: Doing this before notifying our peer ensures our load events get @@ -211,7 +212,7 @@ class RequestProxy : public URLRequest::Delegate, if (request_->status().is_success()) { int bytes_read; - if (request_->Read(buf_, sizeof(buf_), &bytes_read) && bytes_read) { + if (request_->Read(buf_, kDataSize, &bytes_read) && bytes_read) { OnReceivedData(bytes_read); } else if (!request_->status().is_io_pending()) { Done(); @@ -296,7 +297,7 @@ class RequestProxy : public URLRequest::Delegate, static const int kDataSize = 16*1024; // read buffer for async IO - char buf_[kDataSize]; + scoped_refptr<net::IOBuffer> buf_; MessageLoop* owner_loop_; @@ -333,7 +334,7 @@ class SyncRequestProxy : public RequestProxy { } virtual void OnReceivedData(int bytes_read) { - result_->data.append(buf_, bytes_read); + result_->data.append(buf_->data(), bytes_read); AsyncReadData(); // read more (may recurse) } |