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

开启 HTTP2 时,$request->server['request_method'] 与 $request->getMethod() 的结果不一致。 #5400

Closed
pinerge opened this issue Jul 8, 2024 · 3 comments

Comments

@pinerge
Copy link

pinerge commented Jul 8, 2024

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error.

一个简单的 HTTP 服务,提交一个 POST 表单。

// ...
var_dump($request->server['request_method']); // string(4) "POST"
var_dump($request->getMethod()); // string(6) "DELETE"
// ...
  1. What did you expect to see?

  2. What did you see instead?

  3. What version of Swoole are you using (show your php --ri swoole)?

root@debian:~/realm# php --ri swoole

swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 6.0.0-dev
Built => Jul  7 2024 11:11:45
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 3.0.13 30 Jan 2024
dtls => enabled
http2 => enabled
json => enabled
zlib => 1.2.13
brotli => E16777225/D16777225
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
coroutine_pgsql => enabled

Directive => Local Value => Master Value
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
root@debian:~/realm# uname -a
Linux debian 6.1.0-22-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.94-1 (2024-06-21) x86_64 GNU/Linux
root@debian:~/realm# php -v
PHP 8.3.9 (cli) (built: Jul  7 2024 11:04:43) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.9, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.9, Copyright (c), by Zend Technologies
root@debian:~/realm# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 12.2.0-14' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (Debian 12.2.0-14)
@jingjingxyk
Copy link
Contributor

jingjingxyk commented Jul 9, 2024

如何复现?

我是这么验证的, 复现不了这种情况

  1. 准备包含 swoole v6 的运行时
  2. 准备服务端
  3. 准备客户顿啊

准备包含swoole v6 的 swoole-cli

curl https://github.com/jingjingxyk/swoole-cli/blob/new_dev/setup-swoole-cli-pre-runtime.sh?raw=true | bash 

./bin/runtime/php -v

准备域名

vi /etc/hosts
::1           http2-test.jingjingxyk.com

准备服务端

<?php

use Swoole\Coroutine\Http\Server;

use function Swoole\Coroutine\run;

run(function () {
    $server = new Server('::', 9502, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL);
    $TLS_DIR = __DIR__;
    $server->set([
        'open_http2_protocol' => true,
        'http2_enable_push' => 0x2,
        'ssl_cert_file' => $TLS_DIR . '/wildcard.jingjingxyk.com.fullchain.pem',
        'ssl_key_file' => $TLS_DIR . '/wildcard.jingjingxyk.com.key.pem',
        'ssl_cafile' => __DIR__ . '/bin/runtime/cacert.pem',
        'ssl_verify_peer' => true,
        'ssl_protocols' => SWOOLE_SSL_TLSv1_3,
        'log_level' => SWOOLE_LOG_TRACE,
        'trace_flags' => SWOOLE_TRACE_ALL
    ]);
    $server->handle('/', function ($request, $response) {
        //var_dump($request);
        var_dump($request->server['request_method']);
        var_dump($request->getMethod());
        $response->end("<h1>Index</h1>");
    });

    $server->handle('/api', function ($request, $response) {
        //var_dump($request);
        var_dump($request->server['request_method']);
        var_dump($request->getMethod());
        $response->end(json_encode($request, JSON_UNESCAPED_UNICODE));
    });

    $server->handle('/stop', function ($request, $response) use ($server) {
        $response->end("<h1>Stop</h1>");
        $server->shutdown();
    });
    $server->start();
});

客户端

<?php
use Swoole\Http2\Request;
use Swoole\Coroutine\Http2\Client;
use function Swoole\Coroutine\run;

run(function () {
    $domain = 'http2-test.jingjingxyk.com';
    $cli = new Client($domain, 9502, true);
    $cli->set([
        'timeout' => -1,
        'ssl_host_name' => $domain
    ]);
    $cli->connect();
    $req = new Request();
    $req->method = 'POST';
    $req->path = '/api';
    $req->headers = [
        'host' => $domain,
        'user-agent' => 'Chrome/49.0.2587.3',
        'accept' => 'text/html,application/xhtml+xml,application/xml',
        'accept-encoding' => 'gzip'
    ];
    $req->data = '{"type":"up"}';
    $cli->send($req);
    $response = $cli->recv();
    var_dump(json_decode($response->data));
});

@jyunwaa
Copy link

jyunwaa commented Jul 9, 2024

如何复现?

我是这么验证的, 复现不了这种情况

1. 准备包含 swoole v6 的运行时

2. 准备服务端

3. 准备客户顿啊

准备包含swoole v6 的 swoole-cli

curl https://github.com/jingjingxyk/swoole-cli/blob/new_dev/setup-swoole-cli-pre-runtime.sh?raw=true | bash 

