Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/curl/tests/libtest/cli_tls_session_reuse.c
2649 views
1
/***************************************************************************
2
* _ _ ____ _
3
* Project ___| | | | _ \| |
4
* / __| | | | |_) | |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
7
*
8
* Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9
*
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at https://curl.se/docs/copyright.html.
13
*
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
17
*
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
20
*
21
* SPDX-License-Identifier: curl
22
*
23
***************************************************************************/
24
#include "first.h"
25
26
#include "testtrace.h"
27
#include "memdebug.h"
28
29
static int tse_found_tls_session = FALSE;
30
31
static size_t write_tse_cb(char *ptr, size_t size, size_t nmemb, void *opaque)
32
{
33
CURL *curl = opaque;
34
(void)ptr;
35
if(!tse_found_tls_session) {
36
struct curl_tlssessioninfo *tlssession;
37
CURLcode rc;
38
39
rc = curl_easy_getinfo(curl, CURLINFO_TLS_SSL_PTR, &tlssession);
40
if(rc) {
41
curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) "
42
"failed: %s\n", curl_easy_strerror(rc));
43
return rc;
44
}
45
if(tlssession->backend == CURLSSLBACKEND_NONE) {
46
curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) "
47
"gave no backend\n");
48
return CURLE_FAILED_INIT;
49
}
50
if(!tlssession->internals) {
51
curl_mfprintf(stderr, "curl_easy_getinfo(CURLINFO_TLS_SSL_PTR) "
52
"missing\n");
53
return CURLE_FAILED_INIT;
54
}
55
tse_found_tls_session = TRUE;
56
}
57
return size * nmemb;
58
}
59
60
static CURL *tse_add_transfer(CURLM *multi, CURLSH *share,
61
struct curl_slist *resolve,
62
const char *url, long http_version)
63
{
64
CURL *curl;
65
CURLMcode mc;
66
67
curl = curl_easy_init();
68
if(!curl) {
69
curl_mfprintf(stderr, "curl_easy_init failed\n");
70
return NULL;
71
}
72
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
73
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cli_debug_cb);
74
curl_easy_setopt(curl, CURLOPT_URL, url);
75
curl_easy_setopt(curl, CURLOPT_SHARE, share);
76
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
77
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L);
78
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
79
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);
80
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_tse_cb);
81
curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl);
82
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
83
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
84
if(resolve)
85
curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve);
86
87
88
mc = curl_multi_add_handle(multi, curl);
89
if(mc != CURLM_OK) {
90
curl_mfprintf(stderr, "curl_multi_add_handle: %s\n",
91
curl_multi_strerror(mc));
92
curl_easy_cleanup(curl);
93
return NULL;
94
}
95
return curl;
96
}
97
98
static CURLcode test_cli_tls_session_reuse(const char *URL)
99
{
100
CURLM *multi = NULL;
101
CURLMcode mc;
102
int running_handles = 0, numfds;
103
CURLMsg *msg;
104
CURLSH *share = NULL;
105
CURLU *cu;
106
struct curl_slist *resolve = NULL;
107
char resolve_buf[1024];
108
int msgs_in_queue;
109
int add_more, waits, ongoing = 0;
110
char *host = NULL, *port = NULL;
111
long http_version = CURL_HTTP_VERSION_1_1;
112
CURLcode result = (CURLcode)1;
113
114
if(!URL || !libtest_arg2) {
115
curl_mfprintf(stderr, "need args: URL proto\n");
116
return (CURLcode)2;
117
}
118
119
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
120
curl_mfprintf(stderr, "curl_global_init() failed\n");
121
return (CURLcode)3;
122
}
123
124
if(!strcmp("h2", libtest_arg2))
125
http_version = CURL_HTTP_VERSION_2;
126
else if(!strcmp("h3", libtest_arg2))
127
http_version = CURL_HTTP_VERSION_3ONLY;
128
129
cu = curl_url();
130
if(!cu) {
131
curl_mfprintf(stderr, "out of memory\n");
132
result = (CURLcode)1;
133
goto cleanup;
134
}
135
if(curl_url_set(cu, CURLUPART_URL, URL, 0)) {
136
curl_mfprintf(stderr, "not a URL: '%s'\n", URL);
137
goto cleanup;
138
}
139
if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {
140
curl_mfprintf(stderr, "could not get host of '%s'\n", URL);
141
goto cleanup;
142
}
143
if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {
144
curl_mfprintf(stderr, "could not get port of '%s'\n", URL);
145
goto cleanup;
146
}
147
148
curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",
149
host, port);
150
resolve = curl_slist_append(resolve, resolve_buf);
151
152
multi = curl_multi_init();
153
if(!multi) {
154
curl_mfprintf(stderr, "curl_multi_init failed\n");
155
goto cleanup;
156
}
157
158
share = curl_share_init();
159
if(!share) {
160
curl_mfprintf(stderr, "curl_share_init failed\n");
161
goto cleanup;
162
}
163
curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
164
165
166
if(!tse_add_transfer(multi, share, resolve, URL, http_version))
167
goto cleanup;
168
++ongoing;
169
add_more = 6;
170
waits = 3;
171
do {
172
mc = curl_multi_perform(multi, &running_handles);
173
if(mc != CURLM_OK) {
174
curl_mfprintf(stderr, "curl_multi_perform: %s\n",
175
curl_multi_strerror(mc));
176
goto cleanup;
177
}
178
179
if(running_handles) {
180
mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds);
181
if(mc != CURLM_OK) {
182
curl_mfprintf(stderr, "curl_multi_poll: %s\n",
183
curl_multi_strerror(mc));
184
goto cleanup;
185
}
186
}
187
188
if(waits) {
189
--waits;
190
}
191
else {
192
while(add_more) {
193
if(!tse_add_transfer(multi, share, resolve, URL, http_version))
194
goto cleanup;
195
++ongoing;
196
--add_more;
197
}
198
}
199
200
/* Check for finished handles and remove. */
201
/* !checksrc! disable EQUALSNULL 1 */
202
while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) {
203
if(msg->msg == CURLMSG_DONE) {
204
long status = 0;
205
curl_off_t xfer_id;
206
curl_easy_getinfo(msg->easy_handle, CURLINFO_XFER_ID, &xfer_id);
207
curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
208
if(msg->data.result == CURLE_SEND_ERROR ||
209
msg->data.result == CURLE_RECV_ERROR) {
210
/* We get these if the server had a GOAWAY in transit on
211
* reusing a connection */
212
}
213
else if(msg->data.result) {
214
curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T
215
": failed with %d\n", xfer_id, msg->data.result);
216
goto cleanup;
217
}
218
else if(status != 200) {
219
curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T
220
": wrong http status %ld (expected 200)\n", xfer_id,
221
status);
222
goto cleanup;
223
}
224
curl_multi_remove_handle(multi, msg->easy_handle);
225
curl_easy_cleanup(msg->easy_handle);
226
--ongoing;
227
curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T" retiring "
228
"(%d now running)\n", xfer_id, running_handles);
229
}
230
}
231
232
curl_mfprintf(stderr, "running_handles=%d, yet_to_start=%d\n",
233
running_handles, add_more);
234
235
} while(ongoing || add_more);
236
237
if(!tse_found_tls_session) {
238
curl_mfprintf(stderr, "CURLINFO_TLS_SSL_PTR not found during run\n");
239
result = CURLE_FAILED_INIT;
240
goto cleanup;
241
}
242
243
curl_mfprintf(stderr, "exiting\n");
244
result = CURLE_OK;
245
246
cleanup:
247
248
if(multi) {
249
CURL **list = curl_multi_get_handles(multi);
250
if(list) {
251
int i;
252
for(i = 0; list[i]; i++) {
253
curl_multi_remove_handle(multi, list[i]);
254
curl_easy_cleanup(list[i]);
255
}
256
curl_free(list);
257
}
258
curl_multi_cleanup(multi);
259
}
260
curl_share_cleanup(share);
261
curl_slist_free_all(resolve);
262
curl_free(host);
263
curl_free(port);
264
if(cu)
265
curl_url_cleanup(cu);
266
curl_global_cleanup();
267
268
return result;
269
}
270
271