From df30f130d3651a1b390e510b0a3d4eb9fa5011e8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 30 Aug 2013 20:02:17 +0800 Subject: [PATCH] Separate logics between low level URLRequestJob and js calls. --- atom.gyp | 2 + browser/api/atom_api_protocol.cc | 164 ++++----------------------- browser/net/adapter_request_job.cc | 118 +++++++++++++++++++ browser/net/adapter_request_job.h | 76 +++++++++++++ browser/net/url_request_string_job.h | 4 +- 5 files changed, 221 insertions(+), 143 deletions(-) create mode 100644 browser/net/adapter_request_job.cc create mode 100644 browser/net/adapter_request_job.h diff --git a/atom.gyp b/atom.gyp index ee5a10a7d4..51a8889512 100644 --- a/atom.gyp +++ b/atom.gyp @@ -97,6 +97,8 @@ 'browser/native_window_win.cc', 'browser/native_window_win.h', 'browser/native_window_observer.h', + 'browser/net/adapter_request_job.cc', + 'browser/net/adapter_request_job.h', 'browser/net/atom_url_request_job_factory.cc', 'browser/net/atom_url_request_job_factory.h', 'browser/net/url_request_string_job.cc', diff --git a/browser/api/atom_api_protocol.cc b/browser/api/atom_api_protocol.cc index 91f47b4295..b982c7537e 100644 --- a/browser/api/atom_api_protocol.cc +++ b/browser/api/atom_api_protocol.cc @@ -4,15 +4,12 @@ #include "browser/api/atom_api_protocol.h" -#include "base/memory/weak_ptr.h" #include "browser/atom_browser_context.h" +#include "browser/net/adapter_request_job.h" #include "browser/net/atom_url_request_job_factory.h" -#include "browser/net/url_request_string_job.h" #include "content/public/browser/browser_thread.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_error_job.h" -#include "net/url_request/url_request_file_job.h" #include "vendor/node/src/node.h" #include "vendor/node/src/node_internals.h" @@ -64,79 +61,16 @@ AtomURLRequestJobFactory* GetRequestJobFactory() { GetRequestContext()->GetURLRequestContext()->job_factory())); } -// Ask JS which type of job it wants, and then delegate corresponding methods. -class AdapterRequestJob : public net::URLRequestJob { +class CustomProtocolRequestJob : public AdapterRequestJob { public: - AdapterRequestJob(ProtocolHandler* protocol_handler, - net::URLRequest* request, - net::NetworkDelegate* network_delegate) - : URLRequestJob(request, network_delegate), - protocol_handler_(protocol_handler), - weak_factory_(this) { + CustomProtocolRequestJob(ProtocolHandler* protocol_handler, + net::URLRequest* request, + net::NetworkDelegate* network_delegate) + : AdapterRequestJob(protocol_handler, request, network_delegate) { } - protected: - // net::URLRequestJob: - virtual void Start() OVERRIDE { - DCHECK(!real_job_); - content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, - base::Bind(&AdapterRequestJob::GetJobTypeInUI, - weak_factory_.GetWeakPtr())); - } - - virtual void Kill() OVERRIDE { - DCHECK(real_job_); - real_job_->Kill(); - } - - virtual bool ReadRawData(net::IOBuffer* buf, - int buf_size, - int *bytes_read) OVERRIDE { - DCHECK(real_job_); - // The ReadRawData is a protected method. - switch (type_) { - case REQUEST_STRING_JOB: - return static_cast(real_job_.get())-> - ReadRawData(buf, buf_size, bytes_read); - case REQUEST_FILE_JOB: - return static_cast(real_job_.get())-> - ReadRawData(buf, buf_size, bytes_read); - default: - return net::URLRequestJob::ReadRawData(buf, buf_size, bytes_read); - } - } - - virtual bool IsRedirectResponse(GURL* location, - int* http_status_code) OVERRIDE { - DCHECK(real_job_); - return real_job_->IsRedirectResponse(location, http_status_code); - } - - virtual net::Filter* SetupFilter() const OVERRIDE { - DCHECK(real_job_); - return real_job_->SetupFilter(); - } - - virtual bool GetMimeType(std::string* mime_type) const OVERRIDE { - DCHECK(real_job_); - return real_job_->GetMimeType(mime_type); - } - - virtual bool GetCharset(std::string* charset) OVERRIDE { - DCHECK(real_job_); - return real_job_->GetCharset(charset); - } - - private: - enum JOB_TYPE { - REQUEST_ERROR_JOB, - REQUEST_STRING_JOB, - REQUEST_FILE_JOB, - }; - - void GetJobTypeInUI() { + // AdapterRequestJob: + virtual void GetJobTypeInUI() OVERRIDE { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); // Call the JS handler. @@ -154,7 +88,7 @@ class AdapterRequestJob : public net::URLRequestJob { content::BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateStringJobAndStart, - weak_factory_.GetWeakPtr(), + GetWeakPtr(), "text/plain", "UTF-8", data)); @@ -174,7 +108,7 @@ class AdapterRequestJob : public net::URLRequestJob { content::BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateStringJobAndStart, - weak_factory_.GetWeakPtr(), + GetWeakPtr(), mime_type, charset, data)); @@ -187,106 +121,54 @@ class AdapterRequestJob : public net::URLRequestJob { content::BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateFileJobAndStart, - weak_factory_.GetWeakPtr(), + GetWeakPtr(), path)); return; } } // Try the default protocol handler if we have. - if (protocol_handler_) + if (default_protocol_handler()) content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateJobFromProtocolHandlerAndStart, - weak_factory_.GetWeakPtr(), - protocol_handler_)); + GetWeakPtr())); // Fallback to the not implemented error. content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateErrorJobAndStart, - weak_factory_.GetWeakPtr(), + GetWeakPtr(), net::ERR_NOT_IMPLEMENTED)); } - - void CreateErrorJobAndStart(int error_code) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - - type_ = REQUEST_ERROR_JOB; - real_job_ = new net::URLRequestErrorJob( - request(), network_delegate(), error_code); - real_job_->Start(); - } - - void CreateStringJobAndStart(const std::string& mime_type, - const std::string& charset, - const std::string& data) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - - type_ = REQUEST_STRING_JOB; - real_job_ = new URLRequestStringJob( - request(), network_delegate(), mime_type, charset, data); - real_job_->Start(); - } - - void CreateFileJobAndStart(const base::FilePath& path) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - - type_ = REQUEST_FILE_JOB; - real_job_ = new net::URLRequestFileJob(request(), network_delegate(), path); - real_job_->Start(); - } - - void CreateJobFromProtocolHandlerAndStart(ProtocolHandler* protocol_handler) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - DCHECK(protocol_handler_); - real_job_ = protocol_handler->MaybeCreateJob(request(), - network_delegate()); - if (!real_job_) - CreateErrorJobAndStart(net::ERR_NOT_IMPLEMENTED); - else - real_job_->Start(); - } - - scoped_refptr real_job_; - - // Type of the delegated url request job. - JOB_TYPE type_; - - // Default protocol handler. - ProtocolHandler* protocol_handler_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AdapterRequestJob); }; -// Always return the same AdapterRequestJob for all requests, because the -// content API needs the ProtocolHandler to return a job immediately, and +// Always return the same CustomProtocolRequestJob for all requests, because +// the content API needs the ProtocolHandler to return a job immediately, and // getting the real job from the JS requires asynchronous calls, so we have // to create an adapter job first. // Users can also pass an extra ProtocolHandler as the fallback one when // registered handler doesn't want to deal with the request. -class AdapterProtocolHandler : public ProtocolHandler { +class CustomProtocolHandler : public ProtocolHandler { public: - AdapterProtocolHandler(ProtocolHandler* protocol_handler = NULL) + CustomProtocolHandler(ProtocolHandler* protocol_handler = NULL) : protocol_handler_(protocol_handler) { } virtual net::URLRequestJob* MaybeCreateJob( net::URLRequest* request, net::NetworkDelegate* network_delegate) const OVERRIDE { - return new AdapterRequestJob(protocol_handler_.get(), - request, - network_delegate); + return new CustomProtocolRequestJob(protocol_handler_.get(), + request, + network_delegate); } private: scoped_ptr protocol_handler_; - DISALLOW_COPY_AND_ASSIGN(AdapterProtocolHandler); + DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler); }; } // namespace @@ -356,7 +238,7 @@ v8::Handle Protocol::UninterceptProtocol(const v8::Arguments& args) { void Protocol::RegisterProtocolInIO(const std::string& scheme) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); AtomURLRequestJobFactory* job_factory(GetRequestJobFactory()); - job_factory->SetProtocolHandler(scheme, new AdapterProtocolHandler); + job_factory->SetProtocolHandler(scheme, new CustomProtocolHandler); content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, diff --git a/browser/net/adapter_request_job.cc b/browser/net/adapter_request_job.cc new file mode 100644 index 0000000000..382325b127 --- /dev/null +++ b/browser/net/adapter_request_job.cc @@ -0,0 +1,118 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/net/adapter_request_job.h" + +#include "browser/net/url_request_string_job.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request_error_job.h" +#include "net/url_request/url_request_file_job.h" + +namespace atom { + +AdapterRequestJob::AdapterRequestJob(ProtocolHandler* protocol_handler, + net::URLRequest* request, + net::NetworkDelegate* network_delegate) + : URLRequestJob(request, network_delegate), + protocol_handler_(protocol_handler), + weak_factory_(this) { +} + +void AdapterRequestJob::Start() { + DCHECK(!real_job_); + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&AdapterRequestJob::GetJobTypeInUI, + weak_factory_.GetWeakPtr())); +} + +void AdapterRequestJob::Kill() { + DCHECK(real_job_); + real_job_->Kill(); +} + +bool AdapterRequestJob::ReadRawData(net::IOBuffer* buf, + int buf_size, + int *bytes_read) { + DCHECK(real_job_); + // The ReadRawData is a protected method. + switch (type_) { + case REQUEST_STRING_JOB: + return static_cast(real_job_.get())-> + ReadRawData(buf, buf_size, bytes_read); + case REQUEST_FILE_JOB: + return static_cast(real_job_.get())-> + ReadRawData(buf, buf_size, bytes_read); + default: + return net::URLRequestJob::ReadRawData(buf, buf_size, bytes_read); + } +} + +bool AdapterRequestJob::IsRedirectResponse(GURL* location, + int* http_status_code) { + DCHECK(real_job_); + return real_job_->IsRedirectResponse(location, http_status_code); +} + +net::Filter* AdapterRequestJob::SetupFilter() const { + DCHECK(real_job_); + return real_job_->SetupFilter(); +} + +bool AdapterRequestJob::GetMimeType(std::string* mime_type) const { + DCHECK(real_job_); + return real_job_->GetMimeType(mime_type); +} + +bool AdapterRequestJob::GetCharset(std::string* charset) { + DCHECK(real_job_); + return real_job_->GetCharset(charset); +} + +base::WeakPtr AdapterRequestJob::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void AdapterRequestJob::CreateErrorJobAndStart(int error_code) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + type_ = REQUEST_ERROR_JOB; + real_job_ = new net::URLRequestErrorJob( + request(), network_delegate(), error_code); + real_job_->Start(); +} + +void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type, + const std::string& charset, + const std::string& data) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + type_ = REQUEST_STRING_JOB; + real_job_ = new URLRequestStringJob( + request(), network_delegate(), mime_type, charset, data); + real_job_->Start(); +} + +void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + type_ = REQUEST_FILE_JOB; + real_job_ = new net::URLRequestFileJob(request(), network_delegate(), path); + real_job_->Start(); +} + +void AdapterRequestJob::CreateJobFromProtocolHandlerAndStart() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + DCHECK(protocol_handler_); + real_job_ = protocol_handler_->MaybeCreateJob(request(), + network_delegate()); + if (!real_job_) + CreateErrorJobAndStart(net::ERR_NOT_IMPLEMENTED); + else + real_job_->Start(); +} + +} // namespace atom diff --git a/browser/net/adapter_request_job.h b/browser/net/adapter_request_job.h new file mode 100644 index 0000000000..af03755a23 --- /dev/null +++ b/browser/net/adapter_request_job.h @@ -0,0 +1,76 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NET_ADAPTER_REQUEST_JOB_H_ +#define ATOM_BROWSER_NET_ADAPTER_REQUEST_JOB_H_ + +#include "base/memory/weak_ptr.h" +#include "net/url_request/url_request_job.h" +#include "net/url_request/url_request_job_factory.h" + +namespace base { +class FilePath; +} + +namespace atom { + +// Ask JS which type of job it wants, and then delegate corresponding methods. +class AdapterRequestJob : public net::URLRequestJob { + public: + typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler; + + AdapterRequestJob(ProtocolHandler* protocol_handler, + net::URLRequest* request, + net::NetworkDelegate* network_delegate); + + public: + // net::URLRequestJob: + virtual void Start() OVERRIDE; + virtual void Kill() OVERRIDE; + virtual bool ReadRawData(net::IOBuffer* buf, + int buf_size, + int *bytes_read) OVERRIDE; + virtual bool IsRedirectResponse(GURL* location, + int* http_status_code) OVERRIDE; + virtual net::Filter* SetupFilter() const OVERRIDE; + virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; + virtual bool GetCharset(std::string* charset) OVERRIDE; + + base::WeakPtr GetWeakPtr(); + + ProtocolHandler* default_protocol_handler() { return protocol_handler_; } + + // Override this function to determine which job should be started. + virtual void GetJobTypeInUI() = 0; + + void CreateErrorJobAndStart(int error_code); + void CreateStringJobAndStart(const std::string& mime_type, + const std::string& charset, + const std::string& data); + void CreateFileJobAndStart(const base::FilePath& path); + void CreateJobFromProtocolHandlerAndStart(); + + private: + enum JOB_TYPE { + REQUEST_ERROR_JOB, + REQUEST_STRING_JOB, + REQUEST_FILE_JOB, + }; + + scoped_refptr real_job_; + + // Type of the delegated url request job. + JOB_TYPE type_; + + // Default protocol handler. + ProtocolHandler* protocol_handler_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(AdapterRequestJob); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_ADAPTER_REQUEST_JOB_H_ diff --git a/browser/net/url_request_string_job.h b/browser/net/url_request_string_job.h index 688f5f9b73..b2fb61024e 100644 --- a/browser/net/url_request_string_job.h +++ b/browser/net/url_request_string_job.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/url_request/url_request_simple_job.h" - #ifndef ATOM_BROWSER_NET_URL_REQUEST_STRING_JOB_H_ #define ATOM_BROWSER_NET_URL_REQUEST_STRING_JOB_H_ +#include "net/url_request/url_request_simple_job.h" + namespace atom { class URLRequestStringJob : public net::URLRequestSimpleJob {