Skip to content
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

$_SERVER['HTTP_HOST'] doesn't exist when requesting via HTTP/3 on nginx #13021

Closed
LIXiangChen opened this issue Dec 25, 2023 · 10 comments
Closed

Comments

@LIXiangChen
Copy link

Description

I'm using nginx 1.25.3 + PHP 8.3.0.

When requesting via HTTP/2, I can get $_SERVER['HTTP_HOST'] correctly. But when requesting via HTTP/3, HTTP_HOST doesn't exist in the array.

Will PHP officially fix this? Is there any other solution besides replacing HTTP_HOST with SERVER_NAME?

PHP Version

PHP 8.3.0

Operating System

Debian 12.2 64-bit

@LIXiangChen LIXiangChen changed the title $_SERVER['HTTP_HOST'] doesn't exist when requesting via HTTP/3 on _nginx_ $_SERVER['HTTP_HOST'] doesn't exist when requesting via HTTP/3 on nginx Dec 25, 2023
@nielsdos
Copy link
Member

Seems to be an issue on nginx's side, see nginx-quic/nginx-quic#3
But I'm not a SAPI expert, so deferring to someone else.

@staabm
Copy link
Contributor

staabm commented Dec 26, 2023

There is a trac ticket linked from above mentioned github issue, which is resolved as "invalid"

https://trac.nginx.org/nginx/ticket/2281

(I am no sapi expert either ;))

@devnexen
Copy link
Member

Seems to be an issue on nginx's side, see nginx-quic/nginx-quic#3

This is not a php issue indeed, but let's leave it open for a while once other folks come back from holidays.

@TimWolla
Copy link
Member

TimWolla commented Dec 26, 2023

Is there any other solution besides replacing HTTP_HOST with SERVER_NAME?

Please note that this is not a solution at all: SERVER_NAME generally speaking is a lie, because it has no relation whatsoever with the actual contents of the HTTP request you're dealing with (at least when dealing with nginx / nginx' $server_name variable, from the CGI spec, SERVER_NAME is in fact a correct value to obtain the request's authority).


Unless nginx starts providing the request's authority as the HTTP_HOST CGI parameter by default, the correct solution is to add fastcgi_param HTTP_HOST $host; to your nginx configuration.

@LIXiangChen
Copy link
Author

LIXiangChen commented Dec 27, 2023

Please note that this is not a solution at all: SERVER_NAME generally speaking is a lie, because it has no relation whatsoever with the actual contents of the HTTP request you're dealing with…

Yes, I understand that. Precisely because SERVER_NAME doesn't help with this matter, I said it directly in the original post to avoid anyone answering this "solution".


Now it seems that nginx doesn't want to change this, but recommends using $host, so if website developers need to get the host, they can only manually add fastcgi_param xxx $host; to nginx config forever? Is there nothing PHP can do about this?

@TimWolla
Copy link
Member

TimWolla commented Dec 27, 2023

Is there nothing PHP can do about this?

By default nginx only provides the request headers to PHP, without using fastcgi_param (possibly via the default /etc/nginx/fastcgi_params config file), not even the script name is provided to PHP.

In other words: PHP can only work with the data nginx provides to it.

You might or might not be able to convince the nginx team to change fastcgi_param SERVER_NAME $server_name; to fastcgi_param SERVER_NAME $host; in their default version of fastcgi_params. According to my understanding of RFC 3875#4.1.14 this would be the more correct value:

In that case, the server would use the contents of the request's Host
header field to select the correct virtual host.

This would require you to change your script to make use of the SERVER_NAME variable, though.

@bukka
Copy link
Member

bukka commented Jan 12, 2024

So as it was said, FPM does not get any info from nginx and most clients won't send Host header with HTTP/3 but instead the :authority: is set so using HTTP_HOST is not reliable for HTTP/3.

I think ideally you should set REMOTE_HOST and use that instead. I think it would be reasonable to have fastcgi_param REMOTE_HOST $host; in the default fastcgi_params config. It might be worth to submit such patch to nginx to see what they think about such addition. Currently the only way to get host is really just from HTTP_HOST if one uses default fastcgi_params config and not HTTP/3.

We could potentially add small change to FPM to take REMOTE_HOST from HTTP_HOST if not set. That would make it more usable for configuration using HTTP/1.1 and HTTP/2. I just checked and we already deal with some headers and changing some other variable so this wouldn't be anything special and pretty easy to do.

@bukka
Copy link
Member

bukka commented Jan 12, 2024

Ok so I just sent a patch to nginx-devel so will see what they think: https://mailman.nginx.org/pipermail/nginx-devel/2024-January/3CQEHII5QU2BTQ7L7DAVCBWK3OQS3GU6.html

@bukka
Copy link
Member

bukka commented Mar 8, 2024

Forgot to send update here. So this was not such a good idea at the end as REMOTE_HOST has a different meaning and it's more a legacy things so not good for this.

Considering https://mailman.nginx.org/pipermail/nginx-devel/2024-January/LCIUMLKCM2EBMEMTU3KXMW74AP2C4FYZ.html , nginx does it (emulates host header) already for HTTP/2 so the best solution would be if they did for HTTP/3 as well. There's nothing we can do on PHP side so closing this.

@bukka bukka closed this as completed Mar 8, 2024
@LIXiangChen
Copy link
Author

Thank you for communicating with the nginx staff. Looking forward to changes in nginx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants