curl-library
[PATCH] getconnectinfo also retrieves active connection
From: Frank Meier <frank.meier_at_ergon.ch>
Date: Wed, 29 Jul 2015 18:04:20 +0200
Date: Wed, 29 Jul 2015 18:04:20 +0200
--- docs/libcurl/curl_easy_getinfo.3 | 5 +- lib/connect.c | 23 +++-- lib/multi.c | 2 + lib/url.c | 4 +- tests/data/Makefile.inc | 2 +- tests/data/test1532 | 65 +++++++++++++ tests/libtest/Makefile.inc | 6 +- tests/libtest/lib1532.c | 201 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 295 insertions(+), 13 deletions(-) create mode 100644 tests/data/test1532 create mode 100644 tests/libtest/lib1532.c diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3 index d48ca04..5fbe4af 100644 --- a/docs/libcurl/curl_easy_getinfo.3 +++ b/docs/libcurl/curl_easy_getinfo.3 @@ -198,13 +198,16 @@ cookies (cookies for the handle have not been enabled or simply none have been received) 'struct curl_slist *' will be set to point to NULL. (Added in 7.14.1) .IP CURLINFO_LASTSOCKET -Pass a pointer to a long to receive the last socket used by this curl +Pass a pointer to a long to receive the most recently used socket by this curl session. If the socket is no longer valid, -1 is returned. When you finish working with the socket, you must call curl_easy_cleanup() as usual and let libcurl close the socket and cleanup other resources associated with the handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY(3)\fP. (Added in 7.15.2) +Since 7.44 the socket currently in use is retrieved, if called while the +transfer is in progress. + NOTE: this API is not really working on win64, since the SOCKET type on win64 is 64 bit large while its 'long' is only 32 bits. .IP CURLINFO_FTP_ENTRY_PATH diff --git a/lib/connect.c b/lib/connect.c index 5cb8928..74680dc 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -1196,6 +1196,8 @@ static int conn_is_conn(struct connectdata *conn, void *param) /* * Used to extract socket and connectdata struct for the most recent * transfer on the given SessionHandle. + * If the transfer is still in progress, the current socket and connectdata + * struct is returned. * * The returned socket will be CURL_SOCKET_BAD in case of failure! */ @@ -1207,19 +1209,22 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, DEBUGASSERT(data); /* this works for an easy handle: - * - that has been used for curl_easy_perform() - * - that is associated with a multi handle, and whose connection - * was detached with CURLOPT_CONNECT_ONLY + * - that has or is being used with curl_easy_perform() + * - that is associated with a multi handle and is being used + * or whose connection was detached with CURLOPT_CONNECT_ONLY */ - if(data->state.lastconnect && (data->multi_easy || data->multi)) { - struct connectdata *c = data->state.lastconnect; + if((data->state.lastconnect || data->easy_conn) + && ( data->multi || data->multi_easy)) { + struct connectdata *c = data->state.lastconnect? + data->state.lastconnect : data->easy_conn; struct connfind find; - find.tofind = data->state.lastconnect; + find.tofind = c; find.found = FALSE; - Curl_conncache_foreach(data->multi_easy? - &data->multi_easy->conn_cache: - &data->multi->conn_cache, &find, conn_is_conn); + Curl_conncache_foreach(data->multi? + &data->multi->conn_cache : + &data->multi_easy->conn_cache, + &find, conn_is_conn); if(!find.found) { data->state.lastconnect = NULL; diff --git a/lib/multi.c b/lib/multi.c index 0052087..1751e0f 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1103,6 +1103,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Curl_pgrsTime(data, TIMER_STARTSINGLE); result = Curl_connect(data, &data->easy_conn, &async, &protocol_connect); + /* Forget about lastconnect since we have a new esy_conn now */ + data->state.lastconnect = NULL; if(CURLE_NO_CONNECTION_AVAILABLE == result) { /* There was no connection available. We will go to the pending state and wait for an available connection. */ diff --git a/lib/url.c b/lib/url.c index 406c1f0..b503206 100644 --- a/lib/url.c +++ b/lib/url.c @@ -412,10 +412,12 @@ CURLcode Curl_close(struct SessionHandle *data) and detach this handle from there. */ curl_multi_remove_handle(data->multi, data); - if(data->multi_easy) + if(data->multi_easy) { /* when curl_easy_perform() is used, it creates its own multi handle to use and this is the one */ curl_multi_cleanup(data->multi_easy); + data->multi_easy = NULL; + } /* Destroy the timeout list that is held in the easy handle. It is /normally/ done by curl_multi_remove_handle() but this is "just in diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index f39db40..d349fe2 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -153,7 +153,7 @@ test1516 \ \ test1520 \ \ -test1525 test1526 test1527 test1528 test1529 test1530 test1531 \ +test1525 test1526 test1527 test1528 test1529 test1530 test1531 test1532 \ \ test1600 test1601 test1602 \ \ diff --git a/tests/data/test1532 b/tests/data/test1532 new file mode 100644 index 0000000..aae37c2 --- /dev/null +++ b/tests/data/test1532 @@ -0,0 +1,65 @@ +<testcase> +<info> +<keywords> +HTTP +</keywords> +</info> + +# Server-side +<reply> +<data> +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fakem +Content-Type: text/html +Content-Length: 12 + +Hello World +</data> +<datacheck> +Hello World +Hello World +Hello World +Hello World +</datacheck> +</reply> + +# Client-side +<client> +<server> +http +</server> +<features> +http +</features> +<tool> +lib1532 +</tool> +<name> +Curl_getconnectinfo +</name> +<command> +http://%HOSTIP:%HTTPPORT/1532 log/ip1532 +</command> +</client> + +<verify> +<file name="log/ip1532"> +SD-CB: 5 +SD-EASY-REUSE-FIN: 5 +SD-CB: 5 +SD-EASY-NOREUSE-FIN: -1 +SD-CB: 5 +SD-MULTI-REUSE-FIN-1: 5 +SD-MULTI-REUSE-FIN-2: -1 +SD-CB: 5 +SD-MULTI-NOREUSE-FIN-1: -1 +SD-MULTI-NOREUSE-FIN-2: -1 +</file> + +# TEST_ERR_SUCCESS is errorcode 120 +<errorcode> +120 +</errorcode> +</verify> +</testcase> diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 27d5ee9..340d9db 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -23,7 +23,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \ lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515 \ lib1520 \ - lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 \ + lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 \ lib1900 \ lib2033 @@ -388,6 +388,10 @@ lib1531_SOURCES = lib1531.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1531_LDADD = $(TESTUTIL_LIBS) lib1531_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1531 +lib1532_SOURCES = lib1532.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1532_LDADD = $(TESTUTIL_LIBS) +lib1532_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1532 + lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1900_LDADD = $(TESTUTIL_LIBS) lib1900_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/tests/libtest/lib1532.c b/tests/libtest/lib1532.c new file mode 100644 index 0000000..a2b3a46 --- /dev/null +++ b/tests/libtest/lib1532.c @@ -0,0 +1,201 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel_at_haxx.se>, 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 http://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" + + +static size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) +{ + CURL* curl = (CURL*)userdata; + FILE *moo = NULL; + long sd = -1; + size_t len = nitems * size; + if ( len >= 15 && !strncmp(buffer, "HTTP/1.1 200 OK", 15) ) { + curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-CB: %ld\n", sd); + fclose(moo); + } + return len; +} + + +static int multi_perform_complete(CURLM* multi) +{ + int res = 0; + int still_running; + CURLMsg *msg; + multi_perform(multi, &still_running); + while(still_running) { + struct timeval timeout; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd = -99; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + + select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); + + multi_perform(multi, &still_running); + } + + msg = curl_multi_info_read(multi, &still_running); + res = msg ? msg->data.result : TEST_ERR_FAILURE; + +test_cleanup: + return res; +} + + +int test(char *URL) +{ + + CURL* curl = NULL; + CURLM* multi = NULL; + int res = 0; + FILE *moo = NULL; + long sd = -1; + + global_init(CURL_GLOBAL_ALL); + multi_init(multi); + easy_init(curl); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curl, CURLOPT_HEADERDATA , curl); + easy_setopt(curl, CURLOPT_FORBID_REUSE, 0L); + + /* clear the file */ + moo = fopen(libtest_arg2, "wb"); + if(!moo) + goto test_cleanup; + fclose(moo); + + /* TEST WITH EASY INTERFACE */ + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-EASY-REUSE-FIN: %ld\n", sd); + fclose(moo); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curl, CURLOPT_HEADERDATA , curl); + easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-EASY-NOREUSE-FIN: %ld\n", sd); + fclose(moo); + + + /* TEST WITH MULTI INTERFACE */ + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curl, CURLOPT_HEADERDATA , curl); + easy_setopt(curl, CURLOPT_FORBID_REUSE, 0L); + + multi_add_handle(multi, curl); + res = multi_perform_complete(multi); + if(res) + goto test_cleanup; + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-MULTI-REUSE-FIN-1: %ld\n", sd); + fclose(moo); + + multi_remove_handle(multi, curl); + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-MULTI-REUSE-FIN-2: %ld\n", sd); + fclose(moo); + + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + easy_setopt(curl, CURLOPT_HEADERDATA , curl); + easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); + + multi_add_handle(multi, curl); + res = multi_perform_complete(multi); + if(res) + goto test_cleanup; + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-MULTI-NOREUSE-FIN-1: %ld\n", sd); + fclose(moo); + + multi_remove_handle(multi, curl); + + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sd); + if (res) + goto test_cleanup; + + moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "SD-MULTI-NOREUSE-FIN-2: %ld\n", sd); + fclose(moo); + + + res = TEST_ERR_SUCCESS; + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_multi_cleanup(multi); + curl_global_cleanup(); + + return res; +} -- 2.3.6 --------------030206050405010107000708 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLQpMaXN0IGFkbWluOiBodHRwOi8vY29vbC5oYXh4LnNlL2xpc3QvbGlzdGluZm8v Y3VybC1saWJyYXJ5CkV0aXF1ZXR0ZTogIGh0dHA6Ly9jdXJsLmhheHguc2UvbWFpbC9ldGlxdWV0 dGUuaHRtbA== --------------030206050405010107000708--Received on 2001-09-17