Skip to content
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

Update embedded curl to 5.2.3 #728

Merged
merged 2 commits into from
Dec 18, 2024
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
14 changes: 7 additions & 7 deletions src/library/curl/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Package: curl
Type: Package
Title: A Modern and Flexible Web Client for R
Version: 5.2.0
Version: 5.2.3
Authors@R: c(
person("Jeroen", "Ooms", role = c("aut", "cre"), email = "[email protected]",
person("Jeroen", "Ooms", role = c("aut", "cre"), email = "[email protected]",
comment = c(ORCID = "0000-0002-4035-0289")),
person("Hadley", "Wickham", , "[email protected]", role = "ctb"),
person("RStudio", role = "cph")
Expand All @@ -23,17 +23,17 @@ SystemRequirements: libcurl: libcurl-devel (rpm) or
URL: https://jeroen.r-universe.dev/curl https://curl.se/libcurl/
BugReports: https://github.com/jeroen/curl/issues
Suggests: spelling, testthat (>= 1.0.0), knitr, jsonlite, later,
rmarkdown, magrittr, httpuv (>= 1.4.4), webutils
rmarkdown, httpuv (>= 1.4.4), webutils
VignetteBuilder: knitr
Depends: R (>= 3.0.0)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.0
Encoding: UTF-8
Language: en-US
NeedsCompilation: yes
Packaged: 2023-12-07 23:07:08 UTC; jeroen
Packaged: 2024-09-19 15:43:51 UTC; jeroen
Author: Jeroen Ooms [aut, cre] (<https://orcid.org/0000-0002-4035-0289>),
Hadley Wickham [ctb],
RStudio [cph]
Maintainer: Jeroen Ooms <[email protected]>
Maintainer: Jeroen Ooms <[email protected]>
Repository: CRAN
Date/Publication: 2023-12-08 07:30:02 UTC
Date/Publication: 2024-09-20 11:50:24 UTC
1 change: 0 additions & 1 deletion src/library/curl/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ useDynLib(curl,R_handle_getcustom)
useDynLib(curl,R_handle_getheaders)
useDynLib(curl,R_handle_reset)
useDynLib(curl,R_handle_setform)
useDynLib(curl,R_handle_setheaders)
useDynLib(curl,R_handle_setopt)
useDynLib(curl,R_multi_add)
useDynLib(curl,R_multi_cancel)
Expand Down
18 changes: 18 additions & 0 deletions src/library/curl/NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
5.2.3
- Remove some CMD check verbosity per new CRAN rules
- New maintainer email address

5.2.2
- Disable a compression test for libcurl 8.7.1 which has a bug for deflate
- Change a unit test to work around firewall problems on CRANs WinBuilder

5.2.1
- In handle_setheader(), setting a header to a non-empty whitespace string will
now send a blank header. Using an empty string will still remove the header
altogether (this has not changed).
- Internally simplify handle_setheader() as a wrapper for handle_setopt(httpheader)
- Fix an issue where curl_fetch_stream() might not return all bytes received
by the C layer if the server closed the connection mid-response.
- No longer enable CURLOPT_UNRESTRICTED_AUTH by default
- Fix code to build with -DR_NO_REMAP (add all the Rf_ prefixes)

5.2.0
- The CURL_CA_BUNDLE envvar is now also used on non-Windows.
- curl_echo() now uses a random available port to run httpuv
Expand Down
11 changes: 9 additions & 2 deletions src/library/curl/R/email.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
#' By default, the port will be 25, unless \code{smtps://} is specified--then
#' the default will be 465 instead.
#'
#' For internet SMTP servers you probably need to pass a
#' \href{https://curl.se/libcurl/c/CURLOPT_USERNAME.html}{username} and
#' \href{https://curl.se/libcurl/c/CURLOPT_PASSWORD.html}{passwords} option.
#' For some servers you also need to pass a string with
#' \href{https://curl.se/libcurl/c/CURLOPT_LOGIN_OPTIONS.html}{login_options}
#' for example \code{login_options="AUTH=NTLM"}.
#'
#' @section Encrypting connections via SMTPS or STARTTLS:
#'
#' There are two different ways in which SMTP can be encrypted: SMTPS servers
Expand Down Expand Up @@ -51,8 +58,8 @@
#' for details. Default will try to SSL, proceed as normal otherwise.
#' @param verbose print output
#' @param ... other options passed to \code{\link{handle_setopt}}. In most cases
#' you will need to set a \code{username} and \code{password} to authenticate
#' with the SMTP server.
#' you will need to set a \code{username} and \code{password} or \code{login_options}
#' to authenticate with the SMTP server, see details.
#' @examples \dontrun{# Set sender and recipients (email addresses only)
#' recipients <- readline("Enter your email address to receive test: ")
#' sender <- '[email protected]'
Expand Down
21 changes: 11 additions & 10 deletions src/library/curl/R/handle.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,21 @@ handle_setopt <- function(handle, ..., .list = list()){
}

#' @export
#' @useDynLib curl R_handle_setheaders
#' @rdname handle
handle_setheaders <- function(handle, ..., .list = list()){
stopifnot(inherits(handle, "curl_handle"))
opts <- c(list(...), .list)
if(!all(vapply(opts, is.character, logical(1)))){
x <- c(list(...), .list)
if(!all(vapply(x, is.character, logical(1)))){
stop("All headers must be strings.")
}
opts$Expect = ""
names <- names(opts)
values <- as.character(unlist(opts))
vec <- paste0(names, ": ", values)
.Call(R_handle_setheaders, handle, vec)
invisible(handle)
handle_setopt(handle, httpheader = format_request_headers(x))
}

format_request_headers <- function(x){
x$Expect = ""
names <- names(x)
values <- as.character(unlist(x))
postfix <- ifelse(grepl("^\\s+$", values), ";", paste(":", values))
paste0(names, postfix)
}

#' @useDynLib curl R_handle_getheaders
Expand Down
18 changes: 9 additions & 9 deletions src/library/curl/configure
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,21 @@ if [ $? -ne 0 ]; then
exit 1
fi

# Hack for MacOS 11 which has newer headers than the libcurl lib
# if [ `uname` = "Darwin" ]; then
# MACVERSION=`sw_vers -productVersion` || true
# case "$MACVERSION" in
# "11"*)
# PKG_CFLAGS="$PKG_CFLAGS -DDISABLE_CURL_EASY_OPTION";;
# esac
# fi
# Disable purling on oldrel due to https://github.com/yihui/knitr/issues/2338
if [ `uname` = "Darwin" ] && [ "${R_VERSION}" = "4.3.3" ]; then
for file in vignettes/*.Rmd; do
sed -i '' '/```/,$d' $file || true
touch inst/doc/* || true
done
fi

# Write to Makevars
sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars

# Extract curlopt symbols
echo '#include <curl/curl.h>' | ${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E -xc - \
| grep "^[ \t]*CURLOPT_.*," | sed s/,// > tools/option_table.txt
| grep "^[ \t]*CURLOPT_.*," | sed s/,// | sed 's/__attribute__[(][(].*[)][)] =/=/' \
> tools/option_table.txt

# Success
exit 0
2 changes: 1 addition & 1 deletion src/library/curl/src/Makevars.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PKG_CFLAGS=$(C_VISIBILITY)
PKG_CPPFLAGS=@cflags@ -DSTRICT_R_HEADERS
PKG_CPPFLAGS=@cflags@ -DSTRICT_R_HEADERS -DR_NO_REMAP
PKG_LIBS=@libs@

all: clean
Expand Down
2 changes: 1 addition & 1 deletion src/library/curl/src/Makevars.win
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PKG_LIBS = \
-lwinhttp -lcurl -lnghttp2 -lssh2 -lz -lssl -lcrypto -pthread -lgdi32 -lws2_32 -lcrypt32 -lbcrypt -lwldap32

PKG_CPPFLAGS= \
-I$(RWINLIB)/include -DCURL_STATICLIB -DSTRICT_R_HEADERS
-I$(RWINLIB)/include -DCURL_STATICLIB -DSTRICT_R_HEADERS -DR_NO_REMAP

all: clean winlibs

Expand Down
18 changes: 9 additions & 9 deletions src/library/curl/src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ int R_curl_callback_progress(SEXP fun,
double dltotal, double dlnow,
double ultotal, double ulnow) {

SEXP down = PROTECT(allocVector(REALSXP, 2));
SEXP down = PROTECT(Rf_allocVector(REALSXP, 2));
REAL(down)[0] = dltotal;
REAL(down)[1] = dlnow;

SEXP up = PROTECT(allocVector(REALSXP, 2));
SEXP up = PROTECT(Rf_allocVector(REALSXP, 2));
REAL(up)[0] = ultotal;
REAL(up)[1] = ulnow;

Expand All @@ -21,19 +21,19 @@ int R_curl_callback_progress(SEXP fun,
return CURL_READFUNC_ABORT;
}

if (TYPEOF(res) != LGLSXP || length(res) != 1) {
if (TYPEOF(res) != LGLSXP || Rf_length(res) != 1) {
UNPROTECT(4);
Rf_warning("progress callback must return boolean");
return 0;
}

int out = asLogical(res);
int out = Rf_asLogical(res);
UNPROTECT(4);
return !out;
}

size_t R_curl_callback_read(char *buffer, size_t size, size_t nitems, SEXP fun) {
SEXP nbytes = PROTECT(ScalarInteger(size * nitems));
SEXP nbytes = PROTECT(Rf_ScalarInteger(size * nitems));
SEXP call = PROTECT(Rf_lang2(fun, nbytes));

int ok;
Expand All @@ -50,7 +50,7 @@ size_t R_curl_callback_read(char *buffer, size_t size, size_t nitems, SEXP fun)
return CURL_READFUNC_ABORT;
}

size_t bytes_read = length(res);
size_t bytes_read = Rf_length(res);
memcpy(buffer, RAW(res), bytes_read);

UNPROTECT(3);
Expand All @@ -59,7 +59,7 @@ size_t R_curl_callback_read(char *buffer, size_t size, size_t nitems, SEXP fun)

/* origin is always SEEK_SET in libcurl, not really useful to pass on */
int R_curl_callback_seek(SEXP fun, curl_off_t offset, int origin){
SEXP soffset = PROTECT(ScalarReal(offset));
SEXP soffset = PROTECT(Rf_ScalarReal(offset));
SEXP call = PROTECT(Rf_lang2(fun, soffset));
int ok;
R_tryEval(call, R_GlobalEnv, &ok);
Expand All @@ -71,8 +71,8 @@ int R_curl_callback_debug(CURL *handle, curl_infotype type_, char *data,
size_t size, SEXP fun) {

/* wrap type and msg into R types */
SEXP type = PROTECT(ScalarInteger(type_));
SEXP msg = PROTECT(allocVector(RAWSXP, size));
SEXP type = PROTECT(Rf_ScalarInteger(type_));
SEXP msg = PROTECT(Rf_allocVector(RAWSXP, size));
memcpy(RAW(msg), data, size);

/* call the R function */
Expand Down
24 changes: 17 additions & 7 deletions src/library/curl/src/curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static size_t push(void *contents, size_t sz, size_t nmemb, void *ctx) {
//Rprintf("Resizing buffer to %d.\n", newlimit);
void *newbuf = realloc(req->buf, newlimit);
if(!newbuf)
error("Failure in realloc. Out of memory?");
Rf_error("Failure in realloc. Out of memory?");
req->buf = newbuf;
req->limit = newlimit;
}
Expand Down Expand Up @@ -130,6 +130,16 @@ static size_t rcurl_read(void *target, size_t sz, size_t ni, Rconnection con) {

/* append data to the target buffer */
size_t total_size = pop(target, req_size, req);

if (total_size > 0 && (!con->blocking || req->partial)) {
// If we can return data without waiting, and the connection is
// non-blocking (or using curl_fetch_stream()), do so.
// This ensures that bytes we already received get flushed
// to the target buffer before a connection error.
con->incomplete = req->has_more || req->size;
return total_size;
}

while((req_size > total_size) && req->has_more) {
/* wait for activity, timeout or "nothing" */
#ifdef HAS_MULTI_WAIT
Expand Down Expand Up @@ -246,14 +256,14 @@ static Rboolean rcurl_open(Rconnection con) {
}

SEXP R_curl_connection(SEXP url, SEXP ptr, SEXP partial) {
if(!isString(url))
error("Argument 'url' must be string.");
if(!Rf_isString(url))
Rf_error("Argument 'url' must be string.");

/* create the R connection object, mimicking base::url() */
Rconnection con;

/* R wants description in native encoding, but we use UTF-8 URL below */
SEXP rc = PROTECT(R_new_custom_connection(translateChar(STRING_ELT(url, 0)), "r", "curl", &con));
SEXP rc = PROTECT(R_new_custom_connection(Rf_translateChar(STRING_ELT(url, 0)), "r", "curl", &con));

/* setup curl. These are the parts that are recycable. */
request *req = malloc(sizeof(request));
Expand All @@ -262,12 +272,12 @@ SEXP R_curl_connection(SEXP url, SEXP ptr, SEXP partial) {
req->limit = CURL_MAX_WRITE_SIZE;
req->buf = malloc(req->limit);
req->manager = curl_multi_init();
req->partial = asLogical(partial); //only for curl_fetch_stream()
req->partial = Rf_asLogical(partial); //only for curl_fetch_stream()
req->used = 0;

/* allocate url string */
req->url = malloc(strlen(translateCharUTF8(asChar(url))) + 1);
strcpy(req->url, translateCharUTF8(asChar(url)));
req->url = malloc(strlen(Rf_translateCharUTF8(Rf_asChar(url))) + 1);
strcpy(req->url, Rf_translateCharUTF8(Rf_asChar(url)));

/* set connection properties */
con->incomplete = FALSE;
Expand Down
28 changes: 14 additions & 14 deletions src/library/curl/src/download.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
#include "curl-common.h"

SEXP R_download_curl(SEXP url, SEXP destfile, SEXP quiet, SEXP mode, SEXP ptr, SEXP nonblocking) {
if(!isString(url))
error("Argument 'url' must be string.");
if(!Rf_isString(url))
Rf_error("Argument 'url' must be string.");

if(!isString(destfile))
error("Argument 'destfile' must be string.");
if(!Rf_isString(destfile))
Rf_error("Argument 'destfile' must be string.");

if(!isLogical(quiet))
error("Argument 'quiet' must be TRUE/FALSE.");
if(!Rf_isLogical(quiet))
Rf_error("Argument 'quiet' must be TRUE/FALSE.");

if(!isString(mode))
error("Argument 'mode' must be string.");
if(!Rf_isString(mode))
Rf_error("Argument 'mode' must be string.");

/* get the handle */
CURL *handle = get_handle(ptr);
reset_errbuf(get_ref(ptr));

/* open file */
FILE *dest = fopen(CHAR(asChar(destfile)), CHAR(asChar(mode)));
FILE *dest = fopen(CHAR(Rf_asChar(destfile)), CHAR(Rf_asChar(mode)));
if(!dest)
error("Failed to open file %s.", CHAR(asChar(destfile)));
Rf_error("Failed to open file %s.", CHAR(Rf_asChar(destfile)));

/* set options */
curl_easy_setopt(handle, CURLOPT_URL, translateCharUTF8(asChar(url)));
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, asLogical(quiet));
curl_easy_setopt(handle, CURLOPT_URL, Rf_translateCharUTF8(Rf_asChar(url)));
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, Rf_asLogical(quiet));
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, push_disk);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, dest);

/* perform blocking request */
CURLcode status = asLogical(nonblocking) ?
CURLcode status = Rf_asLogical(nonblocking) ?
curl_perform_with_interrupt(handle) : curl_easy_perform(handle);

/* cleanup */
Expand All @@ -47,5 +47,5 @@ SEXP R_download_curl(SEXP url, SEXP destfile, SEXP quiet, SEXP mode, SEXP ptr, S

/* check for success */
stop_for_status(handle);
return ScalarInteger(0);
return Rf_ScalarInteger(0);
}
8 changes: 4 additions & 4 deletions src/library/curl/src/escape.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@

SEXP R_curl_escape(SEXP url, SEXP unescape_) {
if (!Rf_isString(url))
error("`url` must be a character vector.");
Rf_error("`url` must be a character vector.");
CURL *handle = curl_easy_init();
int n = Rf_length(url);
SEXP output = PROTECT(allocVector(STRSXP, n));
SEXP output = PROTECT(Rf_allocVector(STRSXP, n));

for (int i = 0; i < n; i++) {
const char *input = CHAR(STRING_ELT(url, i));
char *out = asLogical(unescape_) ?
char *out = Rf_asLogical(unescape_) ?
curl_easy_unescape(handle, input, 0, NULL) : curl_easy_escape(handle, input, 0);
if(out != NULL){
SET_STRING_ELT(output, i, mkCharCE(out, CE_UTF8));
SET_STRING_ELT(output, i, Rf_mkCharCE(out, CE_UTF8));
curl_free(out);
}
}
Expand Down
Loading
Loading