amphp / http-server

An advanced async HTTP server library for PHP, perfect for real-time apps and APIs with high concurrency demands.

Home Page:https://amphp.org/http-server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HTTP2 upgrade seems not working with version beta

glickel opened this issue · comments

Hello, I think I faced an issue while playing with the version beta.
I tried to upgrade a little http-server from version 2 to version beta. After that, using curl with HTTP2 option does not return the response body and take a lot of time.

Here are the code and curl calls examples, from version 2 that works to version beta that does not work. If it's not a real issue, then can you say me what I did wrong please ?

Success example with version 2

Code

<?php

use Amp\ByteStream\ResourceOutputStream;
use Amp\Http\Server\HttpServer;
use Amp\Http\Server\Options;
use Amp\Http\Server\RequestHandler\CallableRequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Status;
use Amp\Log\ConsoleFormatter;
use Amp\Log\StreamHandler;
use Amp\Loop;
use Amp\Socket\Server;
use Monolog\Logger;
use Monolog\Processor\PsrLogMessageProcessor;

require_once __DIR__ . '/vendor/autoload.php';

$logHandler = new StreamHandler(new ResourceOutputStream(STDOUT));
$logHandler->pushProcessor(new PsrLogMessageProcessor());
$logHandler->setFormatter(new ConsoleFormatter());
$logger = new Logger('server');
$logger->pushHandler($logHandler);

$server = new HttpServer(
    [Server::listen('0.0.0.0:1337')],
    new CallableRequestHandler(fn () =>  new Response(Status::OK, stringOrStream: "test\n")),
    $logger,
    (new Options())->withHttp2Upgrade(),
);

Loop::run(function () use ($server) {
    yield $server->start();

    Loop::onSignal(SIGINT, function (string $watcherId) use ($server) {
        Loop::cancel($watcherId);
        yield $server->stop();
    });
});

Curl without HTTP2

time curl http://localhost:1337 -vvv

*   Trying 127.0.0.1:1337...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1337 (#0)
> GET / HTTP/1.1
> Host: localhost:1337
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 5
< connection: keep-alive
< keep-alive: timeout=15
< date: Mon, 09 May 2022 13:01:26 GMT
<
test
* Connection #0 to host localhost left intact

real    0m0.008s
user    0m0.004s
sys     0m0.000s

Curl with HTTP2

time curl --http2 http://localhost:1337 -vvv

*   Trying 127.0.0.1:1337...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1337 (#0)
> GET / HTTP/1.1
> Host: localhost:1337
> User-Agent: curl/7.68.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 101 Switching Protocols
< connection: upgrade
< upgrade: h2c
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 200
< content-length: 5
< date: Mon, 09 May 2022 13:02:32 GMT
<
test
* Connection #0 to host localhost left intact

real    0m0.073s
user    0m0.004s
sys     0m0.000s

Fail example with version beta

Code

<?php

use Amp\Http\Server\DefaultErrorHandler;
use Amp\Http\Server\Driver\DefaultHttpDriverFactory;
use Amp\Http\Server\Driver\SocketClientFactory;
use Amp\Http\Server\RequestHandler\ClosureRequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Server\SocketHttpServer;
use Amp\Http\Status;
use Amp\Log\ConsoleFormatter;
use Amp\Log\StreamHandler;
use Amp\Socket\InternetAddress;
use Amp\Socket\ResourceSocketServerFactory;
use Monolog\Logger;
use Monolog\Processor\PsrLogMessageProcessor;
use function Amp\ByteStream\getStdout;
use function Amp\trapSignal;

require_once __DIR__ . '/vendor/autoload.php';

$logHandler = new StreamHandler(getStdout());
$logHandler->pushProcessor(new PsrLogMessageProcessor());
$logHandler->setFormatter(new ConsoleFormatter());
$logger = new Logger('server');
$logger->pushHandler($logHandler);

$server = new SocketHttpServer(
    $logger,
    new ResourceSocketServerFactory(),
    new SocketClientFactory($logger),
    new DefaultHttpDriverFactory($logger, allowHttp2Upgrade: true),
);

$server->expose(new InternetAddress('0.0.0.0', 1337));

$server->start(
    new ClosureRequestHandler(fn () =>  new Response(Status::OK, body: "test\n")),
    new DefaultErrorHandler(),
);

trapSignal([SIGINT, SIGTERM]);

$server->stop();

Curl without HTTP2

time curl http://localhost:1337 -vvv

*   Trying 127.0.0.1:1337...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1337 (#0)
> GET / HTTP/1.1
> Host: localhost:1337
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 5
< connection: keep-alive
< keep-alive: timeout=15
< date: Mon, 09 May 2022 13:05:49 GMT
<
test
* Connection #0 to host localhost left intact

real    0m0.009s
user    0m0.000s
sys     0m0.004s

Curl with HTTP2

time curl --http2 http://localhost:1337 -vvv

*   Trying 127.0.0.1:1337...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1337 (#0)
> GET / HTTP/1.1
> Host: localhost:1337
> User-Agent: curl/7.68.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 101 Switching Protocols
< connection: upgrade
< upgrade: h2c
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server

real    0m15.088s
user    0m0.004s
sys     0m0.000s

Thanks for reporting this @glickel! I pushed a fix to the v3 branch, can you pull it and let me know if that fixes the issue for you as well?

Yes it works well on my part now @trowski , thank you!

@glickel you may now close this issue. @trowski a new release of the beta would be nice 😊 .