Changelog
Daniel S (14 June 2007)
+- Shmulik Regev:
+
+ 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)
+
- Dave Vasilevsky filed bug report #1736875
(http://curl.haxx.se/bug/view.cgi?id=1736875) almost simultanouesly as Dan
Fandrich mentioned a related build problem on the libcurl mailing list:
o out-of-boundary write in Curl_select()
o -s/--silent can now be used to toggle off the silence again
o builds fine on 64bit HP-UX
+ o multi interface HTTP CONNECT glitch
This release includes the following known bugs:
Frank Hempel, Michael Wallner, Jeff Pohlmeyer, Tobias Rundström,
Anders Gustafsson, James Bursa, Kristian Gunstone, Feng Tu,
Andre Guibert de Bruet, Rob Crittenden, Rich Rauenzahn, Tom Regner,
- Dave Vasilevsky
+ Dave Vasilevsky, Shmulik Regev
Thanks! (and sorry if I forgot to mention someone)
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 */