xref: /aosp_15_r20/external/cronet/components/cronet/cronet_url_request.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
6 #define COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/functional/callback.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/time/time.h"
15 #include "net/base/idempotency.h"
16 #include "net/base/network_handle.h"
17 #include "net/base/request_priority.h"
18 #include "net/url_request/url_request.h"
19 #include "url/gurl.h"
20 
21 namespace net {
22 class HttpRequestHeaders;
23 enum LoadState;
24 class SSLCertRequestInfo;
25 class SSLInfo;
26 class UploadDataStream;
27 }  // namespace net
28 
29 namespace cronet {
30 
31 class CronetContext;
32 class TestUtil;
33 
34 // Wrapper around net::URLRequestContext.
35 // Created and configured from client thread. Start, ReadData, and Destroy are
36 // posted to network thread and all callbacks into the Callback() are
37 // done on the network thread. CronetUrlRequest client is expected to initiate
38 // the next step like FollowDeferredRedirect, ReadData or Destroy. Public
39 // methods can be called on any thread.
40 class CronetURLRequest {
41  public:
42   // Callback implemented by CronetURLRequest() caller and owned by
43   // CronetURLRequest::NetworkTasks. All callback methods are invoked on network
44   // thread.
45   class Callback {
46    public:
47     virtual ~Callback() = default;
48 
49     // Invoked whenever a redirect is encountered. This will only be invoked
50     // between the call to CronetURLRequest::Start() and
51     // Callback::OnResponseStarted(). The body of the redirect response, if
52     // it has one, will be ignored.
53     //
54     // The redirect will not be followed until
55     // CronetURLRequest::FollowDeferredRedirect() method is called, either
56     // synchronously or asynchronously.
57     virtual void OnReceivedRedirect(const std::string& new_location,
58                                     int http_status_code,
59                                     const std::string& http_status_text,
60                                     const net::HttpResponseHeaders* headers,
61                                     bool was_cached,
62                                     const std::string& negotiated_protocol,
63                                     const std::string& proxy_server,
64                                     int64_t received_byte_count) = 0;
65 
66     // Invoked when the final set of headers, after all redirects, is received.
67     // Will only be invoked once for each request.
68     //
69     // With the exception of Callback::OnCanceled(),
70     // no other Callback method will be invoked for the request,
71     // including Callback::OnSucceeded() and Callback::OnFailed(), until
72     // CronetUrlRequest::Read() is called to attempt to start reading the
73     // response body.
74     virtual void OnResponseStarted(int http_status_code,
75                                    const std::string& http_status_text,
76                                    const net::HttpResponseHeaders* headers,
77                                    bool was_cached,
78                                    const std::string& negotiated_protocol,
79                                    const std::string& proxy_server,
80                                    int64_t received_byte_count) = 0;
81 
82     // Invoked whenever part of the response body has been read. Only part of
83     // the buffer may be populated, even if the entire response body has not yet
84     // been consumed.
85     //
86     // With the exception of Callback::OnCanceled(),
87     // no other Callback method will be invoked for the request,
88     // including Callback::OnSucceeded() and Callback::OnFailed(), until
89     // CronetUrlRequest::Read() is called to attempt to continue reading the
90     // response body.
91     virtual void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
92                                  int bytes_read,
93                                  int64_t received_byte_count) = 0;
94 
95     // Invoked when request is completed successfully.
96     virtual void OnSucceeded(int64_t received_byte_count) = 0;
97 
98     // Invoked if request failed for any reason after CronetURLRequest::Start().
99     // |net_error| provides information about the failure. |quic_error| is only
100     // valid if |net_error| is net::QUIC_PROTOCOL_ERROR.
101     virtual void OnError(int net_error,
102                          int quic_error,
103                          const std::string& error_string,
104                          int64_t received_byte_count) = 0;
105 
106     // Invoked if request was canceled via CronetURLRequest::Destroy().
107     virtual void OnCanceled() = 0;
108 
109     // Invoked when request is destroyed. Once invoked, no other Callback
110     // methods will be invoked.
111     virtual void OnDestroyed() = 0;
112 
113     // Reports metrics data about the request.
114     // This is called immediately before the terminal state callback (i.e.
115     // OnSucceeded()/OnError()/OnCanceled()).
116     virtual void OnMetricsCollected(
117         const base::Time& request_start_time,
118         const base::TimeTicks& request_start,
119         const base::TimeTicks& dns_start,
120         const base::TimeTicks& dns_end,
121         const base::TimeTicks& connect_start,
122         const base::TimeTicks& connect_end,
123         const base::TimeTicks& ssl_start,
124         const base::TimeTicks& ssl_end,
125         const base::TimeTicks& send_start,
126         const base::TimeTicks& send_end,
127         const base::TimeTicks& push_start,
128         const base::TimeTicks& push_end,
129         const base::TimeTicks& receive_headers_end,
130         const base::TimeTicks& request_end,
131         bool socket_reused,
132         int64_t sent_bytes_count,
133         int64_t received_bytes_count,
134         bool quic_connection_migration_attempted,
135         bool quic_connection_migration_successful) = 0;
136   };
137   // Invoked in response to CronetURLRequest::GetStatus() to allow multiple
138   // overlapping calls. The load states correspond to the lengthy periods of
139   // time that a request load may be blocked and unable to make progress.
140   using OnStatusCallback = base::OnceCallback<void(net::LoadState)>;
141 
142   // Bypasses cache if |disable_cache| is true. If context is not set up to
143   // use cache, |disable_cache| has no effect. |disable_connection_migration|
144   // causes connection migration to be disabled for this request if true. If
145   // global connection migration flag is not enabled,
146   // |disable_connection_migration| has no effect.
147   CronetURLRequest(CronetContext* context,
148                    std::unique_ptr<Callback> callback,
149                    const GURL& url,
150                    net::RequestPriority priority,
151                    bool disable_cache,
152                    bool disable_connection_migration,
153                    bool traffic_stats_tag_set,
154                    int32_t traffic_stats_tag,
155                    bool traffic_stats_uid_set,
156                    int32_t traffic_stats_uid,
157                    net::Idempotency idempotency,
158                    net::handles::NetworkHandle network =
159                        net::handles::kInvalidNetworkHandle);
160 
161   CronetURLRequest(const CronetURLRequest&) = delete;
162   CronetURLRequest& operator=(const CronetURLRequest&) = delete;
163 
164   // Methods called prior to Start are never called on network thread.
165 
166   // Sets the request method GET, POST etc.
167   bool SetHttpMethod(const std::string& method);
168 
169   // Adds a header to the request before it starts.
170   bool AddRequestHeader(const std::string& name, const std::string& value);
171 
172   // Adds a request body to the request before it starts.
173   void SetUpload(std::unique_ptr<net::UploadDataStream> upload);
174 
175   // Starts the request.
176   void Start();
177 
178   // GetStatus invokes |on_status_callback| on network thread to allow multiple
179   // overlapping calls.
180   void GetStatus(OnStatusCallback on_status_callback) const;
181 
182   // Follows redirect.
183   void FollowDeferredRedirect();
184 
185   // Reads more data.
186   bool ReadData(net::IOBuffer* buffer, int max_bytes);
187 
188   // Releases all resources for the request and deletes the object itself.
189   // |send_on_canceled| indicates whether OnCanceled callback should be
190   // issued to indicate when no more callbacks will be issued.
191   void Destroy(bool send_on_canceled);
192 
193   // On the network thread, reports metrics to the registered
194   // CronetURLRequest::Callback, and then runs |callback| on the network thread.
195   //
196   // Since metrics are only reported once, this can be used to ensure metrics
197   // are reported to the registered CronetURLRequest::Callback before resources
198   // used by the callback are deleted.
199   void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
200 
201  private:
202   friend class TestUtil;
203 
204   // Private destructor invoked fron NetworkTasks::Destroy() on network thread.
205   ~CronetURLRequest();
206 
207   // NetworkTasks performs tasks on the network thread and owns objects that
208   // live on the network thread.
209   class NetworkTasks : public net::URLRequest::Delegate {
210    public:
211     // Invoked off the network thread.
212     NetworkTasks(std::unique_ptr<Callback> callback,
213                  const GURL& url,
214                  net::RequestPriority priority,
215                  int load_flags,
216                  bool traffic_stats_tag_set,
217                  int32_t traffic_stats_tag,
218                  bool traffic_stats_uid_set,
219                  int32_t traffic_stats_uid,
220                  net::Idempotency idempotency,
221                  net::handles::NetworkHandle network);
222 
223     NetworkTasks(const NetworkTasks&) = delete;
224     NetworkTasks& operator=(const NetworkTasks&) = delete;
225 
226     // Invoked on the network thread.
227     ~NetworkTasks() override;
228 
229     // Starts the request.
230     void Start(CronetContext* context,
231                const std::string& method,
232                std::unique_ptr<net::HttpRequestHeaders> request_headers,
233                std::unique_ptr<net::UploadDataStream> upload);
234 
235     // Gets status of the requrest and invokes |on_status_callback| to allow
236     // multiple overlapping calls.
237     void GetStatus(OnStatusCallback on_status_callback) const;
238 
239     // Follows redirect.
240     void FollowDeferredRedirect();
241 
242     // Reads more data.
243     void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size);
244 
245     // Releases all resources for the request and deletes the |request|, which
246     // owns |this|, so |this| is also deleted.
247     // |send_on_canceled| indicates whether OnCanceled callback should be
248     // issued to indicate when no more callbacks will be issued.
249     void Destroy(CronetURLRequest* request, bool send_on_canceled);
250 
251     // Runs MaybeReportMetrics(), then runs |callback|.
252     void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
253 
254    private:
255     friend class TestUtil;
256 
257     // net::URLRequest::Delegate implementations:
258     void OnReceivedRedirect(net::URLRequest* request,
259                             const net::RedirectInfo& redirect_info,
260                             bool* defer_redirect) override;
261     void OnCertificateRequested(
262         net::URLRequest* request,
263         net::SSLCertRequestInfo* cert_request_info) override;
264     void OnSSLCertificateError(net::URLRequest* request,
265                                int net_error,
266                                const net::SSLInfo& ssl_info,
267                                bool fatal) override;
268     void OnResponseStarted(net::URLRequest* request, int net_error) override;
269     void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
270 
271     // Report error and cancel request_adapter.
272     void ReportError(net::URLRequest* request, int net_error);
273     // Reports metrics collected.
274     void MaybeReportMetrics();
275 
276     // Callback implemented by the client.
277     std::unique_ptr<CronetURLRequest::Callback> callback_;
278 
279     const GURL initial_url_;
280     const net::RequestPriority initial_priority_;
281     const int initial_load_flags_;
282     // Count of bytes received during redirect is added to received byte count.
283     int64_t received_byte_count_from_redirects_;
284 
285     // Whether error has been already reported, for example from
286     // OnSSLCertificateError().
287     bool error_reported_;
288 
289     // Whether metrics have been reported.
290     bool metrics_reported_;
291 
292     // Whether |traffic_stats_tag_| should be applied.
293     const bool traffic_stats_tag_set_;
294     // TrafficStats tag to apply to URLRequest.
295     const int32_t traffic_stats_tag_;
296     // Whether |traffic_stats_uid_| should be applied.
297     const bool traffic_stats_uid_set_;
298     // UID to be applied to URLRequest.
299     const int32_t traffic_stats_uid_;
300     // Idempotency of the request.
301     const net::Idempotency idempotency_;
302 
303     net::handles::NetworkHandle network_;
304 
305     scoped_refptr<net::IOBuffer> read_buffer_;
306     std::unique_ptr<net::URLRequest> url_request_;
307 
308     THREAD_CHECKER(network_thread_checker_);
309   };
310 
311   raw_ptr<CronetContext> context_;
312   // |network_tasks_| is invoked on network thread.
313   NetworkTasks network_tasks_;
314 
315   // Request parameters set off network thread before Start().
316   std::string initial_method_;
317   std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_;
318   std::unique_ptr<net::UploadDataStream> upload_;
319 };
320 
321 }  // namespace cronet
322 
323 #endif  // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
324