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 "chrome/browser/net/chrome_network_delegate.h"
6
7#include "base/logging.h"
8#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
9#include "chrome/browser/extensions/extension_event_router_forwarder.h"
10#include "chrome/browser/extensions/extension_proxy_api.h"
11#include "chrome/browser/extensions/extension_webrequest_api.h"
12#include "chrome/browser/prefs/pref_member.h"
13#include "chrome/common/pref_names.h"
14#include "content/browser/browser_thread.h"
15#include "net/base/net_errors.h"
16#include "net/http/http_request_headers.h"
17#include "net/url_request/url_request.h"
18
19namespace {
20
21// If the |request| failed due to problems with a proxy, forward the error to
22// the proxy extension API.
23void ForwardProxyErrors(net::URLRequest* request,
24                        ExtensionEventRouterForwarder* event_router,
25                        ProfileId profile_id) {
26  if (request->status().status() == net::URLRequestStatus::FAILED) {
27    switch (request->status().os_error()) {
28      case net::ERR_PROXY_AUTH_UNSUPPORTED:
29      case net::ERR_PROXY_CONNECTION_FAILED:
30      case net::ERR_TUNNEL_CONNECTION_FAILED:
31        ExtensionProxyEventRouter::GetInstance()->OnProxyError(
32            event_router, profile_id, request->status().os_error());
33    }
34  }
35}
36
37}  // namespace
38
39ChromeNetworkDelegate::ChromeNetworkDelegate(
40    ExtensionEventRouterForwarder* event_router,
41    ProfileId profile_id,
42    BooleanPrefMember* enable_referrers,
43    ProtocolHandlerRegistry* protocol_handler_registry)
44    : event_router_(event_router),
45      profile_id_(profile_id),
46      enable_referrers_(enable_referrers),
47      protocol_handler_registry_(protocol_handler_registry) {
48  DCHECK(event_router);
49  DCHECK(enable_referrers);
50}
51
52ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
53
54// static
55void ChromeNetworkDelegate::InitializeReferrersEnabled(
56    BooleanPrefMember* enable_referrers,
57    PrefService* pref_service) {
58  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59  enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL);
60  enable_referrers->MoveToThread(BrowserThread::IO);
61}
62
63int ChromeNetworkDelegate::OnBeforeURLRequest(
64    net::URLRequest* request,
65    net::CompletionCallback* callback,
66    GURL* new_url) {
67  if (!enable_referrers_->GetValue())
68    request->set_referrer(std::string());
69  return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
70      profile_id_, event_router_.get(), request, callback, new_url);
71}
72
73int ChromeNetworkDelegate::OnBeforeSendHeaders(
74    uint64 request_id,
75    net::CompletionCallback* callback,
76    net::HttpRequestHeaders* headers) {
77  return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
78      profile_id_, event_router_.get(), request_id, callback, headers);
79}
80
81void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
82  ForwardProxyErrors(request, event_router_.get(), profile_id_);
83}
84
85void ChromeNetworkDelegate::OnReadCompleted(net::URLRequest* request,
86                                            int bytes_read) {
87  ForwardProxyErrors(request, event_router_.get(), profile_id_);
88}
89
90void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
91  ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
92      profile_id_, request);
93}
94
95net::URLRequestJob* ChromeNetworkDelegate::OnMaybeCreateURLRequestJob(
96      net::URLRequest* request) {
97  if (!protocol_handler_registry_)
98    return NULL;
99  return protocol_handler_registry_->MaybeCreateJob(request);
100}
101