diff options
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) } |