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

uwsgi + mod_apache_uwsgi + php plugin: issue with absolute PATH_INFO? #2666

Open
eirikrye opened this issue Sep 6, 2024 · 2 comments
Open

Comments

@eirikrye
Copy link

eirikrye commented Sep 6, 2024

Hello,

  • Debian 12
  • libapache-mod-proxy-uwsgi 2.4.62-1~deb12u1
  • uwsgi-core 2.0.21-5.1
  • uwsgi-plugin-php 2.0.21+4+0.0.15

I am having an issue with Apache using AddHandler to forward .php files to uwsgi through mod-proxy-uwsgi. All packages are the ones provided by Debian 12 bookworm.

/etc/apache/sites-enabled/test.conf:

<VirtualHost *:8000>
    ServerName localhost:8000
    DocumentRoot /home/test/www
    DirectoryIndex index.php
    AddHandler proxy:unix:/run/sockets/uwsgi.sock|uwsgi://localhost .php
</VirtualHost>

/etc/uwsgi/test.ini:

[uwsgi]
chdir = /home/test/www
plugins = php
remap-modifier = 14:0
php-index = index.php
socket = /run/sockets/uwsgi.sock
fastcgi-socket = /run/sockets/uwsgi-fcgi.sock

log-format = %(ftime) %(method) %(uri) %(status) %(var.SCRIPT_FILENAME) %(var.SCRIPT_NAME) %(var.PATH_INFO) %(var.PATH_TRANSLATED) %(var.CONTEXT_DOCUMENT_ROOT)

/home/test/www/index.php contains a test file. However, a request for http://localhost:8000/index.php fails with 404 Not Found (from uwsgi).

The request log, with the above format, returns this:

Sep 06 14:01:52 test uwsgi[50038]: 06/Sep/2024:14:01:52 +0200 GET /index.php 404 proxy:uwsgi://localhost/home/test/www/index.php /index.php /home/test/www/index.php - /home/test/www

In other words:

SCRIPT_FILENAME = proxy:uwsgi://localhost/home/test/www/index.php
SCRIPT_NAME = /index.php
PATH_INFO = /home/test/www/index.php
PATH_TRANSLATED = -
CONTEXT_DOCUMENT_ROOT = /home/test/www

However, everything works fine if I switch Apache to use FastCGI through the fastcgi-socket provided by uwsgi, and overriding PATH_INFO, with the following changes to the Apache config above:

ProxyFCGISetEnvIf "true" PATH_INFO "%{reqenv:SCRIPT_NAME}"
AddHandler proxy:unix:/run/sockets/uwsgi-fcgi.sock|fcgi://localhost .php

Log line produced:

Sep 06 14:01:54 test uwsgi[50038]: 06/Sep/2024:14:01:54 +0200 GET /index.php 200 proxy:fcgi://localhost/home/test/www/index.php /index.php /index.php - /home/test/www
SCRIPT_FILENAME = proxy:fcgi://localhost/home/test/www/index.php
SCRIPT_NAME = /index.php
PATH_INFO = /index.php
PATH_TRANSLATED = -
CONTEXT_DOCUMENT_ROOT = /home/test/www

The only difference I can see in the passed variables is that when using mod-proxy-uwsgi, PATH_INFO is passed as an absolute path and not a path relative to the document root, as is done for FCGI due to my PATH_INFO override above.

Apparently, uwsgi expects PATH_INFO to be relative to CONTEXT_DOCUMENT_ROOT. An strace shows this:

newfstatat(AT_FDCWD, "/home/test/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/home/test/www/home", 0x7ffc9ae360a0, 0) = -1 ENOENT (No such file or directory)
writev(8, [{iov_base="HTTP/1.1 404 Not Found\r\nConnecti"..., iov_len=71}, {iov_base="Not Found", iov_len=9}], 2) = 80

(It stops when it encounters the non-existant directory /home/test/www/home)

My question is, is there a way to either make uwsgi properly handle the absolute path in PATH_INFO, or alternatively have Apache send the relative PATH_INFO when using the mod_proxy_uwsgi module?

I've tried doing SetEnv / SetEnvIf to set PATH_INFO(similar to the ProxyFCGISetEnvIf above), but this appears to be ignored. I've also tried setting manage-script-name = true in uwsgi.ini, with no effect.

uwsgi does work fine when using ProxyPass, but this is not an adequate solution for us. We only want proxying to uwsgi for files, not locations, and to happen after Apache rewrites.

@niol
Copy link
Contributor

niol commented Sep 6, 2024

I've been working around this for years with:

$ cat /etc/uwsgi/apps-available/reader.ini
[uwsgi]
[...]
# workaround uwsgi-plugin-php cannot set SCRIPT_NAME
php-set = auto_prepend_file=/etc/uwsgi/apps-available/reader.prepend.php
$ cat /etc/uwsgi/apps-available/reader.prepend.php
<?php
 $_SERVER['SCRIPT_NAME'] = '/r/index.php';
?>

Maybe related to #1616 and #1278. Never got into fixing it.

@eirikrye
Copy link
Author

eirikrye commented Sep 6, 2024

@niol I don't think we're talking about the same issue. auto_prepend_file would never come into play in my case as uwsgi never gets to the point of invoking the PHP subsystem.

From what I can tell, for my specific case, the uwsgi PHP plugin fails because of this concatenation of document_root and path_info:

filename = uwsgi_concat4n(wsgi_req->document_root, wsgi_req->document_root_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len, "", 0);

In my case, this produces filename = /home/test/www/home/test/www/index.php, because

wsgi_req->document_root = /home/test/www
wsgi_req->path_info = /home/test/www/index.php

which in turn causes uwsgi_php_walk() to fail when traversing the path, when it eventually encounters the non-existant path /home/test/www/home.

if (uwsgi_php_walk(wsgi_req, filename, wsgi_req->document_root, wsgi_req->document_root_len, &path_info)) {

I'm unfortunately not versed enough in the realm of CGI/WSGI/uwsgi to determine which part of the chain is "at fault" here, be it the Apache module or the PHP plugin, or maybe Apache itself.

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

No branches or pull requests

2 participants