Networking
Introduction
While not part of Chromium’s //base
itself, realizing that applications
built today almost always require access to network, libbase
provides users
with simple yet quite powerful networking utilities built on top of libcurl
and fully integrated with task runners/sequences. The API is loosely based on
Chromium’s //net
module.
Usage
While Networking module is enabled by default, it is optional so before
starting make sure that libbase
build you’re using was built with it (the
LIBBASE_BUILD_MODULE_NET
build option enabled).
Once built, be sure to link your application with libbase_net
module target.
All code in networking module is located in base/net/
directory and all
classes in that module are in base::net
namespace.
Lastly, before using documented below functionality, be sure to initialize and deinitialize networking module in runtime (on application’s startup and shutdown, respectively) with calls to these functions:
base::net::SimpleUrlLoader
This class provides two functions that you can use to perform a simple network request:
First variant performs a network request for a resource specified by passed
base::net::ResourceRequest
struct as parameter. For HTTP(s) request,
this may be a GET
, POST
or HEAD
request and once finished, it will
execute provided on_done_callback
with response
(base::net::ResourceResponse
). The second variant allows you to specify
maximum size of a response and if there would be more data, it will abort the
request.
Warning
Downloading unknown resource without size limitations may lead to exhausting
all of memory available for your application. It is recommended to either
know the response size before making an Unbounded
request, or using the
Limited
version of the function.
You can also use more advanced utility base::net::UrlRequest
described below where you will have much greater control over the process and
e.g. will be able to stop in the middle of fetching response.
Both of these functions take optional argument of
std::shared_ptr<base::TaskRunner>
type. If provided, your callback will be
executed on that task runner, otherwise provided callback will be executed on
the task runner on which the request (call to Download*()
function) was
made.
They also return an instance of base::net::RequestCancellationToken
class which can be passed to base::net::SimpleUrlLoader::CancelRequest()
function to asynchronously cancel related request.
Warning
Request cancellation is an asynchronous process. Calling
base::net::SimpleUrlLoader::CancelRequest()
function does not
guarantee that provided on_done_callback
will not be executed. If you
need to guarantee that - you need to add your own logic to check for that -
for example by binding the callback to a base::WeakPtr
that you can
invalidate when needed.
Example
void PerformRequest(std::string resource_url) {
base::net::SimpleUrlLoader::DownloadUnbounded(
base::net::ResourceRequest{resource_url},
base::BindOnce(&OnResponse));
}
void OnResponse(base::net::ResourceResponse response) {
// Check response status and other metadata
}
For a full example of base::net::SimpleUrlLoader
usage, refer to
Networking example.
base::net::UrlRequest
This class provides similar functionality to base::net::SimpleUrlLoader
but provides much more control over the process. Instead of calling a function
and passing a callback that will be executed when the request finishes and
provide all metadata and data from the response, this class is used by creating
an instance of it and storing it for the duration of the request during which it
will perform calls to specified client.
To create it, you need to pass a pointer to an instance of
base::net::UrlRequest::Client
interface that will receive calls
marking of a progress on the request such as:
base::net::UrlRequest::Client::OnResponseStarted()
This method will be called with metadata (such as request status code, final URL - if there were any redirects, and received headers) when the connection will be established and those metadata received.
Caution
If the request fails before connection was established, this method will not be called therefore users must not design logic to depend on it being called at least once.
base::net::UrlRequest::Client::OnWriteData()
This method will be called every time new chunk of data will be received by
libbase
network stack. User is expected to process or buffer this data on their own as it will not be buffered and sent all-in-one call later.Caution
Same as with the previous method - if the request fails before any response data (body) will be received, this function may not be called even once. Furthermore, if the request was made with
headers_only
set totrue
, this method will not be called even for a successful requests.Users however can depend on it never being called before/without a call to
base::net::UrlRequest::Client::OnResponseStarted()
method.
base::net::UrlRequest::Client::OnRequestFinished()
This member function will be called when processing of that network request will finish. Users should inspect returned
base::net::Result
parameter to know if the request has finished or not.Note
This callback is guaranteed to be called exactly once when the request will finish, unless the
base::net::UrlRequest
was cancelled (either by calling thebase::net::UrlRequest::Cancel()
method or by destroying the object itself) in which case the callback will not be executed.Caution
Be aware that unless an explicit timeout was specified when making the request, the request can still take arbitrary amount of time until it finishes. If the request has to finish within certain amount of time, please either provide a timeout or monitor and cancel it manually.
Once base::net::UrlRequest
is created and you are ready to perform the
request, you should call base::net::UrlRequest::Start()
and provide
details about the network request to be made.
After the request processing has been started, you may call
base::net::UrlRequest::Cancel()
method at any moment or destroy the
underlying base::net::UrlRequest
object to cancel the request. Once
either of these are done, it is guaranteed that there will be no more calls to
any of the methods on the provided client and the request will be asynchronously
cancelled.
Warning
You can perform only one network request at a time with a single instance of
base::net::UrlRequest
.
Tip
To perform multiple request at the same time you can create a separate
instances of this class for each request you want to start in parallel. You
can then compare provided pointers to base::net::UrlRequest
objects
(which are first arguments in each method in the
base::net::UrlRequest::Client
interface) to know for which request
the calls are made.
For a full example on how to use this class, please refer to the Networking example.