// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The IDL in this file is based on Mojo IDL, but is not currently targeted
// for direct use in Mojo projects.
module Cronet;
// General system support interfaces.
/**
* Data buffer provided by the application to read and write data.
*/
interface Buffer {
/**
* Initialize Buffer with raw buffer |data| of |size| allocated by the app.
* The |callback| is invoked when buffer is destroyed.
*/
InitWithDataAndCallback(handle data, uint64 size, BufferCallback callback);
/**
* Initialize Buffer by allocating buffer of |size|. The content of allocated
* data is not initialized.
*/
InitWithAlloc(uint64 size);
/**
* Return size of data owned by this buffer.
*/
[Sync]
GetSize() => (uint64 size);
/**
* Return raw pointer to |data| owned by this buffer.
*/
[Sync]
GetData() => (handle data);
};
/**
* App-provided callback passed to Buffer::InitWithDataAndCallback that gets invoked
* when Buffer is destroyed.
*/
[Abstract]
interface BufferCallback {
/**
* Method invoked when |buffer| is destroyed so its app-allocated |data| can
* be freed. If a UrlRequest has ownership of a Buffer and the UrlRequest is destroyed
* (e.g. Cronet_UrlRequest_Destroy() is called), then Cronet will call OnDestroy().
*/
OnDestroy(Buffer buffer);
};
// Base error passed to UrlRequestCallback.onFailed().
struct Error {
enum ERROR_CODE {
/**
* Error code indicating the error returned by app callback.
*/
ERROR_CALLBACK = 0,
/**
* Error code indicating the host being sent the request could not be resolved to an IP address.
*/
ERROR_HOSTNAME_NOT_RESOLVED = 1,
/**
* Error code indicating the device was not connected to any network.
*/
ERROR_INTERNET_DISCONNECTED = 2,
/**
* Error code indicating that as the request was processed the network configuration changed.
*/
ERROR_NETWORK_CHANGED = 3,
/**
* Error code indicating a timeout expired. Timeouts expiring while attempting to connect will
* be reported as the more specific {@link #ERROR_CONNECTION_TIMED_OUT}.
*/
ERROR_TIMED_OUT = 4,
/**
* Error code indicating the connection was closed unexpectedly.
*/
ERROR_CONNECTION_CLOSED = 5,
/**
* Error code indicating the connection attempt timed out.
*/
ERROR_CONNECTION_TIMED_OUT = 6,
/**
* Error code indicating the connection attempt was refused.
*/
ERROR_CONNECTION_REFUSED = 7,
/**
* Error code indicating the connection was unexpectedly reset.
*/
ERROR_CONNECTION_RESET = 8,
/**
* Error code indicating the IP address being contacted is unreachable, meaning there is no
* route to the specified host or network.
*/
ERROR_ADDRESS_UNREACHABLE = 9,
/**
* Error code indicating an error related to the <a href="https://www.chromium.org/quic">
* QUIC</a> protocol. When {@link #error_code} is this code, see
* {@link quic_detailed_error_code} for more information.
*/
ERROR_QUIC_PROTOCOL_FAILED = 10,
/**
* Error code indicating another type of error was encountered.
* |internal_error_code| can be consulted to get a more specific cause.
*/
ERROR_OTHER = 11
};
/**
* Error code, one of ERROR_* values.
*/
ERROR_CODE error_code = ERROR_CALLBACK;
/**
* Message, explaining the error.
*/
string message;
/**
* Cronet internal error code. This may provide more specific error
* diagnosis than |error_code|, but the constant values may change over time.
* See
* <a href=https://chromium.googlesource.com/chromium/src/+/main/net/base/net_error_list.h>
* here</a> for the lastest list of values.
*/
int32 internal_error_code = 0;
/**
* |true| if retrying this request right away might succeed, |false|
* otherwise. For example, is |true| when |error_code| is |ERROR_NETWORK_CHANGED|
* because trying the request might succeed using the new
* network configuration, but |false| when |error_code| is
* ERROR_INTERNET_DISCONNECTED because retrying the request right away will
* encounter the same failure (instead retrying should be delayed until device regains
* network connectivity).
*/
bool immediately_retryable = false;
/**
* Contains detailed <a href="https://www.chromium.org/quic">QUIC</a> error code from
* <a href="https://cs.chromium.org/search/?q=symbol:%5CbQuicErrorCode%5Cb">
* QuicErrorCode</a> when the |error_code| code is |ERROR_QUIC_PROTOCOL_FAILED|.
*/
int32 quic_detailed_error_code = 0;
};
/**
* An interface to run commands on the |Executor|.
*
* Note: In general creating Runnables should only be done by Cronet. Runnables
* created by the app don't have the ability to perform operations when the
* Runnable is being destroyed (i.e. by Cronet_Runnable_Destroy) so resource
* leaks are possible if the Runnable is posted to an Executor that is being
* shutdown with unexecuted Runnables. In controlled testing environments
* deallocation of associated resources can be performed in Run() if the
* runnable can be assumed to always be executed.
*/
[Abstract]
interface Runnable {
Run();
};
/**
* An interface provided by the app to run |command| asynchronously.
*/
[Abstract]
interface Executor {
/**
* Takes ownership of |command| and runs it synchronously or asynchronously.
* Destroys the |command| after execution, or if executor is shutting down.
*/
Execute(Runnable command);
};
/**
* Runtime result code returned by Engine and UrlRequest. Equivalent to
* runtime exceptions in Android Java API. All results except SUCCESS trigger
* native crash (via SIGABRT triggered by CHECK failure) unless
* EngineParams.enableCheckResult is set to false.
*/
enum RESULT {
/**
* Operation completed successfully
*/
SUCCESS = 0,
/**
* Illegal argument
*/
ILLEGAL_ARGUMENT = -100,
/**
* Storage path must be set to existing directory
*/
ILLEGAL_ARGUMENT_STORAGE_PATH_MUST_EXIST = -101,
/**
* Public key pin is invalid
*/
ILLEGAL_ARGUMENT_INVALID_PIN = -102,
/**
* Host name is invalid
*/
ILLEGAL_ARGUMENT_INVALID_HOSTNAME = -103,
/**
* Invalid http method
*/
ILLEGAL_ARGUMENT_INVALID_HTTP_METHOD = -104,
/**
* Invalid http header
*/
ILLEGAL_ARGUMENT_INVALID_HTTP_HEADER = -105,
/**
* Illegal state
*/
ILLEGAL_STATE = -200,
/**
* Storage path is used by another engine
*/
ILLEGAL_STATE_STORAGE_PATH_IN_USE = -201,
/**
* Cannot shutdown engine from network thread
*/
ILLEGAL_STATE_CANNOT_SHUTDOWN_ENGINE_FROM_NETWORK_THREAD = -202,
/**
* The engine has already started
*/
ILLEGAL_STATE_ENGINE_ALREADY_STARTED = -203,
/**
* The request has already started
*/
ILLEGAL_STATE_REQUEST_ALREADY_STARTED = -204,
/**
* The request is not initialized
*/
ILLEGAL_STATE_REQUEST_NOT_INITIALIZED = -205,
/**
* The request is already initialized
*/
ILLEGAL_STATE_REQUEST_ALREADY_INITIALIZED = -206,
/**
* The request is not started
*/
ILLEGAL_STATE_REQUEST_NOT_STARTED = -207,
/**
* No redirect to follow
*/
ILLEGAL_STATE_UNEXPECTED_REDIRECT = -208,
/**
* Unexpected read attempt
*/
ILLEGAL_STATE_UNEXPECTED_READ = -209,
/**
* Unexpected read failure
*/
ILLEGAL_STATE_READ_FAILED = -210,
/**
* Null pointer or empty data
*/
NULL_POINTER = -300,
/**
* The hostname cannot be null
*/
NULL_POINTER_HOSTNAME = -301,
/**
* The set of SHA256 pins cannot be null
*/
NULL_POINTER_SHA256_PINS = -302,
/**
* The pin expiration date cannot be null
*/
NULL_POINTER_EXPIRATION_DATE = -303,
/**
* Engine is required
*/
NULL_POINTER_ENGINE = -304,
/**
* URL is required
*/
NULL_POINTER_URL = -305,
/**
* Callback is required
*/
NULL_POINTER_CALLBACK = -306,
/**
* Executor is required
*/
NULL_POINTER_EXECUTOR = -307,
/**
* Method is required
*/
NULL_POINTER_METHOD = -308,
/**
* Invalid header name
*/
NULL_POINTER_HEADER_NAME = -309,
/**
* Invalid header value
*/
NULL_POINTER_HEADER_VALUE = -310,
/**
* Params is required
*/
NULL_POINTER_PARAMS = -311,
/**
* Executor for RequestFinishedInfoListener is required
*/
NULL_POINTER_REQUEST_FINISHED_INFO_LISTENER_EXECUTOR = -312,
};
/**
* An engine to process UrlRequests, which uses the best HTTP stack
* available on the current platform. An instance of this class can be started
* using StartWithParams.
*/
interface Engine {
/**
* Starts Engine using given |params|. The engine must be started once
* and only once before other methods can be used.
*/
[Sync]
StartWithParams(EngineParams params) => (RESULT result);
/**
* Starts NetLog logging to a file. The NetLog will contain events emitted
* by all live Engines. The NetLog is useful for debugging.
* The file can be viewed using a Chrome browser navigated to
* chrome://net-internals/#import
* Returns |true| if netlog has started successfully, |false| otherwise.
* @param file_name the complete file path. It must not be empty. If the file
* exists, it is truncated before starting. If actively logging,
* this method is ignored.
* @param log_all {@code true} to include basic events, user cookies,
* credentials and all transferred bytes in the log. This option presents
* a privacy risk, since it exposes the user's credentials, and should
* only be used with the user's consent and in situations where the log
* won't be public. {@code false} to just include basic events.
*/
[Sync]
StartNetLogToFile(string file_name, bool log_all) => (bool started);
/**
* Stops NetLog logging and flushes file to disk. If a logging session is
* not in progress, this call is ignored. This method blocks until the log is
* closed to ensure that log file is complete and available.
*/
[Sync]
StopNetLog() => ();
/**
* Shuts down the Engine if there are no active requests,
* otherwise returns a failure RESULT.
*
* Cannot be called on network thread - the thread Cronet calls into
* Executor on (which is different from the thread the Executor invokes
* callbacks on). This method blocks until all the Engine's resources have
* been cleaned up.
*/
[Sync]
Shutdown() => (RESULT result);
/**
* Returns a human-readable version string of the engine.
*/
[Sync]
GetVersionString() => (string version_string);
/**
* Returns default human-readable version string of the engine. Can be used
* before StartWithParams() is called.
*/
[Sync]
GetDefaultUserAgent() => (string default_user_agent);
/**
* Registers a listener that gets called at the end of each request.
*
* The listener is called on {@code executor}.
*
* The listener is called before {@link UrlRequestCallback.OnCanceled()},
* {@link UrlRequestCallback.OnFailed()} or {@link
* UrlRequestCallback.OnSucceeded()} is called -- note that if {@code
* executor} runs the listener asyncronously, the actual call to the listener
* may happen after a {@code UrlRequestCallback} method is called.
*
* Listeners are only guaranteed to be called for requests that are started
* after the listener is added.
*
* Ownership is **not** taken for {@code listener} or {@code executor}.
*
* Assuming the listener won't run again (there are no pending requests with
* the listener attached, either via {@code Engine} or {@code UrlRequest}),
* the app may destroy it once its {@code OnRequestFinished()} has started,
* even inside that method.
*
* Similarly, the app may destroy {@code executor} in or after {@code
* OnRequestFinished()}.
*
* It's also OK to destroy {@code executor} in or after one of {@link
* UrlRequestCallback.OnCanceled()}, {@link UrlRequestCallback.OnFailed()} or
* {@link UrlRequestCallback.OnSucceeded()}.
*
* Of course, both of these are only true if {@code listener} won't run again
* and {@code executor} isn't being used for anything else that might start
* running in the future.
*
* @param listener the listener for finished requests.
* @param executor the executor upon which to run {@code listener}.
*/
AddRequestFinishedListener(RequestFinishedInfoListener listener,
Executor executor);
/**
* Unregisters a RequestFinishedInfoListener, including its association with
* its registered Executor.
*/
RemoveRequestFinishedListener(RequestFinishedInfoListener listener);
};
/**
* Hint that |host| supports QUIC.
*/
struct QuicHint {
/**
* Name of the host that supports QUIC.
*/
string host;
/**
* Port of the server that supports QUIC.
*/
int32 port = 0;
/**
* Alternate port to use for QUIC.
*/
int32 alternate_port = 0;
};
/**
* Pins a set of public keys for a given |host|. By pinning a set of public keys,
* |pinsSha256|, communication with |host| is required to
* authenticate with a certificate with a public key from the set of pinned ones.
* An app can pin the public key of the root certificate, any of the intermediate
* certificates or the end-entry certificate. Authentication will fail and secure
* communication will not be established if none of the public keys is present in the
* host's certificate chain, even if the host attempts to authenticate with a
* certificate allowed by the device's trusted store of certificates.
*
* More information about the public key pinning can be found in
* <a href="https://tools.ietf.org/html/rfc7469">RFC 7469</a>.
*/
struct PublicKeyPins {
/**
* Name of the host to which the public keys should be pinned. A host that
* consists only of digits and the dot character is treated as invalid.
*/
string host;
/**
* An array of pins. Each pin is the SHA-256 cryptographic
* hash (in the form of "sha256/<base64-hash-value>") of the DER-encoded ASN.1
* representation of the Subject Public Key Info (SPKI) of the host's X.509 certificate.
* Although, the method does not mandate the presence of the backup pin
* that can be used if the control of the primary private key has been
* lost, it is highly recommended to supply one.
*/
array<string> pins_sha256;
/**
* Indicates whether the pinning policy should be applied to subdomains of |host|.
*/
bool include_subdomains = false;
/**
* The expiration date for the pins in milliseconds since epoch (as in java.util.Date).
*/
int64 expiration_date = 0;
};
/**
* Parameters for Engine, which allows its configuration before start.
* Configuration options are set on the EngineParms and
* then Engine.StartWithParams is called to start the Engine.
*/
struct EngineParams {
/**
* Override strict result checking for all operations that return RESULT.
* If set to true, then failed result will cause native crash via SIGABORT.
*/
bool enable_check_result = true;
/**
* Override of the User-Agent header for all requests. An explicitly
* set User-Agent header will override a value set using this param.
*/
string user_agent;
/**
* Sets a default value for the Accept-Language header value for UrlRequests
* created by this engine. Explicitly setting the Accept-Language header
* value for individual UrlRequests will override this value.
*/
string accept_language;
/**
* Directory for HTTP Cache and Prefs Storage. The directory must exist.
*/
string storage_path;
/**
* Whether <a href="https://www.chromium.org/quic">QUIC</a> protocol
* is enabled. If QUIC is enabled, then QUIC User Agent Id
* containing application name and Cronet version is sent to the server.
*/
bool enable_quic = true;
/**
* Whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a>
* protocol is enabled.
*/
bool enable_http2 = true;
/**
* Whether <a href="https://tools.ietf.org/html/rfc7932">Brotli</a> compression is
* enabled. If enabled, Brotli will be advertised in Accept-Encoding request headers.
*/
bool enable_brotli = true;
/**
* Enables or disables caching of HTTP data and other information like QUIC
* server information.
*/
enum HTTP_CACHE_MODE {
/**
* Disable HTTP cache. Some data may still be temporarily stored in memory.
*/
DISABLED = 0,
/**
* Enable in-memory HTTP cache, including HTTP data.
*/
IN_MEMORY = 1,
/**
* Enable on-disk cache, excluding HTTP data.
* |storagePath| must be set to existing directory.
*/
DISK_NO_HTTP = 2,
/**
* Enable on-disk cache, including HTTP data.
* |storagePath| must be set to existing directory.
*/
DISK = 3
};
HTTP_CACHE_MODE http_cache_mode = DISABLED;
/**
* Maximum size in bytes used to cache data (advisory and maybe exceeded at
* times).
*/
int64 http_cache_max_size = 0;
/**
* Hints that hosts support QUIC.
*/
array<QuicHint> quic_hints;
/**
* Pins a set of public keys for given hosts. See |PublicKeyPins| for explanation.
*/
array<PublicKeyPins> public_key_pins;
/**
* Enables or disables public key pinning bypass for local trust anchors. Disabling the
* bypass for local trust anchors is highly discouraged since it may prohibit the app
* from communicating with the pinned hosts. E.g., a user may want to send all traffic
* through an SSL enabled proxy by changing the device proxy settings and adding the
* proxy certificate to the list of local trust anchor. Disabling the bypass will most
* likly prevent the app from sending any traffic to the pinned hosts. For more
* information see 'How does key pinning interact with local proxies and filters?' at
* https://www.chromium.org/Home/chromium-security/security-faq
*/
bool enable_public_key_pinning_bypass_for_local_trust_anchors = true;
/**
* Optional network thread priority. NAN indicates unset, use default.
* On Android, corresponds to android.os.Process.setThreadPriority() values.
* Do not specify for other platforms.
*/
double network_thread_priority = double.NAN;
/**
* JSON formatted experimental options to be used in Cronet Engine.
*/
string experimental_options;
};
/**
* Single HTTP request or response header.
*/
struct HttpHeader {
/**
* Header name.
*/
string name;
/**
* Header value.
*/
string value;
};
struct UrlResponseInfo {
/**
* The URL the response is for. This is the URL after following
* redirects, so it may not be the originally requested URL.
*/
string url;
/**
* The URL chain. The first entry is the originally requested URL;
* the following entries are redirects followed.
*/
array<string> url_chain;
/**
* The HTTP status code. When a resource is retrieved from the cache,
* whether it was revalidated or not, the original status code is returned.
*/
int32 http_status_code = 0;
/**
* The HTTP status text of the status line. For example, if the
* request received a "HTTP/1.1 200 OK" response, this method returns "OK".
*/
string http_status_text;
/**
* Returns an unmodifiable list of response header field and value pairs.
* The headers are in the same order they are received over the wire.
*/
array<HttpHeader> all_headers_list;
/**
* True if the response came from the cache, including
* requests that were revalidated over the network before being retrieved
* from the cache, failed otherwise.
*/
bool was_cached = false;
/**
* The protocol (for example 'quic/1+spdy/3') negotiated with the server.
* An empty string if no protocol was negotiated, the protocol is
* not known, or when using plain HTTP or HTTPS.
*/
string negotiated_protocol;
/**
* The proxy server that was used for the request.
*/
string proxy_server;
/**
* A minimum count of bytes received from the network to process this
* request. This count may ignore certain overheads (for example IP and
* TCP/UDP framing, SSL handshake and framing, proxy handling). This count is
* taken prior to decompression (for example GZIP and Brotli) and includes
* headers and data from all redirects.
*/
int64 received_byte_count = 0;
};
/**
* Listener class used with UrlRequest.GetStatus() to receive the status of a
* UrlRequest.
*/
[Abstract]
interface UrlRequestStatusListener {
enum Status {
/**
* This state indicates that the request is completed, canceled, or is not
* started.
*/
INVALID = -1,
/**
* This state corresponds to a resource load that has either not yet begun
* or is idle waiting for the consumer to do something to move things along
* (e.g. when the consumer of a UrlRequest has not called
* UrlRequest.read() yet).
*/
IDLE = 0,
/**
* When a socket pool group is below the maximum number of sockets allowed
* per group, but a new socket cannot be created due to the per-pool socket
* limit, this state is returned by all requests for the group waiting on an
* idle connection, except those that may be serviced by a pending new
* connection.
*/
WAITING_FOR_STALLED_SOCKET_POOL = 1,
/**
* When a socket pool group has reached the maximum number of sockets
* allowed per group, this state is returned for all requests that don't
* have a socket, except those that correspond to a pending new connection.
*/
WAITING_FOR_AVAILABLE_SOCKET = 2,
/**
* This state indicates that the URLRequest delegate has chosen to block
* this request before it was sent over the network.
*/
WAITING_FOR_DELEGATE = 3,
/**
* This state corresponds to a resource load that is blocked waiting for
* access to a resource in the cache. If multiple requests are made for the
* same resource, the first request will be responsible for writing (or
* updating) the cache entry and the second request will be deferred until
* the first completes. This may be done to optimize for cache reuse.
*/
WAITING_FOR_CACHE = 4,
/**
* This state corresponds to a resource being blocked waiting for the
* PAC script to be downloaded.
*/
DOWNLOADING_PAC_FILE = 5,
/**
* This state corresponds to a resource load that is blocked waiting for a
* proxy autoconfig script to return a proxy server to use.
*/
RESOLVING_PROXY_FOR_URL = 6,
/**
* This state corresponds to a resource load that is blocked waiting for a
* proxy autoconfig script to return a proxy server to use, but that proxy
* script is busy resolving the IP address of a host.
*/
RESOLVING_HOST_IN_PAC_FILE = 7,
/**
* This state indicates that we're in the process of establishing a tunnel
* through the proxy server.
*/
ESTABLISHING_PROXY_TUNNEL = 8,
/**
* This state corresponds to a resource load that is blocked waiting for a
* host name to be resolved. This could either indicate resolution of the
* origin server corresponding to the resource or to the host name of a
* proxy server used to fetch the resource.
*/
RESOLVING_HOST = 9,
/**
* This state corresponds to a resource load that is blocked waiting for a
* TCP connection (or other network connection) to be established. HTTP
* requests that reuse a keep-alive connection skip this state.
*/
CONNECTING = 10,
/**
* This state corresponds to a resource load that is blocked waiting for the
* SSL handshake to complete.
*/
SSL_HANDSHAKE = 11,
/**
* This state corresponds to a resource load that is blocked waiting to
* completely upload a request to a server. In the case of a HTTP POST
* request, this state includes the period of time during which the message
* body is being uploaded.
*/
SENDING_REQUEST = 12,
/**
* This state corresponds to a resource load that is blocked waiting for the
* response to a network request. In the case of a HTTP transaction, this
* corresponds to the period after the request is sent and before all of the
* response headers have been received.
*/
WAITING_FOR_RESPONSE = 13,
/**
* This state corresponds to a resource load that is blocked waiting for a
* read to complete. In the case of a HTTP transaction, this corresponds to
* the period after the response headers have been received and before all
* of the response body has been downloaded. (NOTE: This state only applies
* for an {@link UrlRequest} while there is an outstanding
* {@link UrlRequest#read read()} operation.)
*/
READING_RESPONSE = 14
};
/**
* Invoked on UrlRequest's Executor when request status is obtained.
* |status| is representing the status of the request.
*/
OnStatus(Status status);
};
/**
* Users of Cronet implement this interface to receive callbacks indicating the
* progress of a UrlRequest being processed. An instance of this interface
* is passed in to UrlRequest's method InitWithParams().
* <p>
* Note: All methods will be invoked on the Executor passed to UrlRequest.InitWithParams();
*/
[Abstract]
interface UrlRequestCallback {
/**
* Invoked whenever a redirect is encountered. This will only be invoked
* between the call to UrlRequest.start() and
* UrlRequestCallback.onResponseStarted().
* The body of the redirect response, if it has one, will be ignored.
*
* The redirect will not be followed until the URLRequest.followRedirect()
* ethod is called, either synchronously or asynchronously.
*
* @param request Request being redirected.
* @param info Response information.
* @param new_location_url Location where request is redirected.
*/
OnRedirectReceived(UrlRequest request, UrlResponseInfo info, string new_location_url);
/**
* Invoked when the final set of headers, after all redirects, is received.
* Will only be invoked once for each request.
*
* With the exception of UrlRequestCallback.onCanceled(),
* no other UrlRequestCallback method will be invoked for the request,
* including UrlRequestCallback.onSucceeded() and
* UrlRequestCallback.onFailed(), until UrlRequest.read()} is called to attempt
* to start reading the response body.
*
* @param request Request that started to get response.
* @param info Response information.
*/
OnResponseStarted(UrlRequest request, UrlResponseInfo info);
/**
* 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. This callback transfers ownership of |buffer| back to the app,
* and Cronet guarantees not to access it.
*
* With the exception of UrlRequestCallback.onCanceled(),
* no other UrlRequestCallback method will be invoked for the request,
* including UrlRequestCallback.onSucceeded() and
* UrlRequestCallback.onFailed(), until UrlRequest.read()} is called to attempt
* to continue reading the response body.
*
* @param request Request that received data.
* @param info Response information.
* @param buffer The buffer that was passed in to UrlRequest.read(), now
* containing the received data.
* @param bytes_read The number of bytes read into buffer.
*/
OnReadCompleted(UrlRequest request, UrlResponseInfo info, Buffer buffer, uint64 bytes_read);
/**
* Invoked when request is completed successfully. Once invoked, no other
* UrlRequestCallback methods will be invoked.
*
* Implementations of {@link #OnSucceeded} are allowed to call {@code
* Cronet_UrlRequest_Destroy(request)}, but note that destroying {@code
* request} destroys {@code info}.
*
* @param request Request that succeeded.
* @param info Response information. NOTE: this is owned by {@code request}.
*/
OnSucceeded(UrlRequest request, UrlResponseInfo info);
/**
* Invoked if request failed for any reason after UrlRequest.start().
* Once invoked, no other UrlRequestCallback methods will be invoked.
* |error| provides information about the failure.
*
* Implementations of {@link #OnFailed} are allowed to call {@code
* Cronet_UrlRequest_Destroy(request)}, but note that destroying {@code
* request} destroys {@code info} and {@code error}.
*
* @param request Request that failed.
* @param info Response information. May be null if no response was
* received. NOTE: this is owned by {@code request}.
* @param error information about error. NOTE: this is owned by {@code
* request}.
*/
OnFailed(UrlRequest request, UrlResponseInfo info, Error error);
/**
* Invoked if request was canceled via UrlRequest.cancel(). Once
* invoked, no other UrlRequestCallback methods will be invoked.
*
* Implementations of {@link #OnCanceled} are allowed to call {@code
* Cronet_UrlRequest_Destroy(request)}, but note that destroying {@code
* request} destroys {@code info}.
*
* @param request Request that was canceled.
* @param info Response information. May be null if no response was
* received. NOTE: this is owned by {@code request}.
*/
OnCanceled(UrlRequest request, UrlResponseInfo info);
};
/**
* Defines callbacks methods for UploadDataProvider. All methods
* may be called synchronously or asynchronously, on any thread.
*/
interface UploadDataSink {
/**
* Called by UploadDataProvider when a read succeeds.
*
* @param bytes_read number of bytes read into buffer passed to read().
* @param final_chunk For chunked uploads, |true| if this is the final
* read. It must be |false| for non-chunked uploads.
*/
OnReadSucceeded(uint64 bytes_read, bool final_chunk);
/**
* Called by UploadDataProvider when a read fails.
* @param error_message to pass on to UrlRequestCallback.onFailed().
*/
OnReadError(string error_message);
/**
* Called by UploadDataProvider when a rewind succeeds.
*/
OnRewindSucceeded();
/**
* Called by UploadDataProvider when a rewind fails, or if rewinding
* uploads is not supported.
* @param error_message to pass on to UrlRequestCallback.onFailed().
*/
OnRewindError(string error_message);
};
/**
* The interface allowing the embedder to provide an upload body to
* UrlRequest. It supports both non-chunked (size known in advanced) and
* chunked (size not known in advance) uploads. Be aware that not all servers
* support chunked uploads.
*
* An upload is either always chunked, across multiple uploads if the data
* ends up being sent more than once, or never chunked.
*/
[Abstract]
interface UploadDataProvider {
/**
* If this is a non-chunked upload, returns the length of the upload. Must
* always return -1 if this is a chunked upload.
*/
[Sync]
GetLength() => (int64 length);
/**
* Reads upload data into |buffer|. Each call of this method must be followed be a
* single call, either synchronous or asynchronous, to
* UploadDataSink.onReadSucceeded() on success
* or UploadDataSink.onReadError() on failure. Neither read nor rewind
* will be called until one of those methods or the other is called. Even if
* the associated UrlRequest is canceled, one or the other must
* still be called before resources can be safely freed.
*
* @param upload_data_sink The object to notify when the read has completed,
* successfully or otherwise.
* @param buffer The buffer to copy the read bytes into.
*/
Read(UploadDataSink upload_data_sink, Buffer buffer);
/**
* Rewinds upload data. Each call must be followed be a single
* call, either synchronous or asynchronous, to
* UploadDataSink.onRewindSucceeded() on success or
* UploadDataSink.onRewindError() on failure. Neither read nor rewind
* will be called until one of those methods or the other is called.
* Even if the associated UrlRequest is canceled, one or the other
* must still be called before resources can be safely freed.
*
* If rewinding is not supported, this should call
* UploadDataSink.onRewindError(). Note that rewinding is required to
* follow redirects that preserve the upload body, and for retrying when the
* server times out stale sockets.
*
* @param upload_data_sink The object to notify when the rewind operation has
* completed, successfully or otherwise.
*/
Rewind(UploadDataSink upload_data_sink);
/**
* Called when this UploadDataProvider is no longer needed by a request, so that resources
* (like a file) can be explicitly released.
*/
Close();
};
/**
* Controls an HTTP request (GET, PUT, POST etc).
* Initialized by InitWithParams().
* Note: All methods must be called on the Executor passed to InitWithParams().
*/
interface UrlRequest {
/**
* Initialized UrlRequest to |url| with |params|. All methods of |callback| for
* request will be invoked on |executor|. The |executor| must not run tasks on
* the thread calling Executor.execute() to prevent blocking networking
* operations and causing failure RESULTs during shutdown.
*
* @param engine Engine to process the request.
* @param url URL for the request.
* @param params additional parameters for the request, like headers and priority.
* @param callback Callback that gets invoked on different events.
* @param executor Executor on which all callbacks will be invoked.
*/
[Sync]
InitWithParams(Engine engine,
string url,
UrlRequestParams params,
UrlRequestCallback callback,
Executor executor) => (RESULT result);
/**
* Starts the request, all callbacks go to UrlRequestCallback. May only be called
* once. May not be called if Cancel() has been called.
*/
[Sync]
Start() => (RESULT result);
/**
* Follows a pending redirect. Must only be called at most once for each
* invocation of UrlRequestCallback.OnRedirectReceived().
*/
[Sync]
FollowRedirect() => (RESULT result);
/**
* Attempts to read part of the response body into the provided buffer.
* Must only be called at most once in response to each invocation of the
* UrlRequestCallback.OnResponseStarted() and
* UrlRequestCallback.OnReadCompleted()} methods of the UrlRequestCallback.
* Each call will result in an asynchronous call to
* either the UrlRequestCallback.OnReadCompleted() method if data
* is read, its UrlRequestCallback.OnSucceeded() method if
* there's no more data to read, or its UrlRequestCallback.OnFailed()
* method if there's an error.
* This method transfers ownership of |buffer| to Cronet, and app should
* not access it until one of these callbacks is invoked.
*
* @param buffer to write response body to. The app must not read or
* modify buffer's position, limit, or data between its position and
* limit until the request calls back into the UrlRequestCallback.
*/
[Sync]
Read(Buffer buffer) => (RESULT result);
/**
* Cancels the request. Can be called at any time.
* UrlRequestCallback.OnCanceled() will be invoked when cancellation
* is complete and no further callback methods will be invoked. If the
* request has completed or has not started, calling Cancel() has no
* effect and OnCanceled() will not be invoked. If the
* Executor passed in to UrlRequest.InitWithParams() runs
* tasks on a single thread, and Cancel() is called on that thread,
* no callback methods (besides OnCanceled() will be invoked after
* Cancel() is called. Otherwise, at most one callback method may be
* invoked after Cancel() has completed.
*/
Cancel();
/**
* Returns true if the request was successfully started and is now
* finished (completed, canceled, or failed).
*/
[Sync]
IsDone() => (bool done);
/**
* Queries the status of the request.
* @param listener a UrlRequestStatusListener that will be invoked with
* the request's current status. Listener will be invoked
* back on the Executor passed in when the request was
* created.
*/
GetStatus(UrlRequestStatusListener listener);
};
/**
* Parameters for UrlRequest. Allows configuring requests before initializing them
* with UrlRequest.InitWithParams().
*/
struct UrlRequestParams {
enum REQUEST_PRIORITY {
/**
* Lowest request priority.
*/
REQUEST_PRIORITY_IDLE = 0,
/**
* Very low request priority.
*/
REQUEST_PRIORITY_LOWEST = 1,
/**
* Low request priority.
*/
REQUEST_PRIORITY_LOW = 2,
/**
* Medium request priority. This is the default priority given to the request.
*/
REQUEST_PRIORITY_MEDIUM = 3,
/**
* Highest request priority.
*/
REQUEST_PRIORITY_HIGHEST = 4,
};
/**
* The HTTP method verb to use for this request.
*
* The default when this value is not set is "GET" if the request has
* no body or "POST" if it does.
*
* Allowed methods are "GET", "HEAD", "DELETE", "POST" or "PUT".
*/
string http_method;
/**
* Array of HTTP headers for this request..
*/
array<HttpHeader> request_headers;
/**
* Disables cache for the request. If context is not set up to use cache,
* this call has no effect.
*/
bool disable_cache = false;
/**
* Priority of the request which should be one of the REQUEST_PRIORITY values.
*/
REQUEST_PRIORITY priority = REQUEST_PRIORITY_MEDIUM;
/**
* Upload data provider. Setting this value switches method to "POST" if not
* explicitly set. Starting the request will fail if a Content-Type header is not set.
*/
UploadDataProvider? upload_data_provider;
/**
* Upload data provider executor that will be used to invoke uploadDataProvider.
*/
Executor? upload_data_provider_executor;
/**
* Marks that the executors this request will use to notify callbacks (for
* UploadDataProvider and UrlRequestCallback) is intentionally performing
* inline execution without switching to another thread.
*
* <p><b>Warning:</b> This option makes it easy to accidentally block the network thread.
* It should not be used if your callbacks perform disk I/O, acquire locks, or call into
* other code you don't carefully control and audit.
*/
bool allow_direct_executor = false;
/**
* Associates the annotation object with this request. May add more than one.
* Passed through to a RequestFinishedInfoListener.
*/
array<handle> annotations;
/**
* A listener that gets invoked at the end of each request.
*
* The listener is invoked with the request finished info on {@code
* request_finished_executor}, which must be set.
*
* The listener is called before {@link UrlRequestCallback.OnCanceled()},
* {@link UrlRequestCallback.OnFailed()} or {@link
* UrlRequestCallback.OnSucceeded()} is called -- note that if {@code
* request_finished_executor} runs the listener asyncronously, the actual
* call to the listener may happen after a {@code UrlRequestCallback} method
* is called.
* Ownership is **not** taken.
*
* Assuming the listener won't run again (there are no pending requests with
* the listener attached, either via {@code Engine} or {@code UrlRequest}),
* the app may destroy it once its {@code OnRequestFinished()} has started,
* even inside that method.
*/
RequestFinishedInfoListener? request_finished_listener;
/**
* The Executor used to run the {@code request_finished_listener}.
*
* Ownership is **not** taken.
*
* Similar to {@code request_finished_listener}, the app may destroy {@code
* request_finished_executor} in or after {@code OnRequestFinished()}.
*
* It's also OK to destroy {@code request_finished_executor} in or after one
* of {@link UrlRequestCallback.OnCanceled()}, {@link
* UrlRequestCallback.OnFailed()} or {@link
* UrlRequestCallback.OnSucceeded()}.
*
* Of course, both of these are only true if {@code
* request_finished_executor} isn't being used for anything else that might
* start running in the future.
*/
Executor? request_finished_executor;
enum IDEMPOTENCY {
DEFAULT_IDEMPOTENCY = 0,
IDEMPOTENT = 1,
NOT_IDEMPOTENT = 2,
};
/**
* Idempotency of the request, which determines that if it is safe to enable
* 0-RTT for the Cronet request. By default, 0-RTT is only enabled for safe
* HTTP methods, i.e., GET, HEAD, OPTIONS, and TRACE. For other methods,
* enabling 0-RTT may cause security issues since a network observer can
* replay the request. If the request has any side effects, those effects can
* happen multiple times. It is only safe to enable the 0-RTT if it is known
* that the request is idempotent.
*/
IDEMPOTENCY idempotency = DEFAULT_IDEMPOTENCY;
};
/**
* Represents a date and time expressed as the number of milliseconds since the
* UNIX epoch.
*/
struct DateTime {
/**
* Number of milliseconds since the UNIX epoch.
*/
int64 value = 0;
};
/*
* Represents metrics collected for a single request. Most of these metrics are
* timestamps for events during the lifetime of the request, which can be used
* to build a detailed timeline for investigating performance.
*
* Events happen in this order:
* <ol>
* <li>{@link #request_start request start}</li>
* <li>{@link #dns_start DNS start}</li>
* <li>{@link #dns_end DNS end}</li>
* <li>{@link #connect_start connect start}</li>
* <li>{@link #ssl_start SSL start}</li>
* <li>{@link #ssl_end SSL end}</li>
* <li>{@link #connect_end connect end}</li>
* <li>{@link #sending_start sending start}</li>
* <li>{@link #sending_end sending end}</li>
* <li>{@link #response_start response start}</li>
* <li>{@link #request_end request end}</li>
* </ol>
*
* Start times are reported as the time when a request started blocking on the
* event, not when the event actually occurred, with the exception of push
* start and end. If a metric is not meaningful or not available, including
* cases when a request finished before reaching that stage, start and end
* times will be null. If no time was spent blocking on an event, start and end
* will be the same time.
*
* Timestamps are recorded using a clock that is guaranteed not to run
* backwards. All timestamps are correct relative to the system clock at the
* time of request start, and taking the difference between two timestamps will
* give the correct difference between the events. In order to preserve this
* property, timestamps for events other than request start are not guaranteed
* to match the system clock at the times they represent.
*
* Most timing metrics are taken from
* <a
* href="https://cs.chromium.org/chromium/src/net/base/load_timing_info.h">LoadTimingInfo</a>,
* which holds the information for <a href="http://w3c.github.io/navigation-timing/"></a> and
* <a href="https://www.w3.org/TR/resource-timing/"></a>.
*/
struct Metrics {
/**
* Time when the request started, which corresponds to calling
* Cronet_UrlRequest_Start(). This timestamp will match the system clock at
* the time it represents.
*/
DateTime request_start;
/**
* Time when DNS lookup started. This and {@link #dns_end} will be set to
* non-null regardless of whether the result came from a DNS server or the
* local cache. Will equal null if the socket was reused (see {@link
* #socket_reused}).
*/
DateTime? dns_start;
/**
* Time when DNS lookup finished. This and {@link dns_start} will return
* non-null regardless of whether the result came from a DNS server or the
* local cache. Will equal null if the socket was reused (see {@link
* #socket_reused}).
*/
DateTime? dns_end;
/**
* Time when connection establishment started, typically when DNS resolution
* finishes. Will equal null if the socket was reused (see {@link
* #socket_reused}).
*/
DateTime? connect_start;
/**
* Time when connection establishment finished, after TCP connection is
* established and, if using HTTPS, SSL handshake is completed. For QUIC
* 0-RTT, this represents the time of handshake confirmation and might happen
* later than {@link #sending_start}. Will equal null if the socket was
* reused (see {@link #socket_reused}).
*/
DateTime? connect_end;
/**
* Time when SSL handshake started. For QUIC, this will be the same time as
* {@link #connect_start}. Will equal null if SSL is not used or if the
* socket was reused (see {@link #socket_reused}).
*/
DateTime? ssl_start;
/**
* Time when SSL handshake finished. For QUIC, this will be the same time as
* {@link #connect_end}. Will equal null if SSL is not used or if the socket
* was reused (see {@link #socket_reused}).
*/
DateTime? ssl_end;
/**
* Time when sending HTTP request headers started.
*
* Will equal null if the request failed or was canceled before sending
* started.
*/
DateTime? sending_start;
/**
* Time when sending HTTP request body finished. (Sending request body
* happens after sending request headers.)
*
* Will equal null if the request failed or was canceled before sending
* ended.
*/
DateTime? sending_end;
/**
* Time when first byte of HTTP/2 server push was received. Will equal
* null if server push is not used.
*/
DateTime? push_start;
/**
* Time when last byte of HTTP/2 server push was received. Will equal
* null if server push is not used.
*/
DateTime? push_end;
/**
* Time when the end of the response headers was received.
*
* Will equal null if the request failed or was canceled before the response
* started.
*/
DateTime? response_start;
/**
* Time when the request finished.
*/
DateTime request_end;
/**
* True if the socket was reused from a previous request, false otherwise.
* In HTTP/2 or QUIC, if streams are multiplexed in a single connection, this
* will be {@code true} for all streams after the first. When {@code true},
* DNS, connection, and SSL times will be null.
*/
bool socket_reused = false;
/**
* Returns total bytes sent over the network transport layer, or -1 if not
* collected.
*/
int64 sent_byte_count = -1;
/**
* Total bytes received over the network transport layer, or -1 if not
* collected. Number of bytes does not include any previous redirects.
*/
int64 received_byte_count = -1;
};
/**
* Information about a finished request.
*/
struct RequestFinishedInfo {
/**
* The reason why the request finished.
*/
enum FINISHED_REASON {
/**
* The request succeeded.
*/
SUCCEEDED = 0,
/**
* The request failed or returned an error.
*/
FAILED = 1,
/**
* The request was canceled.
*/
CANCELED = 2,
};
/**
* Metrics collected for this request.
*/
Metrics metrics;
/**
* The objects that the caller has supplied when initiating the request,
* using {@link UrlRequestParams.annotations}.
*
* Annotations can be used to associate a {@link RequestFinishedInfo} with
* the original request or type of request.
*/
array<handle> annotations;
/**
* Returns the reason why the request finished.
*/
FINISHED_REASON finished_reason = SUCCEEDED;
};
/**
* Listens for finished requests for the purpose of collecting metrics.
*/
[Abstract]
interface RequestFinishedInfoListener {
/**
* Will be called in a task submitted to the {@code Executor} passed with
* this {@code RequestFinishedInfoListener}.
*
* The listener is called before {@link UrlRequestCallback.OnCanceled()},
* {@link UrlRequestCallback.OnFailed()} or {@link
* UrlRequestCallback.OnSucceeded()} is called -- note that if the executor
* runs the listener asyncronously, the actual call to the listener may
* happen after a {@code UrlRequestCallback} method is called.
*
* @param request_info {@link RequestFinishedInfo} for finished request.
* Ownership is *not* transferred by this call, do not destroy
* {@code request_info}.
*
* {@code request_info} will be valid as long as the {@code UrlRequest}
* that created it hasn't been destroyed -- **additionally**, it will
* also always be valid for the duration of {@code OnRequestFinished()},
* even if the {@code UrlRequest} has been destroyed.
*
* This is accomplished by ownership being shared between the {@code
* UrlRequest} and the code that calls this listener.
*
* @param response_info A pointer to the same UrlResponseInfo passed to
* {@link UrlRequestCallback.OnCanceled()}, {@link
* UrlRequestCallback.OnFailed()} or {@link
* UrlRequestCallback.OnSucceeded()}. The lifetime and ownership of
* {@code response_info} works the same as for {@code request_info}.
*
* @param error A pointer to the same Error passed to
* {@code UrlRequestCallback.OnFailed()}, or null if there was no error.
* The lifetime and ownership of {@code error} works the same as for
* {@code request_info}.
*/
OnRequestFinished(RequestFinishedInfo request_info,
UrlResponseInfo response_info,
Error error);
};