• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     // Invoked right before request is destroyed to report collected metrics.
114     virtual void OnMetricsCollected(
115         const base::Time& request_start_time,
116         const base::TimeTicks& request_start,
117         const base::TimeTicks& dns_start,
118         const base::TimeTicks& dns_end,
119         const base::TimeTicks& connect_start,
120         const base::TimeTicks& connect_end,
121         const base::TimeTicks& ssl_start,
122         const base::TimeTicks& ssl_end,
123         const base::TimeTicks& send_start,
124         const base::TimeTicks& send_end,
125         const base::TimeTicks& push_start,
126         const base::TimeTicks& push_end,
127         const base::TimeTicks& receive_headers_end,
128         const base::TimeTicks& request_end,
129         bool socket_reused,
130         int64_t sent_bytes_count,
131         int64_t received_bytes_count,
132         bool quic_connection_migration_attempted,
133         bool quic_connection_migration_successful) = 0;
134   };
135   // Invoked in response to CronetURLRequest::GetStatus() to allow multiple
136   // overlapping calls. The load states correspond to the lengthy periods of
137   // time that a request load may be blocked and unable to make progress.
138   using OnStatusCallback = base::OnceCallback<void(net::LoadState)>;
139 
140   // Bypasses cache if |disable_cache| is true. If context is not set up to
141   // use cache, |disable_cache| has no effect. |disable_connection_migration|
142   // causes connection migration to be disabled for this request if true. If
143   // global connection migration flag is not enabled,
144   // |disable_connection_migration| has no effect.
145   CronetURLRequest(CronetContext* context,
146                    std::unique_ptr<Callback> callback,
147                    const GURL& url,
148                    net::RequestPriority priority,
149                    bool disable_cache,
150                    bool disable_connection_migration,
151                    bool traffic_stats_tag_set,
152                    int32_t traffic_stats_tag,
153                    bool traffic_stats_uid_set,
154                    int32_t traffic_stats_uid,
155                    net::Idempotency idempotency,
156                    net::handles::NetworkHandle network =
157                        net::handles::kInvalidNetworkHandle);
158 
159   CronetURLRequest(const CronetURLRequest&) = delete;
160   CronetURLRequest& operator=(const CronetURLRequest&) = delete;
161 
162   // Methods called prior to Start are never called on network thread.
163 
164   // Sets the request method GET, POST etc.
165   bool SetHttpMethod(const std::string& method);
166 
167   // Adds a header to the request before it starts.
168   bool AddRequestHeader(const std::string& name, const std::string& value);
169 
170   // Adds a request body to the request before it starts.
171   void SetUpload(std::unique_ptr<net::UploadDataStream> upload);
172 
173   // Starts the request.
174   void Start();
175 
176   // GetStatus invokes |on_status_callback| on network thread to allow multiple
177   // overlapping calls.
178   void GetStatus(OnStatusCallback on_status_callback) const;
179 
180   // Follows redirect.
181   void FollowDeferredRedirect();
182 
183   // Reads more data.
184   bool ReadData(net::IOBuffer* buffer, int max_bytes);
185 
186   // Releases all resources for the request and deletes the object itself.
187   // |send_on_canceled| indicates whether OnCanceled callback should be
188   // issued to indicate when no more callbacks will be issued.
189   void Destroy(bool send_on_canceled);
190 
191   // On the network thread, reports metrics to the registered
192   // CronetURLRequest::Callback, and then runs |callback| on the network thread.
193   //
194   // Since metrics are only reported once, this can be used to ensure metrics
195   // are reported to the registered CronetURLRequest::Callback before resources
196   // used by the callback are deleted.
197   void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
198 
199  private:
200   friend class TestUtil;
201 
202   // Private destructor invoked fron NetworkTasks::Destroy() on network thread.
203   ~CronetURLRequest();
204 
205   // NetworkTasks performs tasks on the network thread and owns objects that
206   // live on the network thread.
207   class NetworkTasks : public net::URLRequest::Delegate {
208    public:
209     // Invoked off the network thread.
210     NetworkTasks(std::unique_ptr<Callback> callback,
211                  const GURL& url,
212                  net::RequestPriority priority,
213                  int load_flags,
214                  bool traffic_stats_tag_set,
215                  int32_t traffic_stats_tag,
216                  bool traffic_stats_uid_set,
217                  int32_t traffic_stats_uid,
218                  net::Idempotency idempotency,
219                  net::handles::NetworkHandle network);
220 
221     NetworkTasks(const NetworkTasks&) = delete;
222     NetworkTasks& operator=(const NetworkTasks&) = delete;
223 
224     // Invoked on the network thread.
225     ~NetworkTasks() override;
226 
227     // Starts the request.
228     void Start(CronetContext* context,
229                const std::string& method,
230                std::unique_ptr<net::HttpRequestHeaders> request_headers,
231                std::unique_ptr<net::UploadDataStream> upload);
232 
233     // Gets status of the requrest and invokes |on_status_callback| to allow
234     // multiple overlapping calls.
235     void GetStatus(OnStatusCallback on_status_callback) const;
236 
237     // Follows redirect.
238     void FollowDeferredRedirect();
239 
240     // Reads more data.
241     void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size);
242 
243     // Releases all resources for the request and deletes the |request|, which
244     // owns |this|, so |this| is also deleted.
245     // |send_on_canceled| indicates whether OnCanceled callback should be
246     // issued to indicate when no more callbacks will be issued.
247     void Destroy(CronetURLRequest* request, bool send_on_canceled);
248 
249     // Runs MaybeReportMetrics(), then runs |callback|.
250     void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
251 
252    private:
253     friend class TestUtil;
254 
255     // net::URLRequest::Delegate implementations:
256     void OnReceivedRedirect(net::URLRequest* request,
257                             const net::RedirectInfo& redirect_info,
258                             bool* defer_redirect) override;
259     void OnCertificateRequested(
260         net::URLRequest* request,
261         net::SSLCertRequestInfo* cert_request_info) override;
262     void OnSSLCertificateError(net::URLRequest* request,
263                                int net_error,
264                                const net::SSLInfo& ssl_info,
265                                bool fatal) override;
266     void OnResponseStarted(net::URLRequest* request, int net_error) override;
267     void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
268 
269     // Report error and cancel request_adapter.
270     void ReportError(net::URLRequest* request, int net_error);
271     // Reports metrics collected.
272     void MaybeReportMetrics();
273 
274     // Callback implemented by the client.
275     std::unique_ptr<CronetURLRequest::Callback> callback_;
276 
277     const GURL initial_url_;
278     const net::RequestPriority initial_priority_;
279     const int initial_load_flags_;
280     // Count of bytes received during redirect is added to received byte count.
281     int64_t received_byte_count_from_redirects_;
282 
283     // Whether error has been already reported, for example from
284     // OnSSLCertificateError().
285     bool error_reported_;
286 
287     // Whether metrics have been reported.
288     bool metrics_reported_;
289 
290     // Whether |traffic_stats_tag_| should be applied.
291     const bool traffic_stats_tag_set_;
292     // TrafficStats tag to apply to URLRequest.
293     const int32_t traffic_stats_tag_;
294     // Whether |traffic_stats_uid_| should be applied.
295     const bool traffic_stats_uid_set_;
296     // UID to be applied to URLRequest.
297     const int32_t traffic_stats_uid_;
298     // Idempotency of the request.
299     const net::Idempotency idempotency_;
300 
301     net::handles::NetworkHandle network_;
302 
303     scoped_refptr<net::IOBuffer> read_buffer_;
304     std::unique_ptr<net::URLRequest> url_request_;
305 
306     THREAD_CHECKER(network_thread_checker_);
307   };
308 
309   raw_ptr<CronetContext> context_;
310   // |network_tasks_| is invoked on network thread.
311   NetworkTasks network_tasks_;
312 
313   // Request parameters set off network thread before Start().
314   std::string initial_method_;
315   std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_;
316   std::unique_ptr<net::UploadDataStream> upload_;
317 };
318 
319 }  // namespace cronet
320 
321 #endif  // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
322