diff --git a/lib/http_proxy.c b/lib/http_proxy.c index fc050a07d5..cfe616fa64 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -198,11 +198,11 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit) return CURLE_OK; } -static void connect_done(struct Curl_easy *data) +void Curl_connect_done(struct Curl_easy *data) { struct connectdata *conn = data->conn; struct http_connect_state *s = conn->connect_state; - if(s->tunnel_state != TUNNEL_EXIT) { + if(s && (s->tunnel_state != TUNNEL_EXIT)) { s->tunnel_state = TUNNEL_EXIT; Curl_dyn_free(&s->rcvbuf); Curl_dyn_free(&s->req); @@ -662,7 +662,7 @@ static CURLcode CONNECT(struct Curl_easy *data, if(s->close_connection && data->req.newurl) { conn->bits.proxy_connect_closed = TRUE; infof(data, "Connect me again please"); - connect_done(data); + Curl_connect_done(data); } else { free(data->req.newurl); @@ -974,7 +974,7 @@ static CURLcode CONNECT(struct Curl_easy *data, if(conn->bits.close && data->req.newurl) { conn->bits.proxy_connect_closed = TRUE; infof(data, "Connect me again please"); - connect_done(data); + Curl_connect_done(data); } else { free(data->req.newurl); @@ -1048,7 +1048,7 @@ CURLcode Curl_proxyCONNECT(struct Curl_easy *data, result = CONNECT(data, sockindex, hostname, remote_port); if(result || Curl_connect_complete(conn)) - connect_done(data); + Curl_connect_done(data); return result; } diff --git a/lib/multi.c b/lib/multi.c index f307d63b93..ce634fcacb 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -878,6 +878,7 @@ void Curl_detach_connnection(struct Curl_easy *data) { struct connectdata *conn = data->conn; if(conn) { + Curl_connect_done(data); /* if mid-CONNECT, shut it down */ Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); Curl_ssl_detach_conn(data, conn); } diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 9a8b64bed1..b6a503e72a 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -216,7 +216,7 @@ test1800 test1801 \ test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ test1916 test1917 test1918 \ \ -test1933 test1934 test1935 test1936 test1937 test1938 \ +test1933 test1934 test1935 test1936 test1937 test1938 test1939 \ \ test2000 test2001 test2002 test2003 test2004 \ \ diff --git a/tests/data/test1939 b/tests/data/test1939 new file mode 100644 index 0000000000..0b9987b5bb --- /dev/null +++ b/tests/data/test1939 @@ -0,0 +1,52 @@ + + + +CONNECT +curl_easy_cleanup + + + +# Server-side + + +HTTP/1.1 302 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 +Location: /%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +https +http-proxy + + + +curl_easy_cleanup without curl_multi_remove_handle - in CONNECT + + +lib%TESTNUMBER + + + +https://%HOSTIP:%HTTPPORT/%TESTNUMBER http://%HOSTIP:%PROXYPORT + + + +# Verify data after the test has been "shot" + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 8cea7c0146..62a7675b16 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -61,7 +61,8 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1591 lib1592 lib1593 lib1594 lib1596 \ lib1905 lib1906 lib1907 lib1908 lib1910 lib1911 lib1912 lib1913 \ lib1915 lib1916 lib1917 lib1918 lib1933 lib1934 lib1935 lib1936 \ - lib1937 lib1938 lib3010 + lib1937 lib1938 lib1939 \ + lib3010 chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \ ../../lib/curl_ctype.c ../../lib/dynbuf.c ../../lib/strdup.c @@ -715,6 +716,10 @@ lib1938_SOURCES = lib1938.c $(SUPPORTFILES) lib1938_LDADD = $(TESTUTIL_LIBS) lib1938_CPPFLAGS = $(AM_CPPFLAGS) +lib1939_SOURCES = lib1939.c $(SUPPORTFILES) +lib1939_LDADD = $(TESTUTIL_LIBS) +lib1939_CPPFLAGS = $(AM_CPPFLAGS) + lib3010_SOURCES = lib3010.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib3010_LDADD = $(TESTUTIL_LIBS) lib3010_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/tests/libtest/lib1939.c b/tests/libtest/lib1939.c new file mode 100644 index 0000000000..644617712e --- /dev/null +++ b/tests/libtest/lib1939.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURLM *multi; + CURL *easy; + int running_handles; + + curl_global_init(CURL_GLOBAL_DEFAULT); + + multi = curl_multi_init(); + if(!multi) + return 1; + + easy = curl_easy_init(); + if(easy) { + CURLcode c; + CURLMcode m; + + /* Crash only happens when using HTTPS */ + c = curl_easy_setopt(easy, CURLOPT_URL, URL); + if(!c) + /* Any old HTTP tunneling proxy will do here */ + c = curl_easy_setopt(easy, CURLOPT_PROXY, libtest_arg2); + + if(c) + return 2; + + /* We're going to drive the transfer using multi interface here, because we + want to stop during the middle. */ + m = curl_multi_add_handle(multi, easy); + + if(!m) + /* Run the multi handle once, just enough to start establishing an HTTPS + connection. */ + m = curl_multi_perform(multi, &running_handles); + + if(m) + return 3; + + /* Close the easy handle *before* the multi handle. Doing it the other way + around avoids the issue. */ + curl_easy_cleanup(easy); + } + curl_multi_cleanup(multi); /* double-free happens here */ + + curl_global_cleanup(); + return CURLE_OK; +}