1 // Copyright 2014 The Chromium Authors
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 "components/nacl/renderer/manifest_downloader.h"
6
7 #include <utility>
8
9 #include "base/functional/callback.h"
10 #include "components/nacl/renderer/histogram.h"
11 #include "components/nacl/renderer/nexe_load_manager.h"
12 #include "net/base/net_errors.h"
13 #include "third_party/blink/public/platform/web_url_error.h"
14 #include "third_party/blink/public/platform/web_url_response.h"
15 #include "third_party/blink/public/web/web_associated_url_loader.h"
16
17 namespace nacl {
18
ManifestDownloader(std::unique_ptr<blink::WebAssociatedURLLoader> url_loader,bool is_installed,Callback cb)19 ManifestDownloader::ManifestDownloader(
20 std::unique_ptr<blink::WebAssociatedURLLoader> url_loader,
21 bool is_installed,
22 Callback cb)
23 : url_loader_(std::move(url_loader)),
24 is_installed_(is_installed),
25 cb_(std::move(cb)),
26 status_code_(-1),
27 pp_nacl_error_(PP_NACL_ERROR_LOAD_SUCCESS) {
28 CHECK(!cb_.is_null());
29 }
30
~ManifestDownloader()31 ManifestDownloader::~ManifestDownloader() { }
32
Load(const blink::WebURLRequest & request)33 void ManifestDownloader::Load(const blink::WebURLRequest& request) {
34 url_loader_->LoadAsynchronously(request, this);
35 }
36
DidReceiveResponse(const blink::WebURLResponse & response)37 void ManifestDownloader::DidReceiveResponse(
38 const blink::WebURLResponse& response) {
39 if (response.HttpStatusCode() != 200)
40 pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_LOAD_URL;
41 status_code_ = response.HttpStatusCode();
42 }
43
DidReceiveData(const char * data,int data_length)44 void ManifestDownloader::DidReceiveData(const char* data, int data_length) {
45 if (buffer_.size() + data_length > kNaClManifestMaxFileBytes) {
46 pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_TOO_LARGE;
47 buffer_.clear();
48 }
49
50 if (pp_nacl_error_ == PP_NACL_ERROR_LOAD_SUCCESS)
51 buffer_.append(data, data_length);
52 }
53
Close()54 void ManifestDownloader::Close() {
55 // We log the status code here instead of in didReceiveResponse so that we
56 // always log a histogram value, even when we never receive a status code.
57 HistogramHTTPStatusCode(
58 is_installed_ ? "NaCl.HttpStatusCodeClass.Manifest.InstalledApp" :
59 "NaCl.HttpStatusCodeClass.Manifest.NotInstalledApp",
60 status_code_);
61
62 std::move(cb_).Run(pp_nacl_error_, buffer_);
63 delete this;
64 }
65
DidFinishLoading()66 void ManifestDownloader::DidFinishLoading() {
67 Close();
68 }
69
DidFail(const blink::WebURLError & error)70 void ManifestDownloader::DidFail(const blink::WebURLError& error) {
71 // TODO(teravest): Find a place to share this code with PepperURLLoaderHost.
72 pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_LOAD_URL;
73 switch (error.reason()) {
74 case net::ERR_ACCESS_DENIED:
75 case net::ERR_NETWORK_ACCESS_DENIED:
76 pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
77 break;
78 }
79
80 if (error.is_web_security_violation())
81 pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
82
83 Close();
84 }
85
86 } // namespace nacl
87