cURL / Mailing Lists / curl-library / Single Mail

curl-library

Problem with non-blocking proxy CONNECT

From: Shmulik Regev <shmulbox_at_gmail.com>
Date: Thu, 14 Jun 2007 17:04:18 +0300

Hi,,

I've encountered (and hopefully fixed) a problem involving proxy
CONNECT requests and easy handles state management. The problem isn't
simple to reproduce since it depends on socket state. It only
manifests itself when working with non-blocking sockets.

Here is the scenario:
1. in multi_runsingle the easy handle is in the
CURLM_STATE_WAITCONNECT and calls Curl_protocol_connect

2. in Curl_proxyCONNECT, line 1247, if the socket isn't ready the
function returns and conn->bits.tunnel_connecting is TRUE

3. when the call to Curl_protocol_connect returns the protocol_connect
flag is false and the easy state is changed to
CURLM_STATE_PROTOCONNECT which isn't correct if a proxy is used.
Rather CURLM_STATE_WAITPROXYCONNECT should be used.

I discovered this while performing an HTTPS request through a proxy
(squid) on my local network. The problem caused openssl to fail as it
read the proxy response to the CONNECT call ('HTTP/1.0 Established')
rather than the SSL handshake (the exact openssl error was 'wrong ssl
version' but this isn't very important)

The patch below fixes this.

Cheers,
Shmul

Index: multi.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/multi.c,v
retrieving revision 1.146
diff -u -r1.146 multi.c
--- multi.c 1 Jun 2007 21:24:34 -0000 1.146
+++ multi.c 14 Jun 2007 13:54:50 -0000
@@ -1007,8 +1007,15 @@
         if(!protocol_connect) {
           /* We have a TCP connection, but 'protocol_connect' may be false
              and then we continue to 'STATE_PROTOCONNECT'. If protocol
- connect is TRUE, we move on to STATE_DO. */
- multistate(easy, CURLM_STATE_PROTOCONNECT);
+ connect is TRUE, we move on to STATE_DO.
+ BUT if we are using a proxy we must change to WAITPROXYCONNECT
+ */
+#ifndef CURL_DISABLE_HTTP
+ if (easy->easy_conn->bits.tunnel_connecting)
+ multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
+ else
+#endif
+ multistate(easy, CURLM_STATE_PROTOCONNECT);
         }
         else {
           /* after the connect has completed, go WAITDO */
Received on 2007-06-14