1// Copyright (c) 2011 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_factory_impl.h"
6
7#include "base/stl_util.h"
8#include "net/base/load_flags.h"
9#include "net/url_request/url_request_interceptor.h"
10#include "net/url_request/url_request_job_manager.h"
11#include "url/gurl.h"
12
13namespace net {
14
15namespace {
16
17URLRequestInterceptor* g_interceptor_for_testing = NULL;
18
19}  // namespace
20
21URLRequestJobFactoryImpl::URLRequestJobFactoryImpl() {}
22
23URLRequestJobFactoryImpl::~URLRequestJobFactoryImpl() {
24  STLDeleteValues(&protocol_handler_map_);
25}
26
27bool URLRequestJobFactoryImpl::SetProtocolHandler(
28    const std::string& scheme,
29    ProtocolHandler* protocol_handler) {
30  DCHECK(CalledOnValidThread());
31
32  if (!protocol_handler) {
33    ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme);
34    if (it == protocol_handler_map_.end())
35      return false;
36
37    delete it->second;
38    protocol_handler_map_.erase(it);
39    return true;
40  }
41
42  if (ContainsKey(protocol_handler_map_, scheme))
43    return false;
44  protocol_handler_map_[scheme] = protocol_handler;
45  return true;
46}
47
48URLRequestJob* URLRequestJobFactoryImpl::MaybeCreateJobWithProtocolHandler(
49    const std::string& scheme,
50    URLRequest* request,
51    NetworkDelegate* network_delegate) const {
52  DCHECK(CalledOnValidThread());
53  if (g_interceptor_for_testing) {
54    URLRequestJob* job = g_interceptor_for_testing->MaybeInterceptRequest(
55        request, network_delegate);
56    if (job)
57      return job;
58  }
59
60  ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme);
61  if (it == protocol_handler_map_.end())
62    return NULL;
63  return it->second->MaybeCreateJob(request, network_delegate);
64}
65
66bool URLRequestJobFactoryImpl::IsHandledProtocol(
67    const std::string& scheme) const {
68  DCHECK(CalledOnValidThread());
69  return ContainsKey(protocol_handler_map_, scheme) ||
70      URLRequestJobManager::GetInstance()->SupportsScheme(scheme);
71}
72
73bool URLRequestJobFactoryImpl::IsHandledURL(const GURL& url) const {
74  if (!url.is_valid()) {
75    // We handle error cases.
76    return true;
77  }
78  return IsHandledProtocol(url.scheme());
79}
80
81bool URLRequestJobFactoryImpl::IsSafeRedirectTarget(
82    const GURL& location) const {
83  DCHECK(CalledOnValidThread());
84  if (!location.is_valid()) {
85    // Error cases are safely handled.
86    return true;
87  }
88  ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(
89      location.scheme());
90  if (it == protocol_handler_map_.end()) {
91    // Unhandled cases are safely handled.
92    return true;
93  }
94  return it->second->IsSafeRedirectTarget(location);
95}
96
97// static
98void URLRequestJobFactoryImpl::SetInterceptorForTesting(
99    URLRequestInterceptor* interceptor) {
100  DCHECK(!interceptor || !g_interceptor_for_testing);
101
102  g_interceptor_for_testing = interceptor;
103}
104
105}  // namespace net
106