summaryrefslogtreecommitdiff
path: root/chromium/content/browser/net/network_errors_listing_ui.cc
blob: 86ed0bb068b9b7cde66885493ffe3d571606dff0 (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
// Copyright 2015 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 "content/browser/net/network_errors_listing_ui.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/memory/ref_counted_memory.h"
#include "base/values.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_util.h"

static const char kDataFile[] = "network-error-data.json";
static const char kErrorCodeField[]  = "errorCode";
static const char kErrorCodesDataName[] = "errorCodes";
static const char kErrorIdField[]  = "errorId";
static const char kNetworkErrorKey[] = "netError";

namespace content {

namespace {

std::unique_ptr<base::ListValue> GetNetworkErrorData() {
  std::unique_ptr<base::DictionaryValue> error_codes = net::GetNetConstants();
  const base::DictionaryValue* net_error_codes_dict = nullptr;

  for (base::DictionaryValue::Iterator itr(*error_codes); !itr.IsAtEnd();
           itr.Advance()) {
    if (itr.key() == kNetworkErrorKey) {
      itr.value().GetAsDictionary(&net_error_codes_dict);
      break;
    }
  }

  std::unique_ptr<base::ListValue> error_list(new base::ListValue());

  for (base::DictionaryValue::Iterator itr(*net_error_codes_dict);
            !itr.IsAtEnd(); itr.Advance()) {
    int error_code;
    itr.value().GetAsInteger(&error_code);
    // Exclude the aborted and pending codes as these don't return a page.
    if (error_code != net::Error::ERR_IO_PENDING &&
        error_code != net::Error::ERR_ABORTED) {
      std::unique_ptr<base::DictionaryValue> error(new base::DictionaryValue());
      error->SetInteger(kErrorIdField, error_code);
      error->SetString(kErrorCodeField, itr.key());
      error_list->Append(std::move(error));
    }
  }
  return error_list;
}

bool HandleRequestCallback(BrowserContext* current_context,
                           const std::string& path,
                           const WebUIDataSource::GotDataCallback& callback) {
  if (path != kDataFile)
    return false;

  base::DictionaryValue data;
  data.Set(kErrorCodesDataName, GetNetworkErrorData().release());
  std::string json_string;
  base::JSONWriter::Write(data, &json_string);
  callback.Run(base::RefCountedString::TakeString(&json_string));
  return true;
}

} // namespace

NetworkErrorsListingUI::NetworkErrorsListingUI(WebUI* web_ui)
    : WebUIController(web_ui) {
  // Set up the chrome://network-errors source.
  WebUIDataSource* html_source =
      WebUIDataSource::Create(kChromeUINetworkErrorsListingHost);

  // Add required resources.
  html_source->SetJsonPath("strings.js");
  html_source->AddResourcePath("network_errors_listing.css",
                               IDR_NETWORK_ERROR_LISTING_CSS);
  html_source->AddResourcePath("network_errors_listing.js",
                               IDR_NETWORK_ERROR_LISTING_JS);
  html_source->SetDefaultResource(IDR_NETWORK_ERROR_LISTING_HTML);
  html_source->SetRequestFilter(
      base::Bind(&HandleRequestCallback,
                 web_ui->GetWebContents()->GetBrowserContext()));

  BrowserContext* browser_context =
      web_ui->GetWebContents()->GetBrowserContext();
  WebUIDataSource::Add(browser_context, html_source);
}

}  // namespace content