Skip to content

ext/curl: Add CURLOPT_OPENSOCKETFUNCTION - #25410

Closed
nicolas-grekas wants to merge 1 commit into
php:masterfrom
nicolas-grekas:curl-opensocketfunction
Closed

nicolas-grekas wants to merge 1 commit into
php:masterfrom
nicolas-grekas:curl-opensocketfunction

Conversation

@nicolas-grekas

Copy link
Copy Markdown
Contributor

This is an alternative to #23657, following the discussion there.

curl_setopt($ch, CURLOPT_OPENSOCKETFUNCTION, function (CurlHandle $handle, string $address, int $port): bool {
    return false !== filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
});

The callback is called before connect(), so it can block requests to internal addresses. CURLOPT_PREREQFUNCTION can't do that because it's called once the connection is made.

This uses the libcurl option as suggested by @arnaud-lb, but the callback returns a bool instead of a socket. true lets libcurl create the socket, false makes libcurl try the next address. Returning a socket can be added later by widening the return type, and more arguments can be added at the end.

A UNIX socket is reported as its path with port 0, the same as CURLOPT_PREREQFUNCTION and CURLINFO_PRIMARY_IP do. There's no address family enum, since the address is enough to tell IPv4, IPv6 and UNIX sockets apart.

The commit is authored by @xavierleune since it reuses most of the code and tests of #23657.

/cc @bukka @TimWolla

The callback is called after DNS resolution and before connect(), with the
address and the port libcurl is about to connect to. Returning true lets
libcurl create the socket, returning false refuses the address.

This makes it possible to block requests to internal addresses before any
connection is made, which CURLOPT_PREREQFUNCTION can't do.
@nicolas-grekas
nicolas-grekas force-pushed the curl-opensocketfunction branch from 36b4322 to 96fd568 Compare November 12, 2026 11:27
@nicolas-grekas

Copy link
Copy Markdown
Contributor Author

Let me close in favor of #25414, which now has the same signature.

xavierleune added a commit to xavierleune/php-src that referenced this pull request Nov 12, 2026
…n exception

An exception thrown after the callback returned true, e.g. by a destructor,
left both true and a pending exception, so the socket was still created.

Also take the test that refusing an address makes libcurl try the next one
from php#25410.
xavierleune added a commit to xavierleune/php-src that referenced this pull request Nov 12, 2026
…n exception

An exception thrown after the callback returned true, e.g. by a destructor,
left both true and a pending exception, so the socket was still created.

Also take the test that refusing an address makes libcurl try the next one
from php#25410.

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants