Commit 65dcdc57 authored by shalev@chromium.org's avatar shalev@chromium.org

Replaced static URLRequestFileJob factory with non-static protocol handler for File jobs

This is a refactor and shouldn't have any visible behavioral change.

BUG=crbug.com/142945
TEST=browser_tests --single_process --gtest_filter=FullscreenControllerTest.FullscreenFileURL

Review URL: https://chromiumcodereview.appspot.com/10700117

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152381 0039d316-1c4b-4281-b951-d872f2087c98
parent 37cfa2aa
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h" #include "net/http/http_response_info.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h" #include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h" #include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_simple_job.h" #include "net/url_request/url_request_simple_job.h"
...@@ -195,7 +196,9 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { ...@@ -195,7 +196,9 @@ class URLRequestExtensionJob : public net::URLRequestFileJob {
const FilePath& directory_path, const FilePath& directory_path,
const std::string& content_security_policy, const std::string& content_security_policy,
bool send_cors_header) bool send_cors_header)
: net::URLRequestFileJob(request, FilePath()), : net::URLRequestFileJob(request,
FilePath(),
request->context()->network_delegate()),
// TODO(tc): Move all of these files into resources.pak so we don't break // TODO(tc): Move all of these files into resources.pak so we don't break
// when updating on Linux. // when updating on Linux.
resource_(extension_id, directory_path, resource_(extension_id, directory_path,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_file_util.h" #include "chrome/common/extensions/extension_file_util.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_file_job.h" #include "net/url_request/url_request_file_job.h"
namespace { namespace {
...@@ -16,8 +17,10 @@ namespace { ...@@ -16,8 +17,10 @@ namespace {
class ExtensionResourcesJob : public net::URLRequestFileJob { class ExtensionResourcesJob : public net::URLRequestFileJob {
public: public:
explicit ExtensionResourcesJob(net::URLRequest* request) explicit ExtensionResourcesJob(net::URLRequest* request)
: net::URLRequestFileJob(request, FilePath()), : net::URLRequestFileJob(request,
thread_id_(content::BrowserThread::UI) { FilePath(),
request->context()->network_delegate()),
thread_id_(content::BrowserThread::UI) {
} }
virtual void Start() OVERRIDE; virtual void Start() OVERRIDE;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/chrome_network_delegate.h"
#include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include "net/ftp/ftp_network_layer.h" #include "net/ftp/ftp_network_layer.h"
#include "net/http/http_cache.h" #include "net/http/http_cache.h"
#include "net/http/http_server_properties_impl.h" #include "net/http/http_server_properties_impl.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory.h"
#include "webkit/database/database_tracker.h" #include "webkit/database/database_tracker.h"
...@@ -251,6 +253,27 @@ void OffTheRecordProfileIOData::LazyInitializeInternal( ...@@ -251,6 +253,27 @@ void OffTheRecordProfileIOData::LazyInitializeInternal(
main_job_factory_.reset(new net::URLRequestJobFactory); main_job_factory_.reset(new net::URLRequestJobFactory);
extensions_job_factory_.reset(new net::URLRequestJobFactory); extensions_job_factory_.reset(new net::URLRequestJobFactory);
int set_protocol = main_job_factory_->SetProtocolHandler(
chrome::kFileScheme, new net::FileProtocolHandler(network_delegate()));
DCHECK(set_protocol);
// TODO(shalev): Without a network_delegate this protocol handler will never
// handle file: requests, but as a side effect it makes
// job_factory::IsHandledProtocol return true, which prevents attempts to
// handle the protocol externally.
set_protocol = extensions_job_factory_->SetProtocolHandler(
chrome::kFileScheme, new net::FileProtocolHandler(NULL));
DCHECK(set_protocol);
set_protocol = main_job_factory_->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(),
network_delegate()));
DCHECK(set_protocol);
set_protocol = extensions_job_factory_->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), NULL));
DCHECK(set_protocol);
net::URLRequestJobFactory* job_factories[2]; net::URLRequestJobFactory* job_factories[2];
job_factories[0] = main_job_factory_.get(); job_factories[0] = main_job_factory_.get();
job_factories[1] = extensions_job_factory_.get(); job_factories[1] = extensions_job_factory_.get();
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "chrome/browser/net/sqlite_server_bound_cert_store.h" #include "chrome/browser/net/sqlite_server_bound_cert_store.h"
#include "chrome/browser/prefs/pref_member.h" #include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
#include "net/base/server_bound_cert_service.h" #include "net/base/server_bound_cert_service.h"
#include "net/ftp/ftp_network_layer.h" #include "net/ftp/ftp_network_layer.h"
#include "net/http/http_cache.h" #include "net/http/http_cache.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory.h"
#include "webkit/quota/special_storage_policy.h" #include "webkit/quota/special_storage_policy.h"
...@@ -449,6 +451,35 @@ void ProfileImplIOData::LazyInitializeInternal( ...@@ -449,6 +451,35 @@ void ProfileImplIOData::LazyInitializeInternal(
media_request_job_factory_.reset(new net::URLRequestJobFactory); media_request_job_factory_.reset(new net::URLRequestJobFactory);
extensions_job_factory_.reset(new net::URLRequestJobFactory); extensions_job_factory_.reset(new net::URLRequestJobFactory);
int set_protocol = main_job_factory_->SetProtocolHandler(
chrome::kFileScheme, new net::FileProtocolHandler(network_delegate()));
DCHECK(set_protocol);
set_protocol = media_request_job_factory_->SetProtocolHandler(
chrome::kFileScheme, new net::FileProtocolHandler(network_delegate()));
DCHECK(set_protocol);
// TODO(shalev): Without a network_delegate this protocol handler will never
// handle file: requests, but as a side effect it makes
// job_factory::IsHandledProtocol return true, which prevents attempts to
// handle the protocol externally.
set_protocol = extensions_job_factory_->SetProtocolHandler(
chrome::kFileScheme, new net::FileProtocolHandler(NULL));
DCHECK(set_protocol);
set_protocol = main_job_factory_->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(),
network_delegate()));
DCHECK(set_protocol);
set_protocol = media_request_job_factory_->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(),
network_delegate()));
DCHECK(set_protocol);
set_protocol = extensions_job_factory_->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), NULL));
DCHECK(set_protocol);
net::URLRequestJobFactory* job_factories[3]; net::URLRequestJobFactory* job_factories[3];
job_factories[0] = main_job_factory_.get(); job_factories[0] = main_job_factory_.get();
job_factories[1] = media_request_job_factory_.get(); job_factories[1] = media_request_job_factory_.get();
......
...@@ -567,10 +567,6 @@ void ProfileIOData::SetUpJobFactoryDefaults( ...@@ -567,10 +567,6 @@ void ProfileIOData::SetUpJobFactoryDefaults(
ChromeURLDataManagerBackend::CreateProtocolHandler( ChromeURLDataManagerBackend::CreateProtocolHandler(
chrome_url_data_manager_backend_.get())); chrome_url_data_manager_backend_.get()));
DCHECK(set_protocol); DCHECK(set_protocol);
set_protocol = job_factory->SetProtocolHandler(
chrome::kChromeDevToolsScheme,
CreateDevToolsProtocolHandler(chrome_url_data_manager_backend_.get()));
DCHECK(set_protocol);
set_protocol = job_factory->SetProtocolHandler( set_protocol = job_factory->SetProtocolHandler(
chrome::kDataScheme, new net::DataProtocolHandler()); chrome::kDataScheme, new net::DataProtocolHandler());
DCHECK(set_protocol); DCHECK(set_protocol);
......
...@@ -568,21 +568,26 @@ bool IsSupportedURL(const GURL& url, FilePath* path) { ...@@ -568,21 +568,26 @@ bool IsSupportedURL(const GURL& url, FilePath* path) {
class DevToolsJobFactory class DevToolsJobFactory
: public net::URLRequestJobFactory::ProtocolHandler { : public net::URLRequestJobFactory::ProtocolHandler {
public: public:
explicit DevToolsJobFactory(ChromeURLDataManagerBackend* backend); DevToolsJobFactory(ChromeURLDataManagerBackend* backend,
net::NetworkDelegate* network_delegate);
virtual ~DevToolsJobFactory(); virtual ~DevToolsJobFactory();
virtual net::URLRequestJob* MaybeCreateJob( virtual net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request) const OVERRIDE; net::URLRequest* request) const OVERRIDE;
private: private:
// |backend_| is owned by ProfileIOData, which owns this ProtocolHandler. // |backend_| and |network_delegate_| are owned by ProfileIOData, which owns
// this ProtocolHandler.
ChromeURLDataManagerBackend* const backend_; ChromeURLDataManagerBackend* const backend_;
net::NetworkDelegate* network_delegate_;
DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory); DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory);
}; };
DevToolsJobFactory::DevToolsJobFactory(ChromeURLDataManagerBackend* backend) DevToolsJobFactory::DevToolsJobFactory(ChromeURLDataManagerBackend* backend,
: backend_(backend) { net::NetworkDelegate* network_delegate)
: backend_(backend),
network_delegate_(network_delegate) {
DCHECK(backend_); DCHECK(backend_);
} }
...@@ -593,7 +598,7 @@ DevToolsJobFactory::MaybeCreateJob(net::URLRequest* request) const { ...@@ -593,7 +598,7 @@ DevToolsJobFactory::MaybeCreateJob(net::URLRequest* request) const {
if (ShouldLoadFromDisk()) { if (ShouldLoadFromDisk()) {
FilePath path; FilePath path;
if (IsSupportedURL(request->url(), &path)) if (IsSupportedURL(request->url(), &path))
return new net::URLRequestFileJob(request, path); return new net::URLRequestFileJob(request, path, network_delegate_);
} }
return new URLRequestChromeJob(request, backend_); return new URLRequestChromeJob(request, backend_);
...@@ -602,6 +607,7 @@ DevToolsJobFactory::MaybeCreateJob(net::URLRequest* request) const { ...@@ -602,6 +607,7 @@ DevToolsJobFactory::MaybeCreateJob(net::URLRequest* request) const {
} // namespace } // namespace
net::URLRequestJobFactory::ProtocolHandler* net::URLRequestJobFactory::ProtocolHandler*
CreateDevToolsProtocolHandler(ChromeURLDataManagerBackend* backend) { CreateDevToolsProtocolHandler(ChromeURLDataManagerBackend* backend,
return new DevToolsJobFactory(backend); net::NetworkDelegate* network_delegate) {
return new DevToolsJobFactory(backend, network_delegate);
} }
...@@ -23,6 +23,7 @@ class RefCountedMemory; ...@@ -23,6 +23,7 @@ class RefCountedMemory;
} }
namespace net { namespace net {
class NetworkDelegate;
class URLRequest; class URLRequest;
class URLRequestJob; class URLRequestJob;
} }
...@@ -85,6 +86,7 @@ class ChromeURLDataManagerBackend { ...@@ -85,6 +86,7 @@ class ChromeURLDataManagerBackend {
}; };
net::URLRequestJobFactory::ProtocolHandler* net::URLRequestJobFactory::ProtocolHandler*
CreateDevToolsProtocolHandler(ChromeURLDataManagerBackend* backend); CreateDevToolsProtocolHandler(ChromeURLDataManagerBackend* backend,
net::NetworkDelegate* network_delegate);
#endif // CHROME_BROWSER_UI_WEBUI_CHROME_URL_DATA_MANAGER_BACKEND_H_ #endif // CHROME_BROWSER_UI_WEBUI_CHROME_URL_DATA_MANAGER_BACKEND_H_
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_filter.h"
const char kMockHostname[] = "mock.http"; const char kMockHostname[] = "mock.http";
...@@ -82,7 +83,9 @@ FilePath URLRequestMockHTTPJob::GetOnDiskPath(const FilePath& base_path, ...@@ -82,7 +83,9 @@ FilePath URLRequestMockHTTPJob::GetOnDiskPath(const FilePath& base_path,
URLRequestMockHTTPJob::URLRequestMockHTTPJob(net::URLRequest* request, URLRequestMockHTTPJob::URLRequestMockHTTPJob(net::URLRequest* request,
const FilePath& file_path) const FilePath& file_path)
: net::URLRequestFileJob(request, file_path) { } : net::URLRequestFileJob(request,
file_path,
request->context()->network_delegate()) { }
// Public virtual version. // Public virtual version.
void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) { void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) {
......
...@@ -730,6 +730,8 @@ ...@@ -730,6 +730,8 @@
'udp/udp_socket_win.h', 'udp/udp_socket_win.h',
'url_request/data_protocol_handler.cc', 'url_request/data_protocol_handler.cc',
'url_request/data_protocol_handler.h', 'url_request/data_protocol_handler.h',
'url_request/file_protocol_handler.cc',
'url_request/file_protocol_handler.h',
'url_request/fraudulent_certificate_reporter.h', 'url_request/fraudulent_certificate_reporter.h',
'url_request/ftp_protocol_handler.cc', 'url_request/ftp_protocol_handler.cc',
'url_request/ftp_protocol_handler.h', 'url_request/ftp_protocol_handler.h',
......
// Copyright (c) 2012 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.
#include "net/url_request/file_protocol_handler.h"
#include "base/logging.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_dir_job.h"
#include "net/url_request/url_request_file_job.h"
namespace net {
FileProtocolHandler::FileProtocolHandler(
NetworkDelegate* network_delegate)
: network_delegate_(network_delegate) {
}
URLRequestJob* FileProtocolHandler::MaybeCreateJob(URLRequest* request) const {
FilePath file_path;
const bool is_file = FileURLToFilePath(request->url(), &file_path);
// Check file access permissions.
if (!network_delegate_ ||
!network_delegate_->CanAccessFile(*request, file_path)) {
return new URLRequestErrorJob(request, ERR_ACCESS_DENIED);
}
// We need to decide whether to create URLRequestFileJob for file access or
// URLRequestFileDirJob for directory access. To avoid accessing the
// filesystem, we only look at the path string here.
// The code in the URLRequestFileJob::Start() method discovers that a path,
// which doesn't end with a slash, should really be treated as a directory,
// and it then redirects to the URLRequestFileDirJob.
if (is_file &&
file_util::EndsWithSeparator(file_path) &&
file_path.IsAbsolute()) {
return new URLRequestFileDirJob(request, file_path);
}
// Use a regular file request job for all non-directories (including invalid
// file names).
return new URLRequestFileJob(request, file_path, network_delegate_);
}
} // namespace net
// Copyright (c) 2012 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_URL_REQUEST_FILE_PROTOCOL_HANDLER_H_
#define NET_URL_REQUEST_FILE_PROTOCOL_HANDLER_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "net/url_request/url_request_job_factory.h"
namespace net {
class NetworkDelegate;
class URLRequestJob;
// Implements a ProtocolHandler for File jobs. If |network_delegate_| is NULL,
// then all file requests will fail with ERR_ACCESS_DENIED.
class NET_EXPORT FileProtocolHandler :
public URLRequestJobFactory::ProtocolHandler {
public:
explicit FileProtocolHandler(NetworkDelegate* network_delegate);
virtual URLRequestJob* MaybeCreateJob(URLRequest* request) const OVERRIDE;
private:
NetworkDelegate* network_delegate_;
DISALLOW_COPY_AND_ASSIGN(FileProtocolHandler);
};
} // namespace net
#endif // NET_URL_REQUEST_FILE_PROTOCOL_HANDLER_H_
...@@ -84,8 +84,9 @@ class URLRequestFileJob::AsyncResolver ...@@ -84,8 +84,9 @@ class URLRequestFileJob::AsyncResolver
}; };
URLRequestFileJob::URLRequestFileJob(URLRequest* request, URLRequestFileJob::URLRequestFileJob(URLRequest* request,
const FilePath& file_path) const FilePath& file_path,
: URLRequestJob(request, request->context()->network_delegate()), NetworkDelegate* network_delegate)
: URLRequestJob(request, network_delegate),
file_path_(file_path), file_path_(file_path),
stream_(NULL), stream_(NULL),
is_directory_(false), is_directory_(false),
...@@ -99,8 +100,11 @@ URLRequestJob* URLRequestFileJob::Factory(URLRequest* request, ...@@ -99,8 +100,11 @@ URLRequestJob* URLRequestFileJob::Factory(URLRequest* request,
const bool is_file = FileURLToFilePath(request->url(), &file_path); const bool is_file = FileURLToFilePath(request->url(), &file_path);
// Check file access permissions. // Check file access permissions.
if (!IsFileAccessAllowed(*request, file_path)) if (!request->context()->network_delegate() ||
!request->context()->network_delegate()->CanAccessFile(
*request, file_path)) {
return new URLRequestErrorJob(request, ERR_ACCESS_DENIED); return new URLRequestErrorJob(request, ERR_ACCESS_DENIED);
}
// We need to decide whether to create URLRequestFileJob for file access or // We need to decide whether to create URLRequestFileJob for file access or
// URLRequestFileDirJob for directory access. To avoid accessing the // URLRequestFileDirJob for directory access. To avoid accessing the
...@@ -115,7 +119,8 @@ URLRequestJob* URLRequestFileJob::Factory(URLRequest* request, ...@@ -115,7 +119,8 @@ URLRequestJob* URLRequestFileJob::Factory(URLRequest* request,
// Use a regular file request job for all non-directories (including invalid // Use a regular file request job for all non-directories (including invalid
// file names). // file names).
return new URLRequestFileJob(request, file_path); return new URLRequestFileJob(
request, file_path, request->context()->network_delegate());
} }
void URLRequestFileJob::Start() { void URLRequestFileJob::Start() {
...@@ -250,15 +255,6 @@ void URLRequestFileJob::SetExtraRequestHeaders( ...@@ -250,15 +255,6 @@ void URLRequestFileJob::SetExtraRequestHeaders(
} }
} }
// static
bool URLRequestFileJob::IsFileAccessAllowed(const URLRequest& request,
const FilePath& path) {
const NetworkDelegate* delegate = request.context()->network_delegate();
if (delegate)
return delegate->CanAccessFile(request, path);
return false;
}
URLRequestFileJob::~URLRequestFileJob() { URLRequestFileJob::~URLRequestFileJob() {
DCHECK(!async_resolver_); DCHECK(!async_resolver_);
} }
......
...@@ -24,7 +24,9 @@ namespace net { ...@@ -24,7 +24,9 @@ namespace net {
// A request job that handles reading file URLs // A request job that handles reading file URLs
class NET_EXPORT URLRequestFileJob : public URLRequestJob { class NET_EXPORT URLRequestFileJob : public URLRequestJob {
public: public:
URLRequestFileJob(URLRequest* request, const FilePath& file_path); URLRequestFileJob(URLRequest* request,
const FilePath& file_path,
NetworkDelegate* network_delegate);
static URLRequest::ProtocolFactory Factory; static URLRequest::ProtocolFactory Factory;
...@@ -52,12 +54,6 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob { ...@@ -52,12 +54,6 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob {
FilePath file_path_; FilePath file_path_;
private: private:
// Tests to see if access to |path| is allowed. If g_allow_file_access_ is
// true, then this will return true. If the NetworkDelegate associated with
// the |request| says it's OK, then this will also return true.
static bool IsFileAccessAllowed(const URLRequest& request,
const FilePath& path);
// Callback after fetching file info on a background thread. // Callback after fetching file info on a background thread.
void DidResolve(bool exists, const base::PlatformFileInfo& file_info); void DidResolve(bool exists, const base::PlatformFileInfo& file_info);
......
...@@ -94,7 +94,9 @@ class URLRequestTestShellFileJob : public net::URLRequestFileJob { ...@@ -94,7 +94,9 @@ class URLRequestTestShellFileJob : public net::URLRequestFileJob {
private: private:
URLRequestTestShellFileJob(net::URLRequest* request, const FilePath& path) URLRequestTestShellFileJob(net::URLRequest* request, const FilePath& path)
: net::URLRequestFileJob(request, path) { : net::URLRequestFileJob(request,
path,
request->context()->network_delegate()) {
} }
virtual ~URLRequestTestShellFileJob() { } virtual ~URLRequestTestShellFileJob() { }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment