Hi, <first post on this list, please be kind :->
We use curl (version 7.57.0) in our product and discovered a bug in curl_easy_reset(). We have an application that connects to two hosts (using HTTP). When the code is executed to establish just a session with host 1, result is OK. When the code is executed to establish just a session with host 2, result is OK. When the code is executed to establish a session to host 1, do a curl_easy_reset, then contact host 2 (re-using the handle), the result is a HTTP 401 (unauthorized) for the connection to host 2. So it would seem the curl_easy_reset handle retains some information about the previous connection which causes the next connection to host 2 to fail. Host 1 uses HTTP, host 2 HTTPS (don't know if that is relevant). I've reproduced the problem in a small C program (attached, with some userid/password stuff blanked out). Output in our environment (where XXXX and YYYY are working usrenames/passwords): rbeerstr@nlbaldev3: ./curl_test one Start with http://XXXXXX:YYYYYY@nlbavwtech7:8312/webui/servlet/deploy?command=ping HTTP 302 rbeerstr@nlbaldev3: ./curl_test two Start with https://XXXXXX:[email protected]:8447/lnui_ux/servlet/deploy?command=ping HTTP 302 rbeerstr@nlbaldev3: ./curl_test both Start with http://XXXXXX:XXXXXX@nlbavwtech7:8312/webui/servlet/deploy?command=ping HTTP 302 Start with https://XXXXXX:[email protected]:8447/lnui_ux/servlet/deploy?command=ping HTTP 401 rbeerstr@nlbaldev3: When I change the curl_easy_reset() call into a curl_easy_cleanup() followed by curl_easy_init, the output becomes: rbeerstr@nlbaldev3: ./curl_test one Start with http://XXXXXX:YYYYYY@nlbavwtech7:8312/webui/servlet/deploy?command=ping HTTP 302 rbeerstr@nlbaldev3: ./curl_test two Start with https://XXXXXX:[email protected]:8447/lnui_ux/servlet/deploy?command=ping HTTP 302 rbeerstr@nlbaldev3: ./curl_test both Start with http://XXXXXX:XXXXXX@nlbavwtech7:8312/webui/servlet/deploy?command=ping HTTP 302 Start with https://XXXXXX:[email protected]:8447/lnui_ux/servlet/deploy?command=ping HTTP 302 rbeerstr@nlbaldev3: I.e., then it works fine. We have a reasonable workaround (separate sessions) but any insights or solutions would be much appreciated. Regards, Ruurd Beerstra Infor.
#include <stdio.h> #include <curl/curl.h> #define url1 "http://XXXXXXXX:YYYYYYYY@nlbavwtech7:8312/webui/servlet/deploy?command=ping" #define url2 "https://XXXXXXXX:[email protected]:8447/lnui_ux/servlet/deploy?command=ping" static CURL *curl; static int Verbose = 0; void is_url_valid(char *url) { long httpStatus; CURLcode res; printf("Start with %s\n",url); curl_easy_setopt(curl,CURLOPT_VERBOSE,Verbose); res = curl_easy_setopt(curl,CURLOPT_HTTPAUTH,CURLAUTH_DIGEST); if (res != CURLE_OK) printf("CURLOPT_HTTPAUTH = %d\n",res); res = curl_easy_setopt(curl,CURLOPT_COOKIEFILE,"old.txt"); if (res != CURLE_OK) printf("CURLOPT_COOKIEFILE = %d\n",res); res = curl_easy_setopt(curl,CURLOPT_COOKIEJAR,"new.txt"); if (res != CURLE_OK) printf("CURLOPT_COOKIEJAR = %d\n",res); res = curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0); if (res != CURLE_OK) printf("CURLOPT_SSL_VERIFYPEER = %d\n",res); res = curl_easy_setopt(curl,CURLOPT_URL,url); if (res != CURLE_OK) printf("CURLOPT_URL = %d\n",res); res = curl_easy_perform(curl); if (res != CURLE_OK) printf("Perform = %d\n",res); res = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpStatus); if (res != CURLE_OK) printf("CURLINFO_RESPONSE_CODE = %d\n",res); printf("HTTP %ld\n",httpStatus); curl_easy_reset(curl); //curl_easy_cleanup(curl); //curl = curl_easy_init(); } int main (int argc, char **argv) { int arg = 1; if (argc > 1 && strcmp(argv[arg],"-v") == 0) { Verbose = 1; arg++; } curl = curl_easy_init(); if (curl) { if (strcmp(argv[arg],"one") == 0 || strcmp(argv[arg],"both") == 0) is_url_valid(url1); if (strcmp(argv[arg],"two") == 0 || strcmp(argv[arg],"both") == 0) is_url_valid(url2); } }
------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.haxx.se/mail/etiquette.html
