diff --git a/DESCRIPTION b/DESCRIPTION index 52781c8..b42de47 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: curl Type: Package Title: A Modern and Flexible Web Client for R -Version: 6.0.2 +Version: 6.1.0 Authors@R: c( person("Jeroen", "Ooms", role = c("aut", "cre"), email = "jeroenooms@gmail.com", comment = c(ORCID = "0000-0002-4035-0289")), diff --git a/NEWS b/NEWS index be00e29..3139e11 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,8 @@ -6.0.2 +6.1.0 - Fix a rchk bug - Enable CURLOPT_PIPEWAIT by default to prefer multiplex when possible - Enable setting max_streams in multi_set(), default to 10 + - Allow open(curl::curl()) to be interrupted 6.0.1 - Fix a build issue with libcurl 8.11.0 diff --git a/src/curl.c b/src/curl.c index 540c6f2..cc3035d 100644 --- a/src/curl.c +++ b/src/curl.c @@ -224,6 +224,10 @@ static Rboolean rcurl_open(Rconnection con) { while(block_open && req->has_more && !req->has_data) { int numfds; massert(curl_multi_wait(req->manager, NULL, 0, 1000, &numfds)); + if(pending_interrupt()) { + reset(con); //cleanup before jumping + assert_message(CURLE_ABORTED_BY_CALLBACK, NULL); + } massert(curl_multi_perform(req->manager, &(req->has_more))); for(int msg = 1; msg > 0;){ CURLMsg *out = curl_multi_info_read(req->manager, &msg); diff --git a/src/utils.c b/src/utils.c index 2e55b8b..ab28a9e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,19 @@ #include "curl-common.h" #include /* SIZE_MAX */ +#ifdef _WIN32 +#include +void send_r_interrupt() { + UserBreak = 1; + R_CheckUserInterrupt(); +} +#else +#include +void send_r_interrupt() { + Rf_onintr(); +} +#endif + CURL* get_handle(SEXP ptr){ return get_ref(ptr)->handle; } @@ -40,6 +53,8 @@ void reset_errbuf(reference *ref){ void assert_message(CURLcode res, const char *str){ if(res == CURLE_OK) return; + if(res == CURLE_ABORTED_BY_CALLBACK) + send_r_interrupt(); if(str == NULL) str = curl_easy_strerror(res); SEXP code = PROTECT(Rf_ScalarInteger(res)); @@ -54,6 +69,8 @@ void assert_message(CURLcode res, const char *str){ void assert_status(CURLcode res, reference *ref){ if(res == CURLE_OK) return; + if(res == CURLE_ABORTED_BY_CALLBACK) + send_r_interrupt(); const char *source_url = NULL; curl_easy_getinfo(ref->handle, CURLINFO_EFFECTIVE_URL, &source_url); SEXP url = PROTECT(make_string(source_url));