From 970c22f970f0172e6a4c98ccc3176c740ddaa1c6 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 27 Nov 2014 23:59:25 +0100 Subject: libcurl: add UNIX domain sockets support The ability to do HTTP requests over a UNIX domain socket has been requested before, in Apr 2008 [0][1] and Sep 2010 [2]. While a discussion happened, no patch seems to get through. I decided to give it a go since I need to test a nginx HTTP server which listens on a UNIX domain socket. One patch [3] seems to make it possible to use the CURLOPT_OPENSOCKETFUNCTION function to gain a UNIX domain socket. Another person wrote a Go program which can do HTTP over a UNIX socket for Docker[4] which uses a special URL scheme (though the name contains cURL, it has no relation to the cURL library). This patch considers support for UNIX domain sockets at the same level as HTTP proxies / IPv6, it acts as an intermediate socket provider and not as a separate protocol. Since this feature affects network operations, a new feature flag was added ("unix-sockets") with a corresponding CURL_VERSION_UNIX_SOCKETS macro. A new CURLOPT_UNIX_SOCKET_PATH option is added and documented. This option enables UNIX domain sockets support for all requests on the handle (replacing IP sockets and skipping proxies). A new configure option (--enable-unix-sockets) and CMake option (ENABLE_UNIX_SOCKETS) can disable this optional feature. Note that I deliberately did not mark this feature as advanced, this is a feature/component that should easily be available. [0]: http://curl.haxx.se/mail/lib-2008-04/0279.html [1]: http://daniel.haxx.se/blog/2008/04/14/http-over-unix-domain-sockets/ [2]: http://sourceforge.net/p/curl/feature-requests/53/ [3]: http://curl.haxx.se/mail/lib-2008-04/0361.html [4]: https://github.com/Soulou/curl-unix-socket Signed-off-by: Peter Wu --- docs/libcurl/curl_easy_setopt.3 | 2 + docs/libcurl/curl_version_info.3 | 3 ++ docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 | 76 ++++++++++++++++++++++++++++ docs/libcurl/symbols-in-versions | 2 + 4 files changed, 83 insertions(+) create mode 100644 docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 (limited to 'docs/libcurl') diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index d79a42b04..71f681b70 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -187,6 +187,8 @@ Enable TCP keep-alive. See \fICURLOPT_TCP_KEEPALIVE(3)\fP Idle time before sending keep-alive. See \fICURLOPT_TCP_KEEPIDLE(3)\fP .IP CURLOPT_TCP_KEEPINTVL Interval between keep-alive probes. See \fICURLOPT_TCP_KEEPINTVL(3)\fP +.IP CURLOPT_UNIX_SOCKET_PATH +Path to a UNIX domain socket. See \fICURLOPT_UNIX_SOCKET_PATH(3)\fP .SH NAMES and PASSWORDS OPTIONS (Authentication) .IP CURLOPT_NETRC Enable .netrc parsing. See \fICURLOPT_NETRC(3)\fP diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3 index 3acf7851b..6e553463e 100644 --- a/docs/libcurl/curl_version_info.3 +++ b/docs/libcurl/curl_version_info.3 @@ -146,6 +146,9 @@ libcurl was built with support for NTLM delegation to a winbind helper. .IP CURL_VERSION_HTTP2 libcurl was built with support for HTTP2. (Added in 7.33.0) +.IP CURL_VERSION_UNIX_SOCKETS +libcurl was built with support for UNIX domain sockets. +(Added in 7.40.0) .RE \fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl has no SSL support, this is NULL. diff --git a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 new file mode 100644 index 000000000..880c2f71f --- /dev/null +++ b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 @@ -0,0 +1,76 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2014, 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 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. +.\" * +.\" ************************************************************************** +.\" +.TH CURLOPT_UNIX_SOCKET_PATH 3 "09 Oct 2014" "libcurl 7.40.0" "curl_easy_setopt options" +.SH NAME +CURLOPT_UNIX_SOCKET_PATH \- set UNIX domain socket +.SH SYNOPSIS +#include + +CURLcode curl_easy_setopt(CURL *handle, CURLOPT_UNIX_SOCKET_PATH, char *path); +.SH DESCRIPTION +Enables the use of UNIX domain sockets as connection end point and sets the path +to \fIpath\fP. If \fIpath\fP is NULL, then UNIX domain sockets are disabled. An +empty string will result in an error at some point. + +When enabled, cURL will connect to the UNIX domain socket instead of +establishing a TCP connection to a host. Since no TCP connection is established, +cURL does not need to resolve the DNS hostname in the URL. + +The maximum path length on Cygwin, Linux and Solaris is 107. On other platforms +might be even less. + +Proxy and TCP options such as +.BR CURLOPT_TCP_NODELAY "(3) +are not supported. Proxy options such as +.BR CURLOPT_PROXY "(3) +have no effect either as these are TCP-oriented, and asking a proxy server to +connect to a certain UNIX domain socket is not possible. +.SH DEFAULT +Default is NULL, meaning that no UNIX domain sockets are used. +.SH PROTOCOLS +All protocols except for file:// and FTP are supported in theory. HTTP, IMAP, +POP3 and SMTP should in particular work (including their SSL/TLS variants). +.SH EXAMPLE +Given that you have an nginx server running, listening on /tmp/nginx.sock, you +can request a HTTP resource with: + + curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, "/tmp/nginx.sock"); + curl_easy_setopt(curl_handle, CURLOPT_URL, "http://localhost/"); + +If you are on Linux and somehow have a need for paths larger than 107 bytes, you +could use the proc filesystem to bypass the limitation: + + int dirfd = open(long_directory_path_to_socket, O_DIRECTORY | O_RDONLY); + char path[108]; + snprintf(path, sizeof(path), "/proc/self/fd/%d/nginx.sock", dirfd); + curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, path); + /* Be sure to keep dirfd valid until you discard the handle */ + +.SH AVAILABILITY +Since 7.40.0. +.SH RETURN VALUE +Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not. +.SH "SEE ALSO" +.BR CURLOPT_OPENSOCKETFUNCTION "(3) +, +.BR unix "(7) diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 642cc19f4..b8b0838b0 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -529,6 +529,7 @@ CURLOPT_TLSAUTH_TYPE 7.21.4 CURLOPT_TLSAUTH_USERNAME 7.21.4 CURLOPT_TRANSFERTEXT 7.1.1 CURLOPT_TRANSFER_ENCODING 7.21.6 +CURLOPT_UNIX_SOCKET_PATH 7.40.0 CURLOPT_UNRESTRICTED_AUTH 7.10.4 CURLOPT_UPLOAD 7.1 CURLOPT_URL 7.1 @@ -749,6 +750,7 @@ CURL_VERSION_SPNEGO 7.10.8 CURL_VERSION_SSL 7.10 CURL_VERSION_SSPI 7.13.2 CURL_VERSION_TLSAUTH_SRP 7.21.4 +CURL_VERSION_UNIX_SOCKETS 7.40.0 CURL_WAIT_POLLIN 7.28.0 CURL_WAIT_POLLOUT 7.28.0 CURL_WAIT_POLLPRI 7.28.0 -- cgit v1.2.3