summaryrefslogtreecommitdiffstats
path: root/chrome/browser/devtools/devtools_network_controller.cc
blob: 1d22fe94e619a057cddf27e1f7c9e988ed793d40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/devtools/devtools_network_controller.h"

#include "chrome/browser/devtools/devtools_network_conditions.h"
#include "chrome/browser/devtools/devtools_network_interceptor.h"
#include "chrome/browser/devtools/devtools_network_transaction.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_info.h"

using content::BrowserThread;

DevToolsNetworkController::DevToolsNetworkController()
    : default_interceptor_(new DevToolsNetworkInterceptor()),
      appcache_interceptor_(new DevToolsNetworkInterceptor()),
      weak_ptr_factory_(this) {
}

DevToolsNetworkController::~DevToolsNetworkController() {
}

base::WeakPtr<DevToolsNetworkInterceptor>
DevToolsNetworkController::GetInterceptor(
    DevToolsNetworkTransaction* transaction) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(transaction->request());

  if (!interceptors_.size())
    return default_interceptor_->GetWeakPtr();

  if (transaction->request()->load_flags & net::LOAD_DISABLE_INTERCEPT)
    return appcache_interceptor_->GetWeakPtr();

  transaction->ProcessRequest();

  const std::string& client_id = transaction->client_id();
  if (client_id.empty())
    return default_interceptor_->GetWeakPtr();

  DevToolsNetworkInterceptor* interceptor = interceptors_.get(client_id);
  DCHECK(interceptor);
  if (!interceptor)
    return default_interceptor_->GetWeakPtr();

  return interceptor->GetWeakPtr();
}

void DevToolsNetworkController::SetNetworkState(
    const std::string& client_id,
    scoped_ptr<DevToolsNetworkConditions> conditions) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  BrowserThread::PostTask(
      content::BrowserThread::IO,
      FROM_HERE,
      base::Bind(
          &DevToolsNetworkController::SetNetworkStateOnIO,
          weak_ptr_factory_.GetWeakPtr(),
          client_id,
          base::Passed(&conditions)));
}

void DevToolsNetworkController::SetNetworkStateOnIO(
    const std::string& client_id,
    scoped_ptr<DevToolsNetworkConditions> conditions) {
  DCHECK(thread_checker_.CalledOnValidThread());

  DevToolsNetworkInterceptor* interceptor = interceptors_.get(client_id);
  if (!interceptor) {
    DCHECK(conditions);
    if (!conditions)
      return;
    Interceptor new_interceptor = Interceptor(new DevToolsNetworkInterceptor());
    new_interceptor->UpdateConditions(conditions.Pass());
    interceptors_.set(client_id, new_interceptor.Pass());
  } else {
    if (!conditions) {
      scoped_ptr<DevToolsNetworkConditions> online_conditions(
          new DevToolsNetworkConditions());
      interceptor->UpdateConditions(online_conditions.Pass());
      interceptors_.erase(client_id);
    } else {
      interceptor->UpdateConditions(conditions.Pass());
    }
  }

  bool has_offline_interceptors = false;
  Interceptors::iterator it = interceptors_.begin();
  for (; it != interceptors_.end(); ++it) {
    if (it->second->conditions()->offline()) {
      has_offline_interceptors = true;
      break;
    }
  }

  bool is_appcache_offline = appcache_interceptor_->conditions()->offline();
  if (is_appcache_offline != has_offline_interceptors) {
    scoped_ptr<DevToolsNetworkConditions> appcache_conditions(
        new DevToolsNetworkConditions(has_offline_interceptors));
    appcache_interceptor_->UpdateConditions(appcache_conditions.Pass());
  }
}