dunglas / frankenphp

🧟 The modern PHP app server
https://frankenphp.dev
MIT License
6.93k stars 241 forks source link

Shared request headers between different requests #617

Closed CvekCoding closed 6 months ago

CvekCoding commented 8 months ago

What happened?

In Worker mode, I ran into the problem that the context is shared between different requests - it looks like the headers of the previous request remain in the context and are used in the next request. In particular, the Authorization header - a new request has arrived on the server, and the code continues to work with the Authorizztion's value of previous one. As soon as I turn off the worker mode, everything starts working correctly.

I have a pretty standard installation: Symfony 6.4 + lexikjwt.

What can you suggest me? Thanks.

Build Type

Docker (Alpine)

Worker Mode

Yes

Operating System

GNU/Linux

CPU Architecture

x86_64

PHP configuration


phpinfo()
PHP Version => 8.3.3

System => Linux b99862c56d40 5.4.0-26-generic #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020 x86_64
Build Date => Feb 16 2024 21:32:51
Build System => Linux - Docker
Build Provider => https://github.com/docker-library/php
Configure Command =>  './configure'  '--build=x86_64-linux-musl' '--with-config-file-path=/usr/local/etc/php' '--with-config-file-scan-dir=/usr/local/etc/php/conf.d' '--enable-option-checking=fatal' '--with-mhash' '--with-pic' '--enable-mbstring' '--enable-mysqlnd' '--with-password-argon2' '--with-sodium=shared' '--with-pdo-sqlite=/usr' '--with-sqlite3=/usr' '--with-curl' '--with-iconv=/usr' '--with-openssl' '--with-readline' '--with-zlib' '--enable-phpdbg' '--enable-phpdbg-readline' '--with-pear' '--enable-embed' '--enable-zts' '--disable-zend-signals' 'build_alias=x86_64-linux-musl'
Server API => Command Line Interface
Virtual Directory Support => enabled
Configuration File (php.ini) Path => /usr/local/etc/php
Loaded Configuration File => /usr/local/etc/php/php.ini
Scan this dir for additional .ini files => /usr/local/etc/php/conf.d
Additional .ini files parsed => /usr/local/etc/php/conf.d/app.ini,
/usr/local/etc/php/conf.d/app.prod.ini,
/usr/local/etc/php/conf.d/docker-php-ext-amqp.ini,
/usr/local/etc/php/conf.d/docker-php-ext-apcu.ini,
/usr/local/etc/php/conf.d/docker-php-ext-bcmath.ini,
/usr/local/etc/php/conf.d/docker-php-ext-intl.ini,
/usr/local/etc/php/conf.d/docker-php-ext-opcache.ini,
/usr/local/etc/php/conf.d/docker-php-ext-pdo_pgsql.ini,
/usr/local/etc/php/conf.d/docker-php-ext-sodium.ini,
/usr/local/etc/php/conf.d/docker-php-ext-zip.ini

PHP API => 20230831
PHP Extension => 20230831
Zend Extension => 420230831
Zend Extension Build => API420230831,TS
PHP Extension Build => API20230831,TS
Debug Build => no
Thread Safety => enabled
Thread API => POSIX Threads
Zend Signal Handling => disabled
Zend Memory Manager => enabled
Zend Multibyte Support => provided by mbstring
Zend Max Execution Timers => enabled
IPv6 Support => enabled
DTrace Support => disabled

Registered PHP Streams => https, ftps, compress.zlib, php, file, glob, data, http, ftp, phar, zip
Registered Stream Socket Transports => tcp, udp, unix, udg, ssl, tls, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3
Registered Stream Filters => zlib.*, convert.iconv.*, string.rot13, string.toupper, string.tolower, convert.*, consumed, dechunk

This program makes use of the Zend Scripting Language Engine:
Zend Engine v4.3.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.3, Copyright (c), by Zend Technologies
dunglas commented 8 months ago

I tried to reproduce the issue but everything works as expected: https://github.com/dunglas/frankenphp-demo/compare/chore/reproducer-authorization?expand=1

Could you please edit this patch to provide a minimal reproducer?

CvekCoding commented 8 months ago

I'll try to reproduce it, thanks

Rainrider commented 8 months ago

I had similar experience with a similar setup - strange behaviour with 401 responses just after sucessful login. This was not reliably reproducable and only occured after the instance has run for some time.

Could it be some cache related issue in Symfony (https://github.com/symfony/symfony/pull/52079 mentions some left over work for cache in long running processes)?

dunglas commented 8 months ago

I don't see how it can relate to cache issues but it's hard to tell without a reproducer. Do you use the PHP cache proxy provided by Symfony or something like that?

Rainrider commented 8 months ago

Do you use the PHP cache proxy provided by Symfony or something like that?

The one provided by Symfony, yes. We use remote keys sets for JWT verification and we cache the sets locally (cache.app pool), but those just can't be the problem, as they would have been re-fetched on cache miss and the keys were not rotated when the issue occured. I also did not see any hits on the JWK server in that time frame, which would also indicate it is not cache related. Sadly I don't have a reproducer yet :(

filoucrackeur commented 7 months ago

Hi @dunglas i have the same problem maybe like on apache where we must add set-env Authorization *() HTTP_AUTORIZATION ?did it is not needed on caddy ?

What do you think?

dunglas commented 7 months ago

@filoucrackeur it's unlikely. Would you be able to provide a reproducer (even if it happens randomly)?

oleg-andreyev commented 7 months ago

I'm observing something similar, leak between workers or something. If I try to xdebug it only 3rd request in getting connected to IDE.

https://github.com/dunglas/frankenphp/assets/1244112/03245b58-cde3-49b9-92c3-f10d700fddda

It looks like some cache, because process is not connecting to IDE, and if could cache ignore QS?

dunglas commented 7 months ago

This looks like a known EasyAdmin bug. Are you using EA?

It yes, this is an issue that is being tracked by EasyAdmin. There is nothing we can do on our side: https://github.com/EasyCorp/EasyAdminBundle/issues/5986

We're working with @javiereguiluz to solve it. I plan to work on it soon but not ETA :(

oleg-andreyev commented 7 months ago

@dunglas yes, it's EA, from what I've observed EasyAdminTwigExtension is not called, thus not setting ea variable, extension is not called because \Twig\ExtensionSet::getGlobals is not executed - probably due to $initialized = true so maybe it's actually a Twig issue

Looks like a valid "solution": https://github.com/EasyCorp/EasyAdminBundle/issues/5986#issuecomment-1999794853

javiereguiluz commented 7 months ago

@oleg-andreyev please note that even if this issue happens in EasyAdmin ... it not only happens in EasyAdmin. Some people are reporting the same issue when using Shopware and FrankenPHP and for the exact same reason: Twig globals.

Let's see if this can be solved at Twig level somehow. See https://github.com/twigphp/Twig/issues/4007

oleg-andreyev commented 7 months ago

@javiereguiluz Yes, already figured out that it's not EA itself .

dunglas commented 6 months ago

Closing here, this should be fixed in EasyAdmin/ShopWare or/and in Twig.