php-spx
php-spx copied to clipboard
SPX is not working in http mode
I always have 200 empty response on SPX web ui.
Here is a small video: https://www.youtube.com/watch?v=sK8ri8rYhZ4 I'm sure that the website is working and everything except static files is routed to php script. As you can see on the video, I can see the phpinfo output if the wrong key is provided. In case of the correct key, psx just silently dies (?).
Information
- Environment: Docker
- PHP image Dockerfile:
FROM php:7.3-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libicu-dev \
libxslt-dev \
libzip-dev \
curl \
vim \
git \
cron \
libssl-dev \
libgringotts-dev \
zip \
unzip \
--no-install-recommends && rm -r /var/lib/apt/lists/*
RUN service cron start
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) \
gd \
iconv \
mbstring \
opcache \
bcmath \
soap \
intl \
zip \
xsl \
pdo_mysql \
sockets
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN cd /tmp/ && git clone https://github.com/NoiseByNorthwest/php-spx.git && cd php-spx && phpize && ./configure && make && make install && echo "extension=spx.so" > /usr/local/etc/php/conf.d/spx.ini
RUN echo "spx.http_enabled=1\nspx.http_key=\"dev\"\nspx.http_ip_whitelist=\"*\"" >> /usr/local/etc/php/conf.d/spx.ini
WORKDIR /app
EXPOSE 9000
CMD ["php-fpm", "-R"]
- Nginx config from another container
upstream fastcgi_backend {
server app:9000;
}
upstream fastcgi_backend_xdebug {
server app-xdebug:9000;
}
map $cookie_XDEBUG_SESSION $fastcgi_backend_name {
"" "fastcgi_backend";
default "fastcgi_backend_xdebug";
}
server {
listen 80;
#server_name localhost;
set $MAGE_ROOT /app;
set $MAGE_MODE developer;
root $MAGE_ROOT/pub;
index index.php;
autoindex on;
charset off;
add_header test test;
add_header 'X-Content-Type-Options' 'nosniff';
add_header Access-Control-Allow-Origin *;
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP entry point for setup application
location ~* ^/setup($|/) {
root $MAGE_ROOT;
location ~ ^/setup/index.php {
fastcgi_pass fastcgi_backend;
fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off";
fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=600";
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/setup/(?!pub/). {
deny all;
}
location ~ ^/setup/pub/ {
add_header X-Frame-Options "SAMEORIGIN";
}
}
location /pub {
location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) {
deny all;
}
alias $MAGE_ROOT/pub;
add_header X-Frame-Options "SAMEORIGIN";
}
location /static/ {
if ($MAGE_MODE = "production") {
expires max;
}
# remove signature of static files used to overcome browser cache
location ~ ^/static/version {
rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
add_header Access-Control-Allow-Origin *;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
add_header test test;
add_header X-Frame-Options "SAMEORIGIN";
}
location /media/ {
try_files $uri $uri/ /get.php?$args;
location ~ ^/media/theme_customization/.*\.xml {
deny all;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
try_files $uri $uri/ /get.php?$args;
}
location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
try_files $uri $uri/ /get.php?$args;
}
add_header X-Frame-Options "SAMEORIGIN";
}
location /media/customer/ {
deny all;
}
location /media/downloadable/ {
deny all;
}
location /media/import/ {
deny all;
}
location ~ /media/theme_customization/.*\.xml$ {
deny all;
}
location /errors/ {
try_files $uri =404;
}
location ~ ^/errors/.*\.(xml|phtml)$ {
deny all;
}
location ~ cron\.php {
deny all;
}
location ~ (index|get|static|report|404|503)\.php$ {
try_files $uri =404;
add_header X-beckend $fastcgi_backend_name always;
fastcgi_pass $fastcgi_backend_name;
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
fastcgi_param MAGE_MODE $MAGE_MODE;
fastcgi_param fastcgi_backend $fastcgi_backend_name;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- Spx version 0.4.7
- Host OS: MacOS
Thanks for the video & the docker files. It sounds like the response has already been sent before the shutdown of the UI handler.
Can you try with the https://github.com/NoiseByNorthwest/php-spx/tree/debug_logs branch ? It adds some useful logs.
Can you also confirm me that the observed behavior is a 200 with an empty response body ? Can you show me the response headers ?
Hi, sure
Logs output:
[02-Mar-2020 16:52:01 UTC] PHP Notice: SPX: debug /tmp/php-spx/src/php_spx.c:http_ui_handler_init():762 in Unknown on line 0"
Response:
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Mon, 02 Mar 2020 16:53:53 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
Vary: Accept-Encoding
X-beckend: fastcgi_backend
Response body is empty
I checked the C file and seems like it's somehow related to ZTS. Here is some additional content from php -i | grep -i -E "thread|ZTS"
:
Thread Safety => disabled
extension_dir => /usr/local/lib/php/extensions/no-debug-non-zts-20180731 => /usr/local/lib/php/extensions/no-debug-non-zts-20180731
I checked the C file and seems like it's somehow related to ZTS.
SPX does not work when PHP is built with ZTS, it even cannot be built in ZTS mode. And as expeded your PHP build has a disabled ZTS.
Logs output:
Thanks, if there is only this log, this is a very weird situation because http_ui_handler_init
is called but http_ui_handler_shutdown
is never called. I will have to try your Dockerfile to go further.
curl -vvv 'http://host.perf/?SPX_KEY=perf&SPX_UI_URI=/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'DNT: 1' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' -H 'Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,uk;q=0.6' --compressed --insecure
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to host.perf (127.0.0.1) port 80 (#0)
> GET /?SPX_KEY=perf&SPX_UI_URI=/ HTTP/1.1
> Host: host.perf
> Accept-Encoding: deflate, gzip
> Connection: keep-alive
> Cache-Control: max-age=0
> DNT: 1
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
> Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,uk;q=0.6
>
< HTTP/1.1 200 OK
< Server: nginx/1.17.6
< Date: Wed, 18 Mar 2020 03:49:26 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Content-Encoding: gzip
< Vary: Accept-Encoding
< X-beckend: fastcgi_backend
<
* Error while processing content unencoding: invalid stored block lengths
* Failed writing data
* stopped the pause stream!
* Closing connection 0
curl: (23) Error while processing content unencoding: invalid stored block lengths
If I add zlib.output_compression = 0
then all works as expected
@NoiseByNorthwest Could this be added to the README? Took me a while to find this info, could help people in the future.
@Quazz yes, could you make the PR or at least paste me the diff you want to apply to the README ?
The PR: #186