Permalink
Browse files

Add support for CURLOPT_TCP_FASTOPEN

Closes #19.
  • Loading branch information...
bassosimone committed Dec 5, 2018
1 parent dea2a85 commit a5c258b5ecd30692d988cea281487e0daff47600
Showing with 30 additions and 0 deletions.
  1. +3 −0 mkcurl-client.cpp
  2. +27 −0 mkcurl.h
@@ -28,6 +28,7 @@ static void usage() {
std::clog << " --ca-bundle-path <path> : path to OpenSSL CA bundle\n";
std::clog << " --data <data> : send <data> as body\n";
std::clog << " --enable-http2 : enable HTTP2 support\n";
std::clog << " --enable-tcp-fastopen : enable TCP fastopen support\n";
std::clog << " --follow-redirect : enable following redirects\n";
std::clog << " --header <header> : add <header> to headers\n";
std::clog << " --post : use POST rather than GET\n";
@@ -109,6 +110,8 @@ int main(int, char **argv) {
for (auto &flag : cmdline.flags()) {
if (flag == "enable-http2") {
mkcurl_request_enable_http2_v2(req.get());
} else if (flag == "enable-tcp-fastopen") {
mkcurl_request_enable_tcp_fastopen(req.get());
} else if (flag == "follow-redirect") {
mkcurl_request_enable_follow_redirect_v2(req.get());
} else if (flag == "post") {
@@ -85,6 +85,10 @@ void mkcurl_request_set_proxy_url_v2(mkcurl_request_t *req, const char *u);
/// function call abort if passed any null argument by the caller.
void mkcurl_request_enable_follow_redirect_v2(mkcurl_request_t *req);

/// mkcurl_request_enable_tcp_fastopen enables TCP fastopen (if that is
/// possible). This function will call abort if @p req is null.
void mkcurl_request_enable_tcp_fastopen(mkcurl_request_t *req);

/// mkcurl_request_perform_nonnull sends an HTTP request and returns the related
/// response. It will never return a null pointer. It will call abort if
/// passed a null argument by the caller.
@@ -230,6 +234,14 @@ enum class mkcurl_method {
PUT
};

// TODO(bassosimone): this code can actually be refactored such that the
// request owns CURL's handle, and we set directly fields inside of it since
// starting from v7.17.0 CURL copies strings passed to it. (Make sure this
// also applies to post data, BTW). This different code structure will allow
// us to possibly reuse the request containing the handle for continuing to
// use the channel and make more follow up requests. An additional benefit is
// that this file will be smaller and we'll make it less bureaucratic :^).

// mkcurl_request is an HTTP request.
struct mkcurl_request {
// ca_path is the path to the CA bundle to use.
@@ -248,6 +260,8 @@ struct mkcurl_request {
long timeout = 30;
// proxy_url is the optional URL of the proxy to use.
std::string proxy_url;
// enable_fastopen will enable TCP fastopen (if possible).
bool enable_fastopen = false;
// follow_redir indicates whether we should follow redirects.
bool follow_redir = false;
};
@@ -329,6 +343,13 @@ void mkcurl_request_set_proxy_url_v2(mkcurl_request_t *req, const char *u) {
req->proxy_url = u;
}

void mkcurl_request_enable_tcp_fastopen(mkcurl_request_t *req) {
if (req == nullptr) {
MKCURL_ABORT();
}
req->enable_fastopen = true;
}

void mkcurl_request_enable_follow_redirect_v2(mkcurl_request_t *req) {
if (req == nullptr) {
MKCURL_ABORT();
@@ -677,6 +698,12 @@ mkcurl_response_t *mkcurl_request_perform_nonnull(const mkcurl_request_t *req) {
return res.release();
}
}
if (req->enable_fastopen &&
(res->error = MKCURL_EASY_SETOPT(handle.get(), CURLOPT_TCP_FASTOPEN,
1L)) != CURLE_OK) {
mkcurl_log(res->logs, "curl_easy_setopt(CURLOPT_TCP_FASTOPEN) failed");
return res.release();
}
if (!req->ca_path.empty() &&
(res->error = MKCURL_EASY_SETOPT(handle.get(), CURLOPT_CAINFO,
req->ca_path.c_str())) != CURLE_OK) {

0 comments on commit a5c258b

Please sign in to comment.