blob: 20483ac772c2c928cf4ae39119fa63d7cad183d8 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
#define COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
namespace net {
class HttpRequestHeaders;
enum LoadState;
class SSLCertRequestInfo;
class SSLInfo;
class UploadDataStream;
} // namespace net
namespace cronet {
class CronetURLRequestContext;
class TestUtil;
// Wrapper around net::URLRequestContext.
// Created and configured from client thread. Start, ReadData, and Destroy are
// posted to network thread and all callbacks into the Callback() are
// done on the network thread. CronetUrlRequest client is expected to initiate
// the next step like FollowDeferredRedirect, ReadData or Destroy. Public
// methods can be called on any thread.
class CronetURLRequest {
public:
// Callback implemented by CronetURLRequest() caller and owned by
// CronetURLRequest::NetworkTasks. All callback methods are invoked on network
// thread.
class Callback {
public:
virtual ~Callback() = default;
// Invoked whenever a redirect is encountered. This will only be invoked
// between the call to CronetURLRequest::Start() and
// Callback::OnResponseStarted(). The body of the redirect response, if
// it has one, will be ignored.
//
// The redirect will not be followed until
// CronetURLRequest::FollowDeferredRedirect() method is called, either
// synchronously or asynchronously.
virtual void OnReceivedRedirect(const std::string& new_location,
int http_status_code,
const std::string& http_status_text,
const net::HttpResponseHeaders* headers,
bool was_cached,
const std::string& negotiated_protocol,
const std::string& proxy_server,
int64_t received_byte_count) = 0;
// Invoked when the final set of headers, after all redirects, is received.
// Will only be invoked once for each request.
//
// With the exception of Callback::OnCanceled(),
// no other Callback method will be invoked for the request,
// including Callback::OnSucceeded() and Callback::OnFailed(), until
// CronetUrlRequest::Read() is called to attempt to start reading the
// response body.
virtual void OnResponseStarted(int http_status_code,
const std::string& http_status_text,
const net::HttpResponseHeaders* headers,
bool was_cached,
const std::string& negotiated_protocol,
const std::string& proxy_server) = 0;
// Invoked whenever part of the response body has been read. Only part of
// the buffer may be populated, even if the entire response body has not yet
// been consumed.
//
// With the exception of Callback::OnCanceled(),
// no other Callback method will be invoked for the request,
// including Callback::OnSucceeded() and Callback::OnFailed(), until
// CronetUrlRequest::Read() is called to attempt to continue reading the
// response body.
virtual void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
int bytes_read,
int64_t received_byte_count) = 0;
// Invoked when request is completed successfully.
virtual void OnSucceeded(int64_t received_byte_count) = 0;
// Invoked if request failed for any reason after CronetURLRequest::Start().
// |net_error| provides information about the failure. |quic_error| is only
// valid if |net_error| is net::QUIC_PROTOCOL_ERROR.
virtual void OnError(int net_error,
int quic_error,
const std::string& error_string,
int64_t received_byte_count) = 0;
// Invoked if request was canceled via CronetURLRequest::Start().
virtual void OnCanceled() = 0;
// Invoked when request is destroyed. Once invoked, no other Callback
// methods will be invoked.
virtual void OnDestroyed() = 0;
// Invoked right before request is destroyed to report collected metrics if
// |enable_metrics| is true in CronetURLRequest::CronetURLRequest().
virtual void OnMetricsCollected(const base::Time& request_start_time,
const base::TimeTicks& request_start,
const base::TimeTicks& dns_start,
const base::TimeTicks& dns_end,
const base::TimeTicks& connect_start,
const base::TimeTicks& connect_end,
const base::TimeTicks& ssl_start,
const base::TimeTicks& ssl_end,
const base::TimeTicks& send_start,
const base::TimeTicks& send_end,
const base::TimeTicks& push_start,
const base::TimeTicks& push_end,
const base::TimeTicks& receive_headers_end,
const base::TimeTicks& request_end,
bool socket_reused,
int64_t sent_bytes_count,
int64_t received_bytes_count) = 0;
};
// Invoked in response to CronetURLRequest::GetStatus() to allow multiple
// overlapping calls. The load states correspond to the lengthy periods of
// time that a request load may be blocked and unable to make progress.
using OnStatusCallback = base::OnceCallback<void(net::LoadState)>;
// Bypasses cache if |disable_cache| is true. If context is not set up to
// use cache, |disable_cache| has no effect. |disable_connection_migration|
// causes connection migration to be disabled for this request if true. If
// global connection migration flag is not enabled,
// |disable_connection_migration| has no effect.
CronetURLRequest(CronetURLRequestContext* context,
std::unique_ptr<Callback> callback,
const GURL& url,
net::RequestPriority priority,
bool disable_cache,
bool disable_connection_migration,
bool enable_metrics);
// Methods called prior to Start are never called on network thread.
// Sets the request method GET, POST etc.
bool SetHttpMethod(const std::string& method);
// Adds a header to the request before it starts.
bool AddRequestHeader(const std::string& name, const std::string& value);
// Adds a request body to the request before it starts.
void SetUpload(std::unique_ptr<net::UploadDataStream> upload);
// Starts the request.
void Start();
// GetStatus invokes |on_status_callback| on network thread to allow multiple
// overlapping calls.
void GetStatus(OnStatusCallback on_status_callback) const;
// Follows redirect.
void FollowDeferredRedirect();
// Reads more data.
bool ReadData(net::IOBuffer* buffer, int max_bytes);
// Releases all resources for the request and deletes the object itself.
// |send_on_canceled| indicates whether OnCanceled callback should be
// issued to indicate when no more callbacks will be issued.
void Destroy(bool send_on_canceled);
private:
friend class TestUtil;
// Private destructor invoked fron NetworkTasks::Destroy() on network thread.
~CronetURLRequest();
// NetworkTasks performs tasks on the network thread and owns objects that
// live on the network thread.
class NetworkTasks : public net::URLRequest::Delegate {
public:
// Invoked off the network thread.
NetworkTasks(std::unique_ptr<Callback> callback,
const GURL& url,
net::RequestPriority priority,
int load_flags,
bool enable_metrics);
// Invoked on the network thread.
~NetworkTasks() override;
// Starts the request.
void Start(CronetURLRequestContext* context,
const std::string& method,
std::unique_ptr<net::HttpRequestHeaders> request_headers,
std::unique_ptr<net::UploadDataStream> upload);
// Gets status of the requrest and invokes |on_status_callback| to allow
// multiple overlapping calls.
void GetStatus(OnStatusCallback on_status_callback) const;
// Follows redirect.
void FollowDeferredRedirect();
// Reads more data.
void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size);
// Releases all resources for the request and deletes the |request|, which
// owns |this|, so |this| is also deleted.
// |send_on_canceled| indicates whether OnCanceled callback should be
// issued to indicate when no more callbacks will be issued.
void Destroy(CronetURLRequest* request, bool send_on_canceled);
private:
friend class TestUtil;
// net::URLRequest::Delegate implementations:
void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) override;
void OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) override;
void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
// Report error and cancel request_adapter.
void ReportError(net::URLRequest* request, int net_error);
// Reports metrics collected.
void MaybeReportMetrics();
// Callback implemented by the client.
std::unique_ptr<CronetURLRequest::Callback> callback_;
const GURL initial_url_;
const net::RequestPriority initial_priority_;
const int initial_load_flags_;
// Whether detailed metrics should be collected and reported.
const bool enable_metrics_;
// Whether metrics have been reported.
bool metrics_reported_;
scoped_refptr<net::IOBuffer> read_buffer_;
std::unique_ptr<net::URLRequest> url_request_;
THREAD_CHECKER(network_thread_checker_);
DISALLOW_COPY_AND_ASSIGN(NetworkTasks);
};
CronetURLRequestContext* context_;
// |network_tasks_| is invoked on network thread.
NetworkTasks network_tasks_;
// Request parameters set off network thread before Start().
std::string initial_method_;
std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_;
std::unique_ptr<net::UploadDataStream> upload_;
DISALLOW_COPY_AND_ASSIGN(CronetURLRequest);
};
} // namespace cronet
#endif // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_