-
-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PHP 8.4] Add CURL_HTTP_VERSION_3(ONLY)
constants
#489
Conversation
9fb074e
to
a9e0756
Compare
Defining constants that cannot have effect would make the polyfilled case worse as it breaks feature detection without making the feature works. So -1 from me. |
Actually, passing the raw values does work. Curl accepts them (provided a recent enough version is installed). Only PHP doesn't expose these values as constants. |
Thank you for the reviews @derrabus @stof. @derrabus you are right that declaring Curl constants gives a false pretense that the feature is available. However, all of our constant declarations are only dependent on libcurl and PHP version numbers; They do not check the availability of those features. Recent additions include DoH and HSTS support. The constants are declared as long as the Curl extension is compiled with the minimum require version or later, but it does not guarantee those features are available. For HTTP/3, the version check php-src uses is whether libcurl is >= v7.66. While most setups will have the libcurl version, it will not have HTTP/3 support because as of now, default builds for libcurl do not come with HTTP/3 support (checked on Fedora, Ubuntu and Debian). Even without HTTP/3 support, PHP 8.4 will have these constants declared. Like @nicolas-grekas said, any PHP version can use HTTP/3 if built with support for it. curl_setopt($ch, CURLOPT_HTTP_VERSION, 30); // returns false if HTTP/3 is not supported. What the polyfill does is merely declare this as a proper constant. I think having this in the polyfill will can be helpful to avoid magic numbers. The technically correct way to check HTTP/3 availability would be:
That said, we cannot polyfill all Curl constants. We can't polyfill Curl options, but we should be able to polyfill Curl option values where they make sense. For example, we added |
Understood. But this PR ignores the libcurl version and the availability of ext-curl completely.
Let's look at how this is implemented in PHP: If I read that piece of code correctly, the answer to both questions should be no. But this is not what this PR implements. |
a9e0756
to
565f22e
Compare
Thank you for the pointers @nicolas-grekas @derrabus. I think you are right, it doesn't make sense to expose the constants on Curl < 7.66. I updated the PR to check for it and a
In my previous attempt, the bitmask check was to make sure Curl supports HTTP/3 with a |
src/Php84/bootstrap.php
Outdated
if (function_exists('curl_version') && curl_version()['version'] >= 0x074200) { // libcurl >= 7.66.0 | ||
define('CURL_HTTP_VERSION_3', 30); | ||
|
||
if (curl_version()['version'] >= 0x075800) { // libcurl >= 7.88.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit annoyed by this slow path, how about not doing the check and always declare the const next to the previous one?
Accuracy of the polyfilling on this aspect doesn't look more important than raw perf here to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the curl_version()
call really that expensive? 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Things add up: there are many polyfills to load: if we're not careful with each of them, this might make things slow without us realizing. For now, most (all?) checks are resolved at compile-time so they're free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the slowest call, but curl_version()
has a lot of information mostly by checking bitmasks for protocol and feature support. We only need the version here, so yeah I agree it makes sense to use something like defined('CURLOPT_UPLOAD_BUFFERSIZE')
that also implicitly ensures libcurl >= 7.62
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (curl_version()['version'] >= 0x075800) { // libcurl >= 7.88.0 | |
if (defined('CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256')) { // libcurl >= 7.80.0 (7.88 would be better but is slow to check) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
If the underlying Curl build supports it, setting the HTTP version should be theoretically possible. The availability of the constants do not guarantee the feature support, so declaring them in the polyfill should be same and effective. - PR that added constants: [php-src#15350](php/php-src#15350) - libcurl doc on `CURLOPT_HTTP_VERSION`](https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html) - [PHP.Watch: HTTP/3 Request with PHP Curl Extension](https://php.watch/articles/php-curl-http3) - Codex for [`CURL_HTTP_VERSION_3`](https://php.watch/codex/CURL_HTTP_VERSION_3) and [`CURL_HTTP_VERSION_3ONLY`](https://php.watch/codex/CURL_HTTP_VERSION_3ONLY) Fixes symfonyGH-488.
565f22e
to
8323493
Compare
Thank you @Ayesh. |
@@ -15,6 +15,14 @@ | |||
return; | |||
} | |||
|
|||
if (defined('CURL_VERSION_HTTP3') || PHP_VERSION_ID < 80200 && function_exists('curl_version') && curl_version()['version'] >= 0x074200) { // libcurl >= 7.66.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why PHP 8.2.0 as boundary ? the PR you linked was merged in 8.4-dev so we might need the polyfill on 8.2 or 8.3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
php/php-src#8720 this one is merged in 8.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but it does not add those constants. So we could be on PHP 8.2.12 or 8.3.5 with CURL_VERSION_HTTP3
not being defined and we would never enter this if
even if we have the latest libcurl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stof: If the CURL_VERSION_HTTP3
constant does not exist although we're on PHP 8.2, we know for sure that we either don't have ext-curl or the linked libcurl is too old, so we don't need to call curl_version()
anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this adds the constant if php is compiled with a recent enough version of curl
If the underlying Curl build supports it, setting the HTTP version should be theoretically possible. The availability of the constants do not guarantee the feature support, so declaring them in the polyfill should be same and effective.
CURLOPT_HTTP_VERSION
](https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html)CURL_HTTP_VERSION_3
andCURL_HTTP_VERSION_3ONLY
Fixes GH-488.