Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: chrome/browser/policy/device_management_service.cc

Issue 8952027: base::Callback-ify policy::DeviceManagementService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/device_management_service.h" 5 #include "chrome/browser/policy/device_management_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
8 #include "base/message_loop.h" 9 #include "base/message_loop.h"
9 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
11 #include "base/stringprintf.h"
12 #include "base/sys_info.h"
10 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/net/chrome_net_log.h" 14 #include "chrome/browser/net/chrome_net_log.h"
12 #include "chrome/browser/policy/device_management_backend.h" 15 #include "chrome/browser/policy/device_management_backend.h"
13 #include "chrome/browser/policy/device_management_backend_impl.h" 16 #include "chrome/browser/policy/device_management_backend_impl.h"
17 #include "chrome/common/chrome_version_info.h"
14 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
15 #include "content/public/common/content_client.h" 19 #include "content/public/common/content_client.h"
16 #include "content/public/common/url_fetcher.h" 20 #include "content/public/common/url_fetcher.h"
21 #include "content/public/common/url_fetcher.h"
Joao da Silva 2012/01/02 16:14:43 Nit: don't include twice
Mattias Nissler (ping if slow) 2012/01/02 17:53:23 Done.
17 #include "net/base/cookie_monster.h" 22 #include "net/base/cookie_monster.h"
23 #include "net/base/escape.h"
18 #include "net/base/host_resolver.h" 24 #include "net/base/host_resolver.h"
19 #include "net/base/load_flags.h" 25 #include "net/base/load_flags.h"
20 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
21 #include "net/base/ssl_config_service_defaults.h" 27 #include "net/base/ssl_config_service_defaults.h"
22 #include "net/http/http_network_layer.h" 28 #include "net/http/http_network_layer.h"
23 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
24 #include "net/proxy/proxy_service.h" 30 #include "net/proxy/proxy_service.h"
25 #include "net/url_request/url_request_context.h" 31 #include "net/url_request/url_request_context.h"
26 #include "net/url_request/url_request_context_getter.h" 32 #include "net/url_request/url_request_context_getter.h"
27 #include "net/url_request/url_request_status.h" 33 #include "net/url_request/url_request_status.h"
34 #include "net/url_request/url_request_status.h"
Joao da Silva 2012/01/02 16:14:43 Nit: don't include twice
Mattias Nissler (ping if slow) 2012/01/02 17:53:23 Done.
35
36 #if defined(OS_CHROMEOS)
37 #include "chrome/browser/chromeos/system/statistics_provider.h"
38 #endif
28 39
29 using content::BrowserThread; 40 using content::BrowserThread;
30 41
31 namespace em = enterprise_management; 42 namespace em = enterprise_management;
32 43
33 namespace policy { 44 namespace policy {
34 45
35 namespace { 46 namespace {
36 47
48 const char kValueAgent[] = "%s %s(%s)";
49 const char kValuePlatform[] = "%s|%s|%s";
50
51 const char kPostContentType[] = "application/protobuf";
52
53 const char kServiceTokenAuthHeader[] = "Authorization: GoogleLogin auth=";
54 const char kDMTokenAuthHeader[] = "Authorization: GoogleDMToken token=";
55
56 // HTTP Error Codes of the DM Server with their concrete meanings in the context
57 // of the DM Server communication.
58 const int kSuccess = 200;
59 const int kInvalidArgument = 400;
60 const int kInvalidAuthCookieOrDMToken = 401;
61 const int kDeviceManagementNotAllowed = 403;
62 const int kInvalidURL = 404; // This error is not coming from the GFE.
63 const int kInvalidSerialNumber = 405;
64 const int kDeviceIdConflict = 409;
65 const int kDeviceNotFound = 410;
66 const int kPendingApproval = 412;
67 const int kInternalServerError = 500;
68 const int kServiceUnavailable = 503;
69 const int kPolicyNotFound = 902; // This error is not sent as HTTP status code.
70
71 // TODO(pastarmovj): Legacy error codes are here for compatibility only. They
72 // should be removed once the DM Server has been updated.
73 const int kPendingApprovalLegacy = 491;
74 const int kDeviceNotFoundLegacy = 901;
75
76 #if defined(OS_CHROMEOS)
77 // Machine info keys.
78 const char kMachineInfoHWClass[] = "hardware_class";
79 const char kMachineInfoBoard[] = "CHROMEOS_RELEASE_BOARD";
80 #endif
81
37 bool IsProxyError(const net::URLRequestStatus status) { 82 bool IsProxyError(const net::URLRequestStatus status) {
38 switch (status.error()) { 83 switch (status.error()) {
39 case net::ERR_PROXY_CONNECTION_FAILED: 84 case net::ERR_PROXY_CONNECTION_FAILED:
40 case net::ERR_TUNNEL_CONNECTION_FAILED: 85 case net::ERR_TUNNEL_CONNECTION_FAILED:
41 case net::ERR_PROXY_AUTH_UNSUPPORTED: 86 case net::ERR_PROXY_AUTH_UNSUPPORTED:
42 case net::ERR_HTTPS_PROXY_TUNNEL_RESPONSE: 87 case net::ERR_HTTPS_PROXY_TUNNEL_RESPONSE:
43 case net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED: 88 case net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED:
44 case net::ERR_PROXY_CERTIFICATE_INVALID: 89 case net::ERR_PROXY_CERTIFICATE_INVALID:
45 case net::ERR_SOCKS_CONNECTION_FAILED: 90 case net::ERR_SOCKS_CONNECTION_FAILED:
46 case net::ERR_SOCKS_CONNECTION_HOST_UNREACHABLE: 91 case net::ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
47 return true; 92 return true;
48 } 93 }
49 return false; 94 return false;
50 } 95 }
51 96
52 bool IsProtobufMimeType(const content::URLFetcher* source) { 97 bool IsProtobufMimeType(const content::URLFetcher* source) {
53 return source->GetResponseHeaders()->HasHeaderValue( 98 return source->GetResponseHeaders()->HasHeaderValue(
54 "content-type", "application/x-protobuffer"); 99 "content-type", "application/x-protobuffer");
55 } 100 }
56 101
102 const char* UserAffiliationToString(UserAffiliation affiliation) {
103 switch (affiliation) {
104 case USER_AFFILIATION_MANAGED:
105 return dm_protocol::kValueUserAffiliationManaged;
106 case USER_AFFILIATION_NONE:
107 return dm_protocol::kValueUserAffiliationNone;
108 }
109 NOTREACHED() << "Invalid user affiliation " << affiliation;
110 return dm_protocol::kValueUserAffiliationNone;
111 }
112
113 const char* JobTypeToRequestType(DeviceManagementRequestJob::JobType type) {
114 switch (type) {
115 case DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT:
116 return dm_protocol::kValueRequestAutoEnrollment;
117 case DeviceManagementRequestJob::TYPE_REGISTRATION:
118 return dm_protocol::kValueRequestRegister;
119 case DeviceManagementRequestJob::TYPE_POLICY_FETCH:
120 return dm_protocol::kValueRequestPolicy;
121 case DeviceManagementRequestJob::TYPE_UNREGISTRATION:
122 return dm_protocol::kValueRequestUnregister;
123 }
124 NOTREACHED() << "Invalid job type " << type;
125 return "";
126 }
127
128 const std::string& GetAgentString() {
129 CR_DEFINE_STATIC_LOCAL(std::string, agent, ());
130 if (!agent.empty())
131 return agent;
132
133 chrome::VersionInfo version_info;
134 agent = base::StringPrintf(kValueAgent,
135 version_info.Name().c_str(),
136 version_info.Version().c_str(),
137 version_info.LastChange().c_str());
138 return agent;
139 }
140
141 const std::string& GetPlatformString() {
142 CR_DEFINE_STATIC_LOCAL(std::string, platform, ());
143 if (!platform.empty())
144 return platform;
145
146 std::string os_name(base::SysInfo::OperatingSystemName());
147 std::string os_hardware(base::SysInfo::CPUArchitecture());
148
149 #if defined(OS_CHROMEOS)
150 chromeos::system::StatisticsProvider* provider =
151 chromeos::system::StatisticsProvider::GetInstance();
152
153 std::string hwclass;
154 std::string board;
155 if (!provider->GetMachineStatistic(kMachineInfoHWClass, &hwclass) ||
156 !provider->GetMachineStatistic(kMachineInfoBoard, &board)) {
157 LOG(ERROR) << "Failed to get machine information";
158 }
159 os_name += ",CrOS," + board;
160 os_hardware += "," + hwclass;
161 #endif
162
163 std::string os_version("-");
164 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
165 int32 os_major_version = 0;
166 int32 os_minor_version = 0;
167 int32 os_bugfix_version = 0;
168 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version,
169 &os_minor_version,
170 &os_bugfix_version);
171 os_version = base::StringPrintf("%d.%d.%d",
172 os_major_version,
173 os_minor_version,
174 os_bugfix_version);
175 #endif
176
177 platform = base::StringPrintf(kValuePlatform,
178 os_name.c_str(),
179 os_hardware.c_str(),
180 os_version.c_str());
181 return platform;
182 }
183
57 // Custom request context implementation that allows to override the user agent, 184 // Custom request context implementation that allows to override the user agent,
58 // amongst others. Wraps a baseline request context from which we reuse the 185 // amongst others. Wraps a baseline request context from which we reuse the
59 // networking components. 186 // networking components.
60 class DeviceManagementRequestContext : public net::URLRequestContext { 187 class DeviceManagementRequestContext : public net::URLRequestContext {
61 public: 188 public:
62 explicit DeviceManagementRequestContext(net::URLRequestContext* base_context); 189 explicit DeviceManagementRequestContext(net::URLRequestContext* base_context);
63 virtual ~DeviceManagementRequestContext(); 190 virtual ~DeviceManagementRequestContext();
64 191
65 private: 192 private:
66 // Overridden from net::URLRequestContext: 193 // Overridden from net::URLRequestContext:
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 return context_.get(); 256 return context_.get();
130 } 257 }
131 258
132 scoped_refptr<base::MessageLoopProxy> 259 scoped_refptr<base::MessageLoopProxy>
133 DeviceManagementRequestContextGetter::GetIOMessageLoopProxy() const { 260 DeviceManagementRequestContextGetter::GetIOMessageLoopProxy() const {
134 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 261 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
135 } 262 }
136 263
137 } // namespace 264 } // namespace
138 265
266 // Request job implementation used with DeviceManagementService.
267 class DeviceManagementRequestJobImpl : public DeviceManagementRequestJob {
268 public:
269 DeviceManagementRequestJobImpl(JobType type,
270 DeviceManagementService* service);
271 virtual ~DeviceManagementRequestJobImpl();
272
273 // Handles the URL request response.
274 void HandleResponse(const net::URLRequestStatus& status,
275 int response_code,
276 const net::ResponseCookies& cookies,
277 const std::string& data);
278
279 // Gets the URL to contact.
280 GURL GetURL(const std::string& server_url);
281
282 // Configures the fetcher, setting up payload and headers.
283 void ConfigureRequest(content::URLFetcher* fetcher);
284
285 protected:
286 // DeviceManagementRequestJob:
287 virtual void Run() OVERRIDE;
288
289 private:
290 // Invokes the callback with the given error code.
291 void ReportError(DeviceManagementStatus code);
292
293 // Pointer to the service this job is associated with.
294 DeviceManagementService* service_;
295
296 DISALLOW_COPY_AND_ASSIGN(DeviceManagementRequestJobImpl);
297 };
298
299 DeviceManagementRequestJobImpl::DeviceManagementRequestJobImpl(
300 JobType type,
301 DeviceManagementService* service)
302 : DeviceManagementRequestJob(type),
303 service_(service) {}
304
305 DeviceManagementRequestJobImpl::~DeviceManagementRequestJobImpl() {
306 service_->RemoveJob(this);
307 }
308
309 void DeviceManagementRequestJobImpl::Run() {
310 service_->AddJob(this);
311 }
312
313 void DeviceManagementRequestJobImpl::HandleResponse(
314 const net::URLRequestStatus& status,
315 int response_code,
316 const net::ResponseCookies& cookies,
317 const std::string& data) {
318 if (status.status() != net::URLRequestStatus::SUCCESS) {
319 ReportError(DM_STATUS_REQUEST_FAILED);
320 return;
321 }
322
323 switch (response_code) {
324 case kSuccess: {
325 em::DeviceManagementResponse response;
326 if (!response.ParseFromString(data)) {
327 ReportError(DM_STATUS_RESPONSE_DECODING_ERROR);
328 return;
329 }
330 callback_.Run(DM_STATUS_SUCCESS, response);
331 return;
332 }
333 case kInvalidArgument: {
334 ReportError(DM_STATUS_REQUEST_INVALID);
335 return;
336 }
337 case kInvalidAuthCookieOrDMToken: {
338 ReportError(DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID);
339 return;
340 }
341 case kDeviceManagementNotAllowed: {
342 ReportError(DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED);
343 return;
344 }
345 case kPendingApprovalLegacy:
346 case kPendingApproval: {
347 ReportError(DM_STATUS_SERVICE_ACTIVATION_PENDING);
348 return;
349 }
350 case kInvalidURL:
351 case kInternalServerError:
352 case kServiceUnavailable: {
353 ReportError(DM_STATUS_TEMPORARY_UNAVAILABLE);
354 return;
355 }
356 case kDeviceNotFoundLegacy:
357 case kDeviceNotFound: {
358 ReportError(DM_STATUS_SERVICE_DEVICE_NOT_FOUND);
359 return;
360 }
361 case kPolicyNotFound: {
362 ReportError(DM_STATUS_SERVICE_POLICY_NOT_FOUND);
363 break;
Joao da Silva 2012/01/02 16:14:43 Some cases return and some break; please use the s
Mattias Nissler (ping if slow) 2012/01/02 17:53:23 Switched break to return. I don't mind either way
364 }
365 case kInvalidSerialNumber: {
366 ReportError(DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER);
367 break;
368 }
369 case kDeviceIdConflict: {
370 ReportError(DM_STATUS_SERVICE_DEVICE_ID_CONFLICT);
371 break;
372 }
373 default: {
374 VLOG(1) << "Unexpected HTTP status in response from DMServer : "
375 << response_code << ".";
376 // Handle all unknown 5xx HTTP error codes as temporary and any other
377 // unknown error as one that needs more time to recover.
378 if (response_code >= 500 && response_code <= 599)
379 ReportError(DM_STATUS_TEMPORARY_UNAVAILABLE);
380 else
381 ReportError(DM_STATUS_HTTP_STATUS_ERROR);
382 return;
383 }
384 }
385 }
386
387 GURL DeviceManagementRequestJobImpl::GetURL(
388 const std::string& server_url) {
389 std::string result(server_url);
390 result += '?';
391 for (ParameterMap::const_iterator entry(query_params_.begin());
392 entry != query_params_.end();
393 ++entry) {
394 if (entry != query_params_.begin())
395 result += '&';
396 result += net::EscapeQueryParamValue(entry->first, true);
397 result += '=';
398 result += net::EscapeQueryParamValue(entry->second, true);
399 }
400 return GURL(result);
401 }
402
403 void DeviceManagementRequestJobImpl::ConfigureRequest(
404 content::URLFetcher* fetcher) {
405 std::string payload;
406 CHECK(request_.SerializeToString(&payload));
407 fetcher->SetUploadData(kPostContentType, payload);
408 std::string extra_headers;
409 if (!gaia_token_.empty())
410 extra_headers += kServiceTokenAuthHeader + gaia_token_ + "\n";
411 if (!dm_token_.empty())
412 extra_headers += kDMTokenAuthHeader + dm_token_ + "\n";
413 fetcher->SetExtraRequestHeaders(extra_headers);
414 }
415
416 void DeviceManagementRequestJobImpl::ReportError(DeviceManagementStatus code) {
417 em::DeviceManagementResponse dummy_response;
418 callback_.Run(code, dummy_response);
419 }
420
421 DeviceManagementRequestJob::~DeviceManagementRequestJob() {}
422
423 void DeviceManagementRequestJob::SetGaiaToken(const std::string& gaia_token) {
424 gaia_token_ = gaia_token;
425 }
426
427 void DeviceManagementRequestJob::SetOAuthToken(const std::string& oauth_token) {
428 query_params_[dm_protocol::kParamOAuthToken] = oauth_token;
429 }
430
431 void DeviceManagementRequestJob::SetUserAffiliation(
432 UserAffiliation user_affiliation) {
433 query_params_[dm_protocol::kParamUserAffiliation] =
434 UserAffiliationToString(user_affiliation);
435 }
436
437 void DeviceManagementRequestJob::SetDMToken(const std::string& dm_token) {
438 dm_token_ = dm_token;
439 }
440
441 void DeviceManagementRequestJob::SetClientID(const std::string& client_id) {
442 query_params_[dm_protocol::kParamDeviceID] = client_id;
443 }
444
445 em::DeviceManagementRequest* DeviceManagementRequestJob::GetRequest() {
446 return &request_;
447 }
448
449 DeviceManagementRequestJob::DeviceManagementRequestJob(JobType type) {
450 query_params_[dm_protocol::kParamRequest] = JobTypeToRequestType(type);
451 query_params_[dm_protocol::kParamDeviceType] = dm_protocol::kValueDeviceType;
452 query_params_[dm_protocol::kParamAppType] = dm_protocol::kValueAppType;
453 query_params_[dm_protocol::kParamAgent] = GetAgentString();
454 query_params_[dm_protocol::kParamPlatform] = GetPlatformString();
455 }
456
457 void DeviceManagementRequestJob::Start(const Callback& callback) {
458 callback_ = callback;
459 Run();
460 }
461
139 DeviceManagementService::~DeviceManagementService() { 462 DeviceManagementService::~DeviceManagementService() {
140 // All running jobs should have been cancelled by now. If not, there are 463 // All running jobs should have been cancelled by now.
141 // backend objects still around, which is an error.
142 DCHECK(pending_jobs_.empty()); 464 DCHECK(pending_jobs_.empty());
143 DCHECK(queued_jobs_.empty()); 465 DCHECK(queued_jobs_.empty());
144 } 466 }
145 467
146 DeviceManagementBackend* DeviceManagementService::CreateBackend() { 468 DeviceManagementBackend* DeviceManagementService::CreateBackend() {
147 return new DeviceManagementBackendImpl(this); 469 return new DeviceManagementBackendImpl(this);
148 } 470 }
149 471
472 DeviceManagementRequestJob* DeviceManagementService::CreateJob(
473 DeviceManagementRequestJob::JobType type) {
474 return new DeviceManagementRequestJobImpl(type, this);
475 }
476
150 void DeviceManagementService::ScheduleInitialization(int64 delay_milliseconds) { 477 void DeviceManagementService::ScheduleInitialization(int64 delay_milliseconds) {
151 if (initialized_) 478 if (initialized_)
152 return; 479 return;
153 MessageLoop::current()->PostDelayedTask( 480 MessageLoop::current()->PostDelayedTask(
154 FROM_HERE, 481 FROM_HERE,
155 base::Bind(&DeviceManagementService::Initialize, 482 base::Bind(&DeviceManagementService::Initialize,
156 weak_ptr_factory_.GetWeakPtr()), 483 weak_ptr_factory_.GetWeakPtr()),
157 delay_milliseconds); 484 delay_milliseconds);
158 } 485 }
159 486
160 void DeviceManagementService::Initialize() { 487 void DeviceManagementService::Initialize() {
161 if (initialized_) 488 if (initialized_)
162 return; 489 return;
163 DCHECK(!request_context_getter_); 490 DCHECK(!request_context_getter_);
164 request_context_getter_ = new DeviceManagementRequestContextGetter( 491 request_context_getter_ = new DeviceManagementRequestContextGetter(
165 g_browser_process->system_request_context()); 492 g_browser_process->system_request_context());
166 initialized_ = true; 493 initialized_ = true;
167 494
168 while (!queued_jobs_.empty()) { 495 while (!queued_jobs_.empty()) {
169 StartJob(queued_jobs_.front(), false); 496 StartJob(queued_jobs_.front(), false);
170 queued_jobs_.pop_front(); 497 queued_jobs_.pop_front();
171 } 498 }
172 } 499 }
173 500
174 void DeviceManagementService::Shutdown() { 501 void DeviceManagementService::Shutdown() {
175 for (JobFetcherMap::iterator job(pending_jobs_.begin()); 502 for (JobFetcherMap::iterator job(pending_jobs_.begin());
176 job != pending_jobs_.end(); 503 job != pending_jobs_.end();
177 ++job) { 504 ++job) {
178 delete job->first;
Joao da Silva 2012/01/02 16:14:43 Why? It seems that the outstanding URLFetcher will
Mattias Nissler (ping if slow) 2012/01/02 17:53:23 Must have deleted this by accident when making the
179 queued_jobs_.push_back(job->second); 505 queued_jobs_.push_back(job->second);
180 } 506 }
181 pending_jobs_.clear(); 507 pending_jobs_.clear();
182 } 508 }
183 509
184 DeviceManagementService::DeviceManagementService( 510 DeviceManagementService::DeviceManagementService(
185 const std::string& server_url) 511 const std::string& server_url)
186 : server_url_(server_url), 512 : server_url_(server_url),
187 initialized_(false), 513 initialized_(false),
188 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 514 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
189 } 515 }
190 516
191 void DeviceManagementService::AddJob(DeviceManagementJob* job) { 517 void DeviceManagementService::StartJob(DeviceManagementRequestJobImpl* job,
192 if (initialized_)
193 StartJob(job, false);
194 else
195 queued_jobs_.push_back(job);
196 }
197
198 void DeviceManagementService::RemoveJob(DeviceManagementJob* job) {
199 for (JobFetcherMap::iterator entry(pending_jobs_.begin());
200 entry != pending_jobs_.end();
201 ++entry) {
202 if (entry->second == job) {
203 delete entry->first;
204 pending_jobs_.erase(entry);
205 return;
206 }
207 }
208
209 const JobQueue::iterator elem =
210 std::find(queued_jobs_.begin(), queued_jobs_.end(), job);
211 if (elem != queued_jobs_.end())
212 queued_jobs_.erase(elem);
213 }
214
215 void DeviceManagementService::StartJob(DeviceManagementJob* job,
216 bool bypass_proxy) { 518 bool bypass_proxy) {
217 content::URLFetcher* fetcher = content::URLFetcher::Create( 519 content::URLFetcher* fetcher = content::URLFetcher::Create(
218 0, job->GetURL(server_url_), content::URLFetcher::POST, this); 520 0, job->GetURL(server_url_), content::URLFetcher::POST, this);
219 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 521 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
220 net::LOAD_DO_NOT_SAVE_COOKIES | 522 net::LOAD_DO_NOT_SAVE_COOKIES |
221 net::LOAD_DISABLE_CACHE | 523 net::LOAD_DISABLE_CACHE |
222 (bypass_proxy ? net::LOAD_BYPASS_PROXY : 0)); 524 (bypass_proxy ? net::LOAD_BYPASS_PROXY : 0));
223 fetcher->SetRequestContext(request_context_getter_.get()); 525 fetcher->SetRequestContext(request_context_getter_.get());
224 job->ConfigureRequest(fetcher); 526 job->ConfigureRequest(fetcher);
225 pending_jobs_[fetcher] = job; 527 pending_jobs_[fetcher] = job;
226 fetcher->Start(); 528 fetcher->Start();
227 } 529 }
228 530
229 void DeviceManagementService::OnURLFetchComplete( 531 void DeviceManagementService::OnURLFetchComplete(
230 const content::URLFetcher* source) { 532 const content::URLFetcher* source) {
231 JobFetcherMap::iterator entry(pending_jobs_.find(source)); 533 JobFetcherMap::iterator entry(pending_jobs_.find(source));
232 if (entry != pending_jobs_.end()) { 534 if (entry == pending_jobs_.end()) {
233 DeviceManagementJob* job = entry->second; 535 NOTREACHED() << "Callback from foreign URL fetcher";
234 pending_jobs_.erase(entry); 536 return;
537 }
235 538
236 // Retry the job if it failed due to a broken proxy, by bypassing the 539 DeviceManagementRequestJobImpl* job = entry->second;
237 // proxy on the next try. Don't retry if this URLFetcher already bypassed 540 pending_jobs_.erase(entry);
238 // the proxy. 541
239 bool retry = false; 542 // Retry the job if it failed due to a broken proxy, by bypassing the
240 if ((source->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0) { 543 // proxy on the next try. Don't retry if this URLFetcher already bypassed
241 if (!source->GetStatus().is_success() && 544 // the proxy.
242 IsProxyError(source->GetStatus())) { 545 bool retry = false;
243 LOG(WARNING) << "Proxy failed while contacting dmserver."; 546 if ((source->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0) {
244 retry = true; 547 if (!source->GetStatus().is_success() &&
245 } else if (source->GetStatus().is_success() && 548 IsProxyError(source->GetStatus())) {
246 source->WasFetchedViaProxy() && 549 LOG(WARNING) << "Proxy failed while contacting dmserver.";
247 !IsProtobufMimeType(source)) { 550 retry = true;
248 // The proxy server can be misconfigured but pointing to an existing 551 } else if (source->GetStatus().is_success() &&
249 // server that replies to requests. Try to recover if a successful 552 source->WasFetchedViaProxy() &&
250 // request that went through a proxy returns an unexpected mime type. 553 !IsProtobufMimeType(source)) {
251 LOG(WARNING) << "Got bad mime-type in response from dmserver that was " 554 // The proxy server can be misconfigured but pointing to an existing
252 << "fetched via a proxy."; 555 // server that replies to requests. Try to recover if a successful
253 retry = true; 556 // request that went through a proxy returns an unexpected mime type.
254 } 557 LOG(WARNING) << "Got bad mime-type in response from dmserver that was "
558 << "fetched via a proxy.";
559 retry = true;
255 } 560 }
561 }
256 562
257 if (retry) { 563 if (retry) {
258 LOG(WARNING) << "Retrying dmserver request without using a proxy."; 564 LOG(WARNING) << "Retrying dmserver request without using a proxy.";
259 StartJob(job, true); 565 StartJob(job, true);
260 } else {
261 std::string data;
262 source->GetResponseAsString(&data);
263 job->HandleResponse(source->GetStatus(), source->GetResponseCode(),
264 source->GetCookies(), data);
265 }
266 } else { 566 } else {
267 NOTREACHED() << "Callback from foreign URL fetcher"; 567 std::string data;
568 source->GetResponseAsString(&data);
569 job->HandleResponse(source->GetStatus(), source->GetResponseCode(),
570 source->GetCookies(), data);
268 } 571 }
269 delete source; 572 delete source;
270 } 573 }
271 574
575 void DeviceManagementService::AddJob(DeviceManagementRequestJobImpl* job) {
576 if (initialized_)
577 StartJob(job, false);
578 else
579 queued_jobs_.push_back(job);
580 }
581
582 void DeviceManagementService::RemoveJob(DeviceManagementRequestJobImpl* job) {
583 for (JobFetcherMap::iterator entry(pending_jobs_.begin());
584 entry != pending_jobs_.end();
585 ++entry) {
586 if (entry->second == job) {
587 pending_jobs_.erase(entry);
Joao da Silva 2012/01/02 16:14:43 If the job is removed, shouldn't its URLFetcher be
Mattias Nissler (ping if slow) 2012/01/02 17:53:23 You are absolutely right. Done.
588 return;
589 }
590 }
591
592 const JobQueue::iterator elem =
593 std::find(queued_jobs_.begin(), queued_jobs_.end(), job);
594 if (elem != queued_jobs_.end())
595 queued_jobs_.erase(elem);
596 }
597
272 } // namespace policy 598 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698