使用HTTP/2时,Cro如何获取Host或:authority头信息

8
当使用Cro和HTTP1.1时,我可以通过Cro::Uri中的host方法request.uri.host以及浏览器通过Cro::HTTP::Request中的request.header方法发送的Host或:authority头来访问请求的主机。然而,当我使用HTTP/2时,这些都不起作用。Uri对象只包含模式和路径。我正在使用一个带有子域名通配符的官方证书,并通过将这些子域名添加到我的hosts文件中在本地运行。Chrome DevTools表示已在HTTP/2下发送了:authority请求头,Firefox Developer Tools表示已在HTTP/2下发送了Host请求头。但是,如果我像下面这样将标头写入日志,我会看到几个标头,但没有Host或:authority标头。
sub routes() is export {
  route {
    get -> {
      my $log = "/data/myapp/logs/cro.log";
      my $fh = open $log, :w;
      my $host = request.uri.host;
      $fh.say( "Host with host method: " ~ $host );
      $host = request.header('Host');
      $fh.say( "Host: " ~ $host );
      $host = request.header(':authority');
      $fh.say(":authority: " ~ $host );
      $fh.say( "Request headers:" );
      for request.headers {
        $fh.say( "{.name}: {.value}" );
      }
      $fh.close;
      content 'text/html', "<h1> MyApp </h1><p>Running";
    }
  }
}

我知道HTTP/2 使用 服务器名称指示,主机名作为TLS协商的一部分发送。另一方面,这也是 Cro 模块(Cro::TLS)的一部分,并且浏览器仍然发送头信息。
那么在HTTP/2下如何获取主机名呢?
1个回答

8

这似乎是一个简单的漏洞(与Raiph命名的漏洞无关)。

我编写了一个补丁并发送了一个PR(https://github.com/croservices/cro-http/pull/104)。一旦合并,您可以更新您的Cro :: HTTP分发版本,并使用两种方式指定(request.uri构建或请求header('Host')),两种方式都将起作用。


1
嗨@Takao。很高兴看到Cro在经过beta 0.8系列的稳步成熟后,最终将在一年或两年内达到1.0版本。我很好奇你采取了什么调试方法(插入一些say语句?),以及你是否基本上是通过了解相关协议和Cro源代码来猜测问题的?是否有一个很好的单一链接,可以概述一般情况下如何调试Cro问题,特别是http问题?(如果没有,您可能会有任何快速评论。) - raiph
3
我的做法是:1)使用两个HTTP版本在/ 路由块中增加 note $request.uri,运行http2.t 测试;2)这会产生不同的结果。将环境变量设置为 CRO_TRACE=1 运行测试;3)在 CRO_TRACE 的输出中请求具有标头,但当服务器解析它时就不再有了;4)进入设置标头的HTTP/2解析器部分;5)在HTTP/2中有5个伪标头,但我们只处理了其中的3个;6)添加缺失的伪标头;7)修复问题并增加一个测试PR。虽然没有调试手册,但设置 CRO_TRACE 并运行测试可以帮助理解哪个模块存在问题,并且可以跟踪到相关部分。 - Takao
2
Cro非常模块化,有助于调试,但HTTP本身很棘手,因此某些地方的代码很难理解。已知存在一些并发问题,以及与各种情况下的错误报告相关的问题。但是,当涉及协议数据处理部分(例如此部分)时,这些错误通常很容易调试。 - Takao
1
@Takoa 谢谢您的诊断和修复。更多信息请参见 github - acw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接