./bin/runtime/php -v

准备域名

vi /etc/hosts
::1           http2-test.jingjingxyk.com

准备服务端

<?php

use Swoole\Coroutine\Http\Server;

use function Swoole\Coroutine\run;

run(function () {
    $server = new Server('::', 9502, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL);
    $TLS_DIR = __DIR__;
    $server->set([
        'open_http2_protocol' => true,
        'http2_enable_push' => 0x2,
        'ssl_cert_file' => $TLS_DIR . '/wildcard.jingjingxyk.com.fullchain.pem',
        'ssl_key_file' => $TLS_DIR . '/wildcard.jingjingxyk.com.key.pem',
        'ssl_cafile' => __DIR__ . '/bin/runtime/cacert.pem',
        'ssl_verify_peer' => true,
        'ssl_protocols' => SWOOLE_SSL_TLSv1_3,
        'log_level' => SWOOLE_LOG_TRACE,
        'trace_flags' => SWOOLE_TRACE_ALL
    ]);
    $server->handle('/', function ($request, $response) {
        //var_dump($request);
        var_dump($request->server['request_method']);
        var_dump($request->getMethod());
        $response->end("<h1>Index</h1>");
    });

    $server->handle('/api', function ($request, $response) {
        //var_dump($request);
        var_dump($request->server['request_method']);
        var_dump($request->getMethod());
        $response->end(json_encode($request, JSON_UNESCAPED_UNICODE));
    });

    $server->handle('/stop', function ($request, $response) use ($server) {
        $response->end("<h1>Stop</h1>");
        $server->shutdown();
    });
    $server->start();
});

客户端

<?php
use Swoole\Http2\Request;
use Swoole\Coroutine\Http2\Client;
use function Swoole\Coroutine\run;

run(function () {
    $domain = 'http2-test.jingjingxyk.com';
    $cli = new Client($domain, 9502, true);
    $cli->set([
        'timeout' => -1,
        'ssl_host_name' => $domain
    ]);
    $cli->connect();
    $req = new Request();
    $req->method = 'POST';
    $req->path = '/api';
    $req->headers = [
        'host' => $domain,
        'user-agent' => 'Chrome/49.0.2587.3',
        'accept' => 'text/html,application/xhtml+xml,application/xml',
        'accept-encoding' => 'gzip'
    ];
    $req->data = '{"type":"up"}';
    $cli->send($req);
    $response = $cli->recv();
    var_dump(json_decode($response->data));
});

server.php
<?php
declare(strict_types=1);

use Swoole\Coroutine;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;

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

Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL]);

$server = new Server('::', 443, SWOOLE_BASE, SWOOLE_SOCK_TCP6 | SWOOLE_SSL);

$server->set([
    'reactor_num'         => 1,
    'worker_num'          => 1,
    'ssl_cert_file'       => __DIR__ . '/../src/Resources/Ssl/realm.closure.cyou_bundle.crt',
    'ssl_key_file'        => __DIR__ . '/../src/Resources/Ssl/realm.closure.cyou.key',
    'open_http2_protocol' => true,
]);

$server->on('request', function (Request $request, Response $response) {
    $request_method = $request->server['request_method'];
    $getMethod = $request->getMethod();
    $response->end(json_encode(compact('request_method', 'getMethod'), JSON_PRETTY_PRINT) . "\n");
});

$server->start();
curl
root@debian:~/realm/tests# curl --http2 https://realm.closure.cyou/ -v
*   Trying [2409:8a60:1285:4f30:20c:29ff:fe7f:abec]:443...
* Connected to realm.closure.cyou (2409:8a60:1285:4f30:20c:29ff:fe7f:abec) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=realm.closure.cyou
*  start date: Jul  2 00:00:00 2024 GMT
*  expire date: Sep 30 23:59:59 2024 GMT
*  subjectAltName: host "realm.closure.cyou" matched cert's "realm.closure.cyou"
*  issuer: C=CN; O=TrustAsia Technologies, Inc.; CN=TrustAsia RSA DV TLS CA G2
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: realm.closure.cyou]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x558e5d676ce0)
> GET / HTTP/2
> Host: realm.closure.cyou
> user-agent: curl/7.88.1
> accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 200 
< server: swoole-http-server
< date: Tue, 09 Jul 2024 16:30:40 GMT
< content-type: text/html
< content-length: 59
< 
{
    "request_method": "GET",
    "getMethod": "DELETE"
}
* Connection #0 to host realm.closure.cyou left intact
root@debian:~/realm/tests# 

@jingjingxyk
Copy link
Contributor

已复现
image

image

matyhtf added a commit that referenced this issue Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants