url_loader.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright 2020 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. #ifndef PDF_LOADER_URL_LOADER_H_
  5. #define PDF_LOADER_URL_LOADER_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include <string>
  10. #include "base/callback.h"
  11. #include "base/containers/circular_deque.h"
  12. #include "base/containers/span.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "third_party/blink/public/web/web_associated_url_loader_client.h"
  15. namespace blink {
  16. class WebAssociatedURLLoader;
  17. class WebString;
  18. class WebURL;
  19. class WebURLRequest;
  20. struct WebAssociatedURLLoaderOptions;
  21. } // namespace blink
  22. namespace net {
  23. class SiteForCookies;
  24. } // namespace net
  25. namespace chrome_pdf {
  26. // Properties for making a URL request.
  27. struct UrlRequest final {
  28. UrlRequest();
  29. UrlRequest(const UrlRequest& other);
  30. UrlRequest(UrlRequest&& other) noexcept;
  31. UrlRequest& operator=(const UrlRequest& other);
  32. UrlRequest& operator=(UrlRequest&& other) noexcept;
  33. ~UrlRequest();
  34. // Request URL.
  35. std::string url;
  36. // HTTP method.
  37. std::string method;
  38. // Whether to ignore redirects. By default, redirects are followed
  39. // automatically.
  40. bool ignore_redirects = false;
  41. // Custom referrer URL.
  42. std::string custom_referrer_url;
  43. // HTTP headers as a single string of `\n`-delimited key-value pairs.
  44. std::string headers;
  45. // Request body.
  46. std::string body;
  47. // Thresholds for throttling filling of the loader's internal buffer. Filling
  48. // will stop after exceeding the upper threshold, and resume after dropping
  49. // below the lower threshold.
  50. //
  51. // Default values taken from `ppapi/shared_impl/url_request_info_data.cc`. The
  52. // PDF viewer never changes the defaults in production, so these fields mostly
  53. // exist for testing purposes.
  54. size_t buffer_lower_threshold = 50 * 1000 * 1000;
  55. size_t buffer_upper_threshold = 100 * 1000 * 1000;
  56. };
  57. // Properties returned from a URL request. Does not include the response body.
  58. struct UrlResponse final {
  59. UrlResponse();
  60. UrlResponse(const UrlResponse& other);
  61. UrlResponse(UrlResponse&& other) noexcept;
  62. UrlResponse& operator=(const UrlResponse& other);
  63. UrlResponse& operator=(UrlResponse&& other) noexcept;
  64. ~UrlResponse();
  65. // HTTP status code.
  66. int32_t status_code = 0;
  67. // HTTP headers as a single string of `\n`-delimited key-value pairs.
  68. std::string headers;
  69. };
  70. // A Blink URL loader. This implementation tries to emulate a combination of
  71. // `content::PepperURLLoaderHost` and `ppapi::proxy::URLLoaderResource`.
  72. class UrlLoader final : public blink::WebAssociatedURLLoaderClient {
  73. public:
  74. // Client interface required by `UrlLoader`. Instances should be passed using
  75. // weak pointers, as the loader can be shared, and may outlive the client.
  76. class Client {
  77. public:
  78. // Returns `true` if the client is still usable. The client may require
  79. // resources that can become unavailable, such as a local frame. Rather than
  80. // handling missing resources separately for each method, callers can just
  81. // verify validity once, before making any other calls.
  82. virtual bool IsValid() const = 0;
  83. // Completes `partial_url` using the current document.
  84. virtual blink::WebURL CompleteURL(
  85. const blink::WebString& partial_url) const = 0;
  86. // Gets the site-for-cookies for the current document.
  87. virtual net::SiteForCookies SiteForCookies() const = 0;
  88. // Sets the referrer on `request` to `referrer_url` using the current frame.
  89. virtual void SetReferrerForRequest(blink::WebURLRequest& request,
  90. const blink::WebURL& referrer_url) = 0;
  91. // Returns a new `blink::WebAssociatedURLLoader` from the current frame.
  92. virtual std::unique_ptr<blink::WebAssociatedURLLoader>
  93. CreateAssociatedURLLoader(
  94. const blink::WebAssociatedURLLoaderOptions& options) = 0;
  95. protected:
  96. ~Client() = default;
  97. };
  98. explicit UrlLoader(base::WeakPtr<Client> client);
  99. UrlLoader(const UrlLoader&) = delete;
  100. UrlLoader& operator=(const UrlLoader&) = delete;
  101. ~UrlLoader() override;
  102. // Mimic `pp::URLLoader`:
  103. void Open(const UrlRequest& request, base::OnceCallback<void(int)> callback);
  104. void ReadResponseBody(base::span<char> buffer,
  105. base::OnceCallback<void(int)> callback);
  106. void Close();
  107. // Returns the URL response (not including the body). Only valid after
  108. // `Open()` completes.
  109. const UrlResponse& response() const { return response_; }
  110. // blink::WebAssociatedURLLoaderClient:
  111. bool WillFollowRedirect(
  112. const blink::WebURL& new_url,
  113. const blink::WebURLResponse& redirect_response) override;
  114. void DidSendData(uint64_t bytes_sent,
  115. uint64_t total_bytes_to_be_sent) override;
  116. void DidReceiveResponse(const blink::WebURLResponse& response) override;
  117. void DidDownloadData(uint64_t data_length) override;
  118. void DidReceiveData(const char* data, int data_length) override;
  119. void DidFinishLoading() override;
  120. void DidFail(const blink::WebURLError& error) override;
  121. private:
  122. enum class LoadingState {
  123. // Before calling `Open()`.
  124. kWaitingToOpen,
  125. // After calling `Open()`, but before `DidReceiveResponse()` or `DidFail()`.
  126. kOpening,
  127. // After `DidReceiveResponse()`, but before `DidFinishLoading()` or
  128. // `DidFail()`. Zero or more calls allowed to `DidReceiveData()`.
  129. kStreamingData,
  130. // After `DidFinishLoading()` or `DidFail()`, or forced by `Close()`.
  131. // Details about how the load completed are in `complete_result_`.
  132. kLoadComplete,
  133. };
  134. // Aborts the load with `result`. Runs callback if pending.
  135. void AbortLoad(int32_t result);
  136. // Runs callback for `ReadResponseBody()` if pending.
  137. void RunReadCallback();
  138. void SetLoadComplete(int32_t result);
  139. base::WeakPtr<Client> client_;
  140. LoadingState state_ = LoadingState::kWaitingToOpen;
  141. int32_t complete_result_ = 0;
  142. std::unique_ptr<blink::WebAssociatedURLLoader> blink_loader_;
  143. bool ignore_redirects_ = false;
  144. base::OnceCallback<void(int)> open_callback_;
  145. UrlResponse response_;
  146. // Thresholds control buffer throttling, as defined in `UrlRequest`.
  147. size_t buffer_lower_threshold_ = 0;
  148. size_t buffer_upper_threshold_ = 0;
  149. bool deferring_loading_ = false;
  150. base::circular_deque<char> buffer_;
  151. base::OnceCallback<void(int)> read_callback_;
  152. base::span<char> client_buffer_;
  153. };
  154. } // namespace chrome_pdf
  155. #endif // PDF_LOADER_URL_LOADER_H_