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!