aboutsummaryrefslogtreecommitdiffstats
path: root/main/curl/conn_shutdown-if-closed-during-CONNECT-cleanup-properly.patch
blob: bc432276862d7da9f2fbc61b59d61b19962d86d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
From 14a2ca85ecb8478772a30d8c2521e5e1d1d98b3d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 9 Jun 2021 08:38:07 +0200
Subject: [PATCH] conn_shutdown: if closed during CONNECT cleanup properly

Reported-by: Alex Xu
Reported-by: Phil E. Taylor

Fixes #7236
Closes #7237
---
 lib/http_proxy.c | 19 +++++++++++--------
 lib/http_proxy.h |  7 ++++---
 lib/url.c        |  9 +++++++++
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index a67d9d3b4115..e0a4987063d7 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -129,13 +129,13 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex)
 bool Curl_connect_complete(struct connectdata *conn)
 {
   return !conn->connect_state ||
-    (conn->connect_state->tunnel_state == TUNNEL_COMPLETE);
+    (conn->connect_state->tunnel_state >= TUNNEL_COMPLETE);
 }
 
 bool Curl_connect_ongoing(struct connectdata *conn)
 {
   return conn->connect_state &&
-    (conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
+    (conn->connect_state->tunnel_state <= TUNNEL_COMPLETE);
 }
 
 /* when we've sent a CONNECT to a proxy, we should rather either wait for the
@@ -202,13 +202,16 @@ static void connect_done(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
   struct http_connect_state *s = conn->connect_state;
-  s->tunnel_state = TUNNEL_COMPLETE;
-  Curl_dyn_free(&s->rcvbuf);
-  Curl_dyn_free(&s->req);
+  if(s->tunnel_state != TUNNEL_EXIT) {
+    s->tunnel_state = TUNNEL_EXIT;
+    Curl_dyn_free(&s->rcvbuf);
+    Curl_dyn_free(&s->req);
 
-  /* retore the protocol pointer */
-  data->req.p.http = s->prot_save;
-  infof(data, "CONNECT phase completed!\n");
+    /* retore the protocol pointer */
+    data->req.p.http = s->prot_save;
+    s->prot_save = NULL;
+    infof(data, "CONNECT phase completed!\n");
+  }
 }
 
 static CURLcode CONNECT_host(struct Curl_easy *data,
diff --git a/lib/http_proxy.h b/lib/http_proxy.h
index f5a4cb07cf1b..cdf8de4fba86 100644
--- a/lib/http_proxy.h
+++ b/lib/http_proxy.h
@@ -65,9 +65,10 @@ struct http_connect_state {
   } keepon;
   curl_off_t cl; /* size of content to read and ignore */
   enum {
-    TUNNEL_INIT,    /* init/default/no tunnel state */
-    TUNNEL_CONNECT, /* CONNECT has been sent off */
-    TUNNEL_COMPLETE /* CONNECT response received completely */
+    TUNNEL_INIT,     /* init/default/no tunnel state */
+    TUNNEL_CONNECT,  /* CONNECT has been sent off */
+    TUNNEL_COMPLETE, /* CONNECT response received completely */
+    TUNNEL_EXIT
   } tunnel_state;
   BIT(chunked_encoding);
   BIT(close_connection);
diff --git a/lib/url.c b/lib/url.c
index 84d37a560eaf..27ba7d6b52ce 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -727,6 +727,15 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
   DEBUGASSERT(data);
   infof(data, "Closing connection %ld\n", conn->connection_id);
 
+#ifndef USE_HYPER
+  if(conn->connect_state && conn->connect_state->prot_save) {
+    /* If this was closed with a CONNECT in progress, cleanup this temporary
+       struct arrangement */
+    data->req.p.http = NULL;
+    Curl_safefree(conn->connect_state->prot_save);
+  }
+#endif
+
   /* possible left-overs from the async name resolvers */
   Curl_resolver_cancel(data);