OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/url_request/url_request_job_manager.h" | |
6 | |
7 #include <algorithm> | |
8 | |
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" | |
19 | |
20 namespace net { | |
21 | |
22 // The built-in set of protocol factories | |
23 namespace { | |
24 | |
25 struct SchemeToFactory { | |
26 const char* scheme; | |
27 URLRequest::ProtocolFactory* factory; | |
28 }; | |
29 | |
30 } // namespace | |
31 | |
32 static const SchemeToFactory kBuiltinFactories[] = { | |
33 { "http", URLRequestHttpJob::Factory }, | |
34 { "https", URLRequestHttpJob::Factory }, | |
35 | |
36 #if !defined(OS_IOS) | |
37 { "ws", URLRequestHttpJob::Factory }, | |
38 { "wss", URLRequestHttpJob::Factory }, | |
39 #endif // !defined(OS_IOS) | |
40 }; | |
41 | |
42 // static | |
43 URLRequestJobManager* URLRequestJobManager::GetInstance() { | |
44 return Singleton<URLRequestJobManager>::get(); | |
45 } | |
46 | |
47 URLRequestJob* URLRequestJobManager::CreateJob( | |
48 URLRequest* request, NetworkDelegate* network_delegate) const { | |
49 DCHECK(IsAllowedThread()); | |
50 | |
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); | |
54 | |
55 // We do this here to avoid asking interceptors about unsupported schemes. | |
56 const URLRequestJobFactory* job_factory = NULL; | |
57 job_factory = request->context()->job_factory(); | |
58 | |
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); | |
63 } | |
64 | |
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. | |
68 | |
69 // See if the request should be intercepted. | |
70 // | |
71 URLRequestJob* job = job_factory->MaybeCreateJobWithProtocolHandler( | |
72 scheme, request, network_delegate); | |
73 if (job) | |
74 return job; | |
75 | |
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* job = (kBuiltinFactories[i].factory)( | |
80 request, network_delegate, scheme); | |
81 DCHECK(job); // The built-in factories are not expected to fail! | |
82 return job; | |
83 } | |
84 } | |
85 | |
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); | |
91 } | |
92 | |
93 URLRequestJob* URLRequestJobManager::MaybeInterceptRedirect( | |
94 URLRequest* request, | |
95 NetworkDelegate* network_delegate, | |
96 const GURL& location) const { | |
97 DCHECK(IsAllowedThread()); | |
98 if (!request->url().is_valid() || | |
99 request->status().status() == URLRequestStatus::CANCELED) { | |
100 return NULL; | |
101 } | |
102 | |
103 const URLRequestJobFactory* job_factory = NULL; | |
104 job_factory = request->context()->job_factory(); | |
105 | |
106 const std::string& scheme = request->url().scheme(); // already lowercase | |
107 if (!job_factory->IsHandledProtocol(scheme)) | |
108 return NULL; | |
109 | |
110 URLRequestJob* job = | |
111 request->context()->job_factory()->MaybeInterceptRedirect( | |
112 request, network_delegate, location); | |
113 if (job) | |
114 return job; | |
115 | |
116 return NULL; | |
117 } | |
118 | |
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) { | |
124 return NULL; | |
125 } | |
126 | |
127 const URLRequestJobFactory* job_factory = NULL; | |
128 job_factory = request->context()->job_factory(); | |
129 | |
130 const std::string& scheme = request->url().scheme(); // already lowercase | |
131 if (!job_factory->IsHandledProtocol(scheme)) | |
132 return NULL; | |
133 | |
134 URLRequestJob* job = | |
135 request->context()->job_factory()->MaybeInterceptResponse( | |
136 request, network_delegate); | |
137 if (job) | |
138 return job; | |
139 | |
140 return NULL; | |
141 } | |
142 | |
143 // static | |
144 bool URLRequestJobManager::SupportsScheme(const std::string& scheme) { | |
145 for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i) { | |
146 if (LowerCaseEqualsASCII(scheme, kBuiltinFactories[i].scheme)) | |
147 return true; | |
148 } | |
149 | |
150 return false; | |
151 } | |
152 | |
153 URLRequestJobManager::URLRequestJobManager() { | |
154 } | |
155 | |
156 URLRequestJobManager::~URLRequestJobManager() {} | |
157 | |
158 } // namespace net | |
OLD | NEW |