1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/url_request/url_request_job_manager.h"
9 #include "base/memory/singleton.h"
10 #include "build/build_config.h"
11 #include "base/strings/string_util.h"
12 #include "net/base/load_flags.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/network_delegate.h"
15 #include "net/url_request/url_request_context.h"
16 #include "net/url_request/url_request_error_job.h"
17 #include "net/url_request/url_request_http_job.h"
18 #include "net/url_request/url_request_job_factory.h"
22 // The built-in set of protocol factories
25 struct SchemeToFactory
{
27 URLRequest::ProtocolFactory
* factory
;
32 static const SchemeToFactory kBuiltinFactories
[] = {
33 { "http", URLRequestHttpJob::Factory
},
34 { "https", URLRequestHttpJob::Factory
},
37 { "ws", URLRequestHttpJob::Factory
},
38 { "wss", URLRequestHttpJob::Factory
},
39 #endif // !defined(OS_IOS)
43 URLRequestJobManager
* URLRequestJobManager::GetInstance() {
44 return Singleton
<URLRequestJobManager
>::get();
47 URLRequestJob
* URLRequestJobManager::CreateJob(
48 URLRequest
* request
, NetworkDelegate
* network_delegate
) const {
49 DCHECK(IsAllowedThread());
51 // If we are given an invalid URL, then don't even try to inspect the scheme.
52 if (!request
->url().is_valid())
53 return new URLRequestErrorJob(request
, network_delegate
, ERR_INVALID_URL
);
55 // We do this here to avoid asking interceptors about unsupported schemes.
56 const URLRequestJobFactory
* job_factory
=
57 request
->context()->job_factory();
59 const std::string
& scheme
= request
->url().scheme(); // already lowercase
60 if (!job_factory
->IsHandledProtocol(scheme
)) {
61 return new URLRequestErrorJob(
62 request
, network_delegate
, ERR_UNKNOWN_URL_SCHEME
);
65 // THREAD-SAFETY NOTICE:
66 // We do not need to acquire the lock here since we are only reading our
67 // data structures. They should only be modified on the current thread.
69 // See if the request should be intercepted.
71 URLRequestJob
* job
= job_factory
->MaybeCreateJobWithProtocolHandler(
72 scheme
, request
, network_delegate
);
76 // See if the request should be handled by a built-in protocol factory.
77 for (size_t i
= 0; i
< arraysize(kBuiltinFactories
); ++i
) {
78 if (scheme
== kBuiltinFactories
[i
].scheme
) {
79 URLRequestJob
* new_job
=
80 (kBuiltinFactories
[i
].factory
)(request
, network_delegate
, scheme
);
81 DCHECK(new_job
); // The built-in factories are not expected to fail!
86 // If we reached here, then it means that a registered protocol factory
87 // wasn't interested in handling the URL. That is fairly unexpected, and we
88 // don't have a specific error to report here :-(
89 LOG(WARNING
) << "Failed to map: " << request
->url().spec();
90 return new URLRequestErrorJob(request
, network_delegate
, ERR_FAILED
);
93 URLRequestJob
* URLRequestJobManager::MaybeInterceptRedirect(
95 NetworkDelegate
* network_delegate
,
96 const GURL
& location
) const {
97 DCHECK(IsAllowedThread());
98 if (!request
->url().is_valid() ||
99 request
->status().status() == URLRequestStatus::CANCELED
) {
103 const URLRequestJobFactory
* job_factory
= NULL
;
104 job_factory
= request
->context()->job_factory();
106 const std::string
& scheme
= request
->url().scheme(); // already lowercase
107 if (!job_factory
->IsHandledProtocol(scheme
))
111 request
->context()->job_factory()->MaybeInterceptRedirect(
112 request
, network_delegate
, location
);
119 URLRequestJob
* URLRequestJobManager::MaybeInterceptResponse(
120 URLRequest
* request
, NetworkDelegate
* network_delegate
) const {
121 DCHECK(IsAllowedThread());
122 if (!request
->url().is_valid() ||
123 request
->status().status() == URLRequestStatus::CANCELED
) {
127 const URLRequestJobFactory
* job_factory
= NULL
;
128 job_factory
= request
->context()->job_factory();
130 const std::string
& scheme
= request
->url().scheme(); // already lowercase
131 if (!job_factory
->IsHandledProtocol(scheme
))
135 request
->context()->job_factory()->MaybeInterceptResponse(
136 request
, network_delegate
);
144 bool URLRequestJobManager::SupportsScheme(const std::string
& scheme
) {
145 for (size_t i
= 0; i
< arraysize(kBuiltinFactories
); ++i
) {
146 if (base::LowerCaseEqualsASCII(scheme
, kBuiltinFactories
[i
].scheme
))
153 URLRequestJobManager::URLRequestJobManager() {
156 URLRequestJobManager::~URLRequestJobManager() {}