On 4/26/2020 4:44 PM, Jean-Francois Dockes wrote:
Thanks for the CURLOPT_CONNECT_ONLY pointer.
Is there something to prevent me from using the resulting socket fd with
CURLOPT_OPENSOCKETFUNCTION / CURLOPT_SOCKOPTFUNCTION ? I see that
this is a
bit convoluted, but it gains me the use of the libcurl URL parsing and
connect code instead of DIY. Does it make sense ? Performance is no big
issue in my use case.
Since you are not sensible on performance, I wrote a working example
that does the job in 2 phases: 1 for the connect and 2 for the HTTP
protocol, reusing the socket descriptor from 1. It is then possible to
get the local address between the 2 phases. As it uses
CURLOPT_CONNECT_ONLY, connection reuse does not apply.
Please find it in attachment.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <curl/curl.h>
int
sockopt_callback(void *clientp, curl_socket_t curlfd, curlsocktype purpose)
{
curl_socket_t openedsocket = *(curl_socket_t *) clientp;
dup2(openedsocket, curlfd);
return CURL_SOCKOPT_ALREADY_CONNECTED;
}
CURL *
new_handle(void)
{
CURL *easy = curl_easy_init();
curl_easy_setopt(easy, CURLOPT_URL, "http://www.example.com");
curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L);
return easy;
}
int
main(int argc, char **argv)
{
CURL *hconnect;
CURL *htalk;
struct curl_slist *headers = NULL;
curl_socket_t sock;
struct sockaddr_storage locaddr;
socklen_t lasize = sizeof(locaddr);
struct sockaddr_in *la4 = (struct sockaddr_in *) &locaddr;
struct sockaddr_in6 *la6 = (struct sockaddr_in6 *) &locaddr;
char addrbuf[64];
char hdrbuf[128];
curl_global_init(CURL_GLOBAL_ALL);
hconnect = new_handle();
curl_easy_setopt(hconnect, CURLOPT_CONNECT_ONLY, 1L);
curl_easy_perform(hconnect);
curl_easy_getinfo(hconnect, CURLINFO_ACTIVESOCKET, &sock);
getsockname(sock, (struct sockaddr *) &locaddr, &lasize);
inet_ntop(la4->sin_family,
la4->sin_family == AF_INET? (void *) &la4->sin_addr:
(void *) &la6->sin6_addr,
addrbuf, sizeof(addrbuf));
snprintf(hdrbuf, sizeof(hdrbuf), "X-My-Address: %s", addrbuf);
headers = curl_slist_append(headers, hdrbuf);
htalk = new_handle();
curl_easy_setopt(htalk, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
curl_easy_setopt(htalk, CURLOPT_SOCKOPTDATA, &sock);
curl_easy_setopt(htalk, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(htalk);
curl_easy_cleanup(htalk);
curl_easy_cleanup(hconnect);
curl_slist_free_all(headers);
curl_global_cleanup();
exit(0);
}
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html