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

CURLOPT_FOLLOWLOCATION with CURLOPT_CURLU: infinitely following locations #5709

Closed
ghost opened this issue Jul 21, 2020 · 2 comments
Closed
Labels

Comments

@ghost
Copy link

ghost commented Jul 21, 2020

I did this

#include <curl/curl.h>

int main(){
    CURLU* url = curl_url();
    curl_url_set(url, CURLUPART_URL, "https://google.com", 0);

    CURL* get = curl_easy_init();

    curl_easy_setopt(get, CURLOPT_CURLU, url);
    curl_easy_setopt(get, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(get, CURLOPT_VERBOSE, 1L);
    curl_easy_perform(get);

    curl_easy_cleanup(get);
    curl_url_cleanup(url);
}

I expected the following

I expected this would follow to the desired location. Instead curl_easy_perform() is blocking forever, infinitely following the location. Just happens when I set the url with CURLOPT_CURLU, CURLOPT_URL is working as expected. Same error for multiple hosts.

curl/libcurl version

curl 7.71.1 (x86_64-pc-linux-gnu) libcurl/7.71.1 OpenSSL/1.1.1g zlib/1.2.11 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh2/1.9.0 nghttp2/1.41.0
Release-Date: 2020-07-01
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

operating system

Linux 5.7.8-arch1-1

@jay jay added the URL label Jul 22, 2020
@jay
Copy link
Member

jay commented Jul 22, 2020

I can reproduce this. It probably has something to do with parseurlandfillconn which will set the url handle to the user setting (stored in data->set.uh), even on redirect.

curl/lib/url.c

Lines 1840 to 1848 in 5a1fc8d

up_free(data); /* cleanup previous leftovers first */
/* parse the URL */
if(data->set.uh) {
uh = data->state.uh = curl_url_dup(data->set.uh);
}
else {
uh = data->state.uh = curl_url();
}

data->state.uh where the redirect URL handle was stored is freed by up_free and then overwritten. That seems right though but I think something is missing like a data->change.uh to complement data->change.url so uh overwrites data->change.url?

jay added a commit to jay/curl that referenced this issue Jul 23, 2020
Prior to this change if the user set a URL handle (CURLOPT_CURLU) it was
incorrectly used for the location follow, resulting in infinite requests
to the original location.

Reported-by: sspiri@users.noreply.github.com

Fixes curl#5709
Closes #xxxx
@jay
Copy link
Member

jay commented Jul 23, 2020

Try #5713

jay added a commit to jay/curl that referenced this issue Jul 30, 2020
Prior to this change if the user set a URL handle (CURLOPT_CURLU) it was
incorrectly used for the location follow, resulting in infinite requests
to the original location.

Reported-by: sspiri@users.noreply.github.com

Fixes curl#5709
Closes #xxxx
@jay jay closed this as completed in a12a161 Jul 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

1 participant