curl-library
libcurl blocking in multi-mode when doing proxied https fetch from bad host
Date: Mon, 22 Jan 2007 18:04:57 +0000
Hi all!
I'm having an unpleasant problem in a server where a particular type
of bogus https:// fetch is blocking (for 60 seconds!) despite my
using multi-mode, when connecting via a Squid proxy (the app needs
this proxy to function).
This is stalling the whole (single-threaded) server, which of course
isn't ideal. :)
I attach a minimal reproduction case. It's basically just minimal code
for a fetch from a bogus https://6.6.6.6 server with verbose mode turned
on and a little ASCII 'spinner' added to illustrate blocking (or lack
thereof).
If you run via a Squid proxy like so:
HTTPS_PROXY=localhost:1234 ./testnonblock5m
... then you should see that the program blocks on
'Establish HTTP proxy tunnel to 6.6.6.6:443' for about sixty seconds.
If you just run without a proxy, you should get 'Trying 6.6.6.6...'
without blocking (i.e. the spinner spins for sixty seconds while waiting
for the timeout).
This seems particular to https:// URLs. I'm mainly using libcurl
7.12.2; I've tried 7.16.0 but the problem persisted there also. If it's
relevant, the Squid being connected to is squid/2.5.STABLE9. I'm
guessing that this is a libcurl problem since even if Squid itself is
undesirably blocking, libcurl probably shouldn't be communicating with
it in a blocking manner.
I'd appreciate any ideas for workarounds or such!
Thanks,
--Adam
/* meant to demonstrate libcurl erroneously blocking while talking
to a squid proxy. Set HTTPS_PROXY to your squid proxy to see the
problem. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* somewhat unix-specific */
#include <sys/time.h>
#include <unistd.h>
/* curl stuff */
#include <curl/curl.h>
static int debug_callback (CURL *ch, curl_infotype ci,
char *data, size_t datasize, void *user) {
if (CURLINFO_TEXT == ci) {
while (datasize--)
fprintf(stderr, "%c", *(data++));
fprintf(stderr, "\n");
}
return 0;
}
int main(int argc, char **argv)
{
CURL *http_handle;
CURLM *multi_handle;
CURLcode code;
int still_running; /* keep number of running handles */
http_handle = curl_easy_init();
curl_easy_setopt(http_handle, CURLOPT_URL, "https://6.6.6.6");
curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, debug_callback);
curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1);
/* init a multi stack */
multi_handle = curl_multi_init();
/* add the individual transfers */
curl_multi_add_handle(multi_handle, http_handle);
/* show an on-screen spinner to indicate that we're (not) blocking. */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running) ||
still_running)
{
static char spinner[] = "-\\|/";
static int counter = 0;
fprintf(stderr, "%c\b", spinner[counter]);
counter = (counter + 1) % 4;
}
fprintf(stderr, "\nFinished.\n");
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(http_handle);
return 0;
}
Received on 2007-01-22