Skip to content

Address deprecated curl APIs #4245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Issues of note:
not need that functionality, use NO_CURL to build without
it.

Git requires version "7.19.4" or later of "libcurl" to build
Git requires version "7.19.5" or later of "libcurl" to build
without NO_CURL. This version requirement may be bumped in
the future.

Expand Down
8 changes: 8 additions & 0 deletions git-curl-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@
#endif

/**
* CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR were added in 7.85.0,
* released in August 2022.
*/
#if LIBCURL_VERSION_NUM >= 0x075500
#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1
#endif

/*
* CURLSSLOPT_AUTO_CLIENT_CERT was added in 7.77.0, released in May
* 2021.
*/
Expand Down
6 changes: 3 additions & 3 deletions http-push.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,13 @@ static void curl_setup_http(CURL *curl, const char *url,
const char *custom_req, struct buffer *buffer,
curl_write_callback write_fn)
{
curl_easy_setopt(curl, CURLOPT_PUT, 1);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_INFILE, buffer);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);
curl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);
Expand Down
79 changes: 55 additions & 24 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,19 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
return size / eltsize;
}

curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)
int seek_buffer(void *clientp, curl_off_t offset, int origin)
{
struct buffer *buffer = clientp;

switch (cmd) {
case CURLIOCMD_NOP:
return CURLIOE_OK;

case CURLIOCMD_RESTARTREAD:
buffer->posn = 0;
return CURLIOE_OK;

default:
return CURLIOE_UNKNOWNCMD;
if (origin != SEEK_SET)
BUG("seek_buffer only handles SEEK_SET");
if (offset < 0 || offset >= buffer->buf.len) {
error("curl seek would be outside of buffer");
return CURL_SEEKFUNC_FAIL;
}

buffer->posn = offset;
return CURL_SEEKFUNC_OK;
}

size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
Expand Down Expand Up @@ -791,20 +789,37 @@ void setup_curl_trace(CURL *handle)
curl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);
}

static long get_curl_allowed_protocols(int from_user)
static void proto_list_append(struct strbuf *list, const char *proto)
{
long allowed_protocols = 0;
if (!list)
return;
if (list->len)
strbuf_addch(list, ',');
strbuf_addstr(list, proto);
}

if (is_transport_allowed("http", from_user))
allowed_protocols |= CURLPROTO_HTTP;
if (is_transport_allowed("https", from_user))
allowed_protocols |= CURLPROTO_HTTPS;
if (is_transport_allowed("ftp", from_user))
allowed_protocols |= CURLPROTO_FTP;
if (is_transport_allowed("ftps", from_user))
allowed_protocols |= CURLPROTO_FTPS;
static long get_curl_allowed_protocols(int from_user, struct strbuf *list)
{
long bits = 0;

return allowed_protocols;
if (is_transport_allowed("http", from_user)) {
bits |= CURLPROTO_HTTP;
proto_list_append(list, "http");
}
if (is_transport_allowed("https", from_user)) {
bits |= CURLPROTO_HTTPS;
proto_list_append(list, "https");
}
if (is_transport_allowed("ftp", from_user)) {
bits |= CURLPROTO_FTP;
proto_list_append(list, "ftp");
}
if (is_transport_allowed("ftps", from_user)) {
bits |= CURLPROTO_FTPS;
proto_list_append(list, "ftps");
}

return bits;
}

#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
Expand Down Expand Up @@ -959,10 +974,26 @@ static CURL *get_curl_handle(void)

curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);

#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR
{
struct strbuf buf = STRBUF_INIT;

get_curl_allowed_protocols(0, &buf);
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);
strbuf_reset(&buf);

get_curl_allowed_protocols(-1, &buf);
curl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);
strbuf_release(&buf);
}
#else
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,
get_curl_allowed_protocols(0));
get_curl_allowed_protocols(0, NULL));
curl_easy_setopt(result, CURLOPT_PROTOCOLS,
get_curl_allowed_protocols(-1));
get_curl_allowed_protocols(-1, NULL));
#endif

if (getenv("GIT_CURL_VERBOSE"))
http_trace_curl_no_data();
setup_curl_trace(result);
Expand Down
2 changes: 1 addition & 1 deletion http.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct buffer {
size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);
int seek_buffer(void *clientp, curl_off_t offset, int origin);

/* Slot lifecycle functions */
struct active_request_slot *get_active_slot(void);
Expand Down
28 changes: 13 additions & 15 deletions remote-curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,25 +717,23 @@ static size_t rpc_out(void *ptr, size_t eltsize,
return avail;
}

static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
static int rpc_seek(void *clientp, curl_off_t offset, int origin)
{
struct rpc_state *rpc = clientp;

switch (cmd) {
case CURLIOCMD_NOP:
return CURLIOE_OK;
if (origin != SEEK_SET)
BUG("rpc_seek only handles SEEK_SET, not %d", origin);

case CURLIOCMD_RESTARTREAD:
if (rpc->initial_buffer) {
rpc->pos = 0;
return CURLIOE_OK;
if (rpc->initial_buffer) {
if (offset < 0 || offset > rpc->len) {
error("curl seek would be outside of rpc buffer");
return CURL_SEEKFUNC_FAIL;
}
error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
return CURLIOE_FAILRESTART;

default:
return CURLIOE_UNKNOWNCMD;
rpc->pos = offset;
return CURL_SEEKFUNC_OK;
}
error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
return CURL_SEEKFUNC_FAIL;
}

struct check_pktline_state {
Expand Down Expand Up @@ -959,8 +957,8 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece
rpc->initial_buffer = 1;
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
curl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);
curl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);
if (options.verbosity > 1) {
fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);
fflush(stderr);
Expand Down