OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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 "chrome/browser/policy/device_management_service.h" | |
6 | |
7 #include "chrome/browser/browser_thread.h" | |
8 #include "net/base/cookie_monster.h" | |
9 #include "net/base/host_resolver.h" | |
10 #include "net/base/load_flags.h" | |
11 #include "net/base/ssl_config_service_defaults.h" | |
12 #include "net/http/http_auth_handler_factory.h" | |
13 #include "net/http/http_network_layer.h" | |
14 #include "net/proxy/proxy_service.h" | |
15 #include "net/url_request/url_request_context.h" | |
16 #include "net/url_request/url_request_status.h" | |
17 #include "chrome/browser/browser_process.h" | |
18 #include "chrome/browser/io_thread.h" | |
19 #include "chrome/browser/net/chrome_net_log.h" | |
20 #include "chrome/browser/policy/device_management_backend_impl.h" | |
21 #include "chrome/common/net/url_request_context_getter.h" | |
22 | |
23 namespace policy { | |
24 | |
25 namespace { | |
26 | |
27 // Custom request context implementation that allows to override the user agent, | |
28 // amongst others. Wraps a baseline request context from which we reuse the | |
29 // networking components. | |
30 class DeviceManagementBackendRequestContext : public URLRequestContext { | |
31 public: | |
32 explicit DeviceManagementBackendRequestContext( | |
33 URLRequestContext* base_context); | |
34 virtual ~DeviceManagementBackendRequestContext(); | |
35 }; | |
36 | |
37 DeviceManagementBackendRequestContext::DeviceManagementBackendRequestContext( | |
38 URLRequestContext* base_context) { | |
39 // Share resolver, proxy service and ssl bits with the baseline context. This | |
40 // is important so we don't make redundant requests (e.g. when resolving proxy | |
41 // auto configuration). | |
42 net_log_ = base_context->net_log(); | |
43 host_resolver_ = base_context->host_resolver(); | |
44 proxy_service_ = base_context->proxy_service(); | |
45 ssl_config_service_ = base_context->ssl_config_service(); | |
46 | |
47 // Share the http session. | |
48 http_transaction_factory_ = net::HttpNetworkLayer::CreateFactory( | |
49 base_context->http_transaction_factory()->GetSession()); | |
50 | |
51 // No cookies, please. | |
52 cookie_store_ = new net::CookieMonster(NULL, NULL); | |
53 | |
54 // Initialize these to sane values for our purposes. | |
55 accept_language_ = "*"; | |
56 accept_charset_ = "*"; | |
57 } | |
58 | |
59 DeviceManagementBackendRequestContext | |
60 ::~DeviceManagementBackendRequestContext() { | |
61 delete http_transaction_factory_; | |
62 delete http_auth_handler_factory_; | |
63 } | |
64 | |
65 // Request context holder. | |
66 class DeviceManagementBackendRequestContextGetter | |
67 : public URLRequestContextGetter { | |
68 public: | |
69 DeviceManagementBackendRequestContextGetter( | |
70 URLRequestContextGetter* base_context_getter) | |
71 : base_context_getter_(base_context_getter) {} | |
72 | |
73 // URLRequestContextGetter overrides. | |
74 virtual URLRequestContext* GetURLRequestContext(); | |
75 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const; | |
76 | |
77 private: | |
78 scoped_refptr<URLRequestContext> context_; | |
79 scoped_refptr<URLRequestContextGetter> base_context_getter_; | |
80 }; | |
81 | |
82 | |
83 URLRequestContext* | |
84 DeviceManagementBackendRequestContextGetter::GetURLRequestContext() { | |
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
86 if (!context_) { | |
87 context_ = new DeviceManagementBackendRequestContext( | |
88 base_context_getter_->GetURLRequestContext()); | |
89 } | |
90 | |
91 return context_.get(); | |
92 } | |
93 | |
94 scoped_refptr<base::MessageLoopProxy> | |
95 DeviceManagementBackendRequestContextGetter::GetIOMessageLoopProxy() const { | |
96 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | |
97 } | |
98 | |
99 } // namespace | |
100 | |
101 DeviceManagementService::~DeviceManagementService() { | |
102 // All running jobs should have been canceled by now. If not, there are | |
103 // backend objects still around, which is an error. | |
104 DCHECK(pending_jobs_.empty()); | |
105 DCHECK(queued_jobs_.empty()); | |
106 } | |
107 | |
108 DeviceManagementBackend* DeviceManagementService::CreateBackend() { | |
109 return new DeviceManagementBackendImpl(this); | |
110 } | |
111 | |
112 void DeviceManagementService::Initialize( | |
113 URLRequestContextGetter* request_context_getter) { | |
114 DCHECK(!request_context_getter_); | |
115 request_context_getter_ = request_context_getter; | |
116 while (!queued_jobs_.empty()) { | |
117 StartJob(queued_jobs_.front()); | |
118 queued_jobs_.pop_front(); | |
119 } | |
120 } | |
121 | |
122 void DeviceManagementService::Shutdown() { | |
Nico
2010/11/22 11:06:06
This moves all in-flight jobs back to the "queued"
Mattias Nissler (ping if slow)
2010/11/22 12:35:39
The backends should call RemoveJob() when they get
| |
123 for (JobFetcherMap::iterator job(pending_jobs_.begin()); | |
124 job != pending_jobs_.end(); | |
125 ++job) { | |
126 delete job->first; | |
127 queued_jobs_.push_back(job->second); | |
128 } | |
129 } | |
130 | |
131 DeviceManagementService::DeviceManagementService( | |
132 const std::string& server_url) | |
133 : server_url_(server_url) { | |
134 } | |
135 | |
136 void DeviceManagementService::AddJob(DeviceManagementJob* job) { | |
137 if (request_context_getter_.get()) | |
138 StartJob(job); | |
139 else | |
140 queued_jobs_.push_back(job); | |
141 } | |
142 | |
143 void DeviceManagementService::RemoveJob(DeviceManagementJob* job) { | |
144 for (JobFetcherMap::iterator entry(pending_jobs_.begin()); | |
145 entry != pending_jobs_.end(); | |
146 ++entry) { | |
147 if (entry->second == job) { | |
148 delete entry->first; | |
149 pending_jobs_.erase(entry); | |
150 break; | |
151 } | |
152 } | |
153 } | |
154 | |
155 void DeviceManagementService::StartJob(DeviceManagementJob* job) { | |
156 URLFetcher* fetcher = URLFetcher::Create(0, job->GetURL(server_url_), | |
157 URLFetcher::POST, this); | |
158 fetcher->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES | | |
159 net::LOAD_DO_NOT_SAVE_COOKIES | | |
160 net::LOAD_DISABLE_CACHE); | |
161 fetcher->set_request_context(request_context_getter_.get()); | |
162 job->ConfigureRequest(fetcher); | |
163 pending_jobs_[fetcher] = job; | |
164 fetcher->Start(); | |
165 } | |
166 | |
167 void DeviceManagementService::OnURLFetchComplete( | |
168 const URLFetcher* source, | |
169 const GURL& url, | |
170 const URLRequestStatus& status, | |
171 int response_code, | |
172 const ResponseCookies& cookies, | |
173 const std::string& data) { | |
174 JobFetcherMap::iterator entry(pending_jobs_.find(source)); | |
175 if (entry != pending_jobs_.end()) { | |
176 DeviceManagementJob* job = entry->second; | |
177 job->HandleResponse(status, response_code, cookies, data); | |
178 pending_jobs_.erase(entry); | |
179 } else { | |
180 NOTREACHED() << "Callback from foreign URL fetcher"; | |
Nico
2010/11/22 11:06:06
Doesn't this happen in normal usage if a few reque
Mattias Nissler (ping if slow)
2010/11/22 12:35:39
No, shutdown deletes the fetcher, thus cancelling
| |
181 } | |
182 delete source; | |
183 } | |
184 | |
185 } // namespace policy | |
OLD | NEW |