File: url_loader.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (203 lines) | stat: -rw-r--r-- 6,606 bytes parent folder | download | duplicates (6)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PDF_LOADER_URL_LOADER_H_
#define PDF_LOADER_URL_LOADER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>

#include "base/containers/circular_deque.h"
#include "base/containers/span.h"
#include "base/functional/callback.h"
#include "base/memory/raw_span.h"
#include "base/memory/weak_ptr.h"
#include "pdf/loader/result_codes.h"
#include "third_party/blink/public/web/web_associated_url_loader_client.h"

namespace blink {
class WebAssociatedURLLoader;
class WebString;
class WebURL;
class WebURLRequest;
struct WebAssociatedURLLoaderOptions;
}  // namespace blink

namespace net {
class SiteForCookies;
}  // namespace net

namespace chrome_pdf {

// Properties for making a URL request.
struct UrlRequest final {
  UrlRequest();
  UrlRequest(const UrlRequest& other);
  UrlRequest(UrlRequest&& other) noexcept;
  UrlRequest& operator=(const UrlRequest& other);
  UrlRequest& operator=(UrlRequest&& other) noexcept;
  ~UrlRequest();

  // Request URL.
  std::string url;

  // HTTP method.
  std::string method;

  // Whether to ignore redirects. By default, redirects are followed
  // automatically.
  bool ignore_redirects = false;

  // Custom referrer URL.
  std::string custom_referrer_url;

  // HTTP headers as a single string of `\n`-delimited key-value pairs.
  std::string headers;

  // Request body.
  std::string body;

  // Thresholds for throttling filling of the loader's internal buffer. Filling
  // will stop after exceeding the upper threshold, and resume after dropping
  // below the lower threshold.
  //
  // Default values taken from `ppapi/shared_impl/url_request_info_data.cc`. The
  // PDF viewer never changes the defaults in production, so these fields mostly
  // exist for testing purposes.
  size_t buffer_lower_threshold = 50 * 1000 * 1000;
  size_t buffer_upper_threshold = 100 * 1000 * 1000;
};

// Properties returned from a URL request. Does not include the response body.
struct UrlResponse final {
  UrlResponse();
  UrlResponse(const UrlResponse& other);
  UrlResponse(UrlResponse&& other) noexcept;
  UrlResponse& operator=(const UrlResponse& other);
  UrlResponse& operator=(UrlResponse&& other) noexcept;
  ~UrlResponse();

  // HTTP status code.
  int32_t status_code = 0;

  // HTTP headers as a single string of `\n`-delimited key-value pairs.
  std::string headers;
};

// A Blink URL loader. This implementation tries to emulate a combination of
// `content::PepperURLLoaderHost` and `ppapi::proxy::URLLoaderResource`.
class UrlLoader final : public blink::WebAssociatedURLLoaderClient {
 public:
  using OpenCallback = base::OnceCallback<void(Result)>;

  // Client interface required by `UrlLoader`. Instances should be passed using
  // weak pointers, as the loader can be shared, and may outlive the client.
  class Client {
   public:
    // Returns `true` if the client is still usable. The client may require
    // resources that can become unavailable, such as a local frame. Rather than
    // handling missing resources separately for each method, callers can just
    // verify validity once, before making any other calls.
    virtual bool IsValid() const = 0;

    // Completes `partial_url` using the current document.
    virtual blink::WebURL CompleteURL(
        const blink::WebString& partial_url) const = 0;

    // Gets the site-for-cookies for the current document.
    virtual net::SiteForCookies SiteForCookies() const = 0;

    // Sets the referrer on `request` to `referrer_url` using the current frame.
    virtual void SetReferrerForRequest(blink::WebURLRequest& request,
                                       const blink::WebURL& referrer_url) = 0;

    // Returns a new `blink::WebAssociatedURLLoader` from the current frame.
    virtual std::unique_ptr<blink::WebAssociatedURLLoader>
    CreateAssociatedURLLoader(
        const blink::WebAssociatedURLLoaderOptions& options) = 0;

   protected:
    ~Client() = default;
  };

  explicit UrlLoader(base::WeakPtr<Client> client);
  UrlLoader(const UrlLoader&) = delete;
  UrlLoader& operator=(const UrlLoader&) = delete;
  ~UrlLoader() override;

  // Mimic `pp::URLLoader`:
  void Open(const UrlRequest& request, OpenCallback callback);
  void ReadResponseBody(base::span<char> buffer,
                        base::OnceCallback<void(int)> callback);
  void Close();

  // Returns the URL response (not including the body). Only valid after
  // `Open()` completes.
  const UrlResponse& response() const { return response_; }

  // blink::WebAssociatedURLLoaderClient:
  bool WillFollowRedirect(
      const blink::WebURL& new_url,
      const blink::WebURLResponse& redirect_response) override;
  void DidSendData(uint64_t bytes_sent,
                   uint64_t total_bytes_to_be_sent) override;
  void DidReceiveResponse(const blink::WebURLResponse& response) override;
  void DidDownloadData(uint64_t data_length) override;
  void DidReceiveData(base::span<const char> data) override;
  void DidFinishLoading() override;
  void DidFail(const blink::WebURLError& error) override;

 private:
  enum class LoadingState {
    // Before calling `Open()`.
    kWaitingToOpen,

    // After calling `Open()`, but before `DidReceiveResponse()` or `DidFail()`.
    kOpening,

    // After `DidReceiveResponse()`, but before `DidFinishLoading()` or
    // `DidFail()`. Zero or more calls allowed to `DidReceiveData()`.
    kStreamingData,

    // After `DidFinishLoading()` or `DidFail()`, or forced by `Close()`.
    // Details about how the load completed are in `complete_result_`.
    kLoadComplete,
  };

  // Aborts the load with `result`. Runs callback if pending.
  void AbortLoad(Result result);

  // Runs callback for `ReadResponseBody()` if pending.
  void RunReadCallback();

  void SetLoadComplete(Result result);

  base::WeakPtr<Client> client_;

  LoadingState state_ = LoadingState::kWaitingToOpen;
  Result complete_result_ = Result::kSuccess;

  std::unique_ptr<blink::WebAssociatedURLLoader> blink_loader_;

  bool ignore_redirects_ = false;
  OpenCallback open_callback_;

  UrlResponse response_;

  // Thresholds control buffer throttling, as defined in `UrlRequest`.
  size_t buffer_lower_threshold_ = 0;
  size_t buffer_upper_threshold_ = 0;
  bool deferring_loading_ = false;
  base::circular_deque<char> buffer_;

  base::OnceCallback<void(int)> read_callback_;
  base::raw_span<char> client_buffer_;
};

}  // namespace chrome_pdf

#endif  // PDF_LOADER_URL_LOADER_H_