Quarkus Rest Lambda解析HTTP2伪标头失败问题求助
问题
使用Quarkus Rest构建了Quarkus Lambda,未通过AWS API Gateway作为入口,而是采用Gloo Gateway的Lambda集成方案。当Gloo生成AWS Lambda请求事件时,会包含HTTP2伪标头,示例事件如下:
{ "body": "", "headers": { ":authority": "lambda.example.com:81", ":method": "GET", ":path": "/hello", ":scheme": "http", "accept": "*/*", "user-agent": "curl/8.7.1", "x-forwarded-proto": "http", "x-request-id": "76e5213d-4327-49ae-97b3-6a78099ca41b" } }
但Quarkus无法验证这些标头,在处理:authority标头时直接失败,报错信息如下:
2024-12-12 09:48:32,057 ERROR [qua.ama.lam.http] (main) Request Failure: java.lang.IllegalArgumentException: a header name cannot contain some prohibited characters, such as : :authority at io.vertx.core.http.impl.HttpUtils.validateHeaderName0(HttpUtils.java:992) at io.vertx.core.http.impl.HttpUtils.validateHeaderName(HttpUtils.java:964) at io.vertx.core.http.impl.HttpUtils.validateHeader(HttpUtils.java:851) at io.quarkus.vertx.http.runtime.QuarkusHttpHeaders.add0(QuarkusHttpHeaders.java:535) at io.quarkus.vertx.http.runtime.QuarkusHttpHeaders.add(QuarkusHttpHeaders.java:90) at io.quarkus.vertx.http.runtime.QuarkusHttpHeaders.add(QuarkusHttpHeaders.java:97) at io.quarkus.vertx.http.runtime.QuarkusHttpHeaders.add(QuarkusHttpHeaders.java:35) at io.quarkus.amazon.lambda.http.LambdaHttpHandler.nettyDispatch(LambdaHttpHandler.java:195) at io.quarkus.amazon.lambda.http.LambdaHttpHandler.handleRequest(LambdaHttpHandler.java:63)
疑问点:
- 这种报错是否属于预期情况?
- 是否有办法让Quarkus处理HTTP2伪标头?
- 是否可以在Lambda中禁用标头验证(已知存在风险)?
已尝试的无效方案:
- 在
application.properties中配置vertx.disableHttpHeadersValidation=true无效果 - 尝试在Gloo/Envoy端移除HTTP2伪标头,但不被允许
解决方案
1. 报错是否属于预期情况?
是。Quarkus的AWS Lambda HTTP适配器是针对AWS API Gateway的事件格式设计的,而API Gateway不会将HTTP2伪标头(:开头的标头)传递给Lambda。Gloo Gateway直接将这些伪标头放入事件的headers字段,不符合Quarkus适配器的预期输入格式,因此触发Vert.x的标头合法性验证报错。
2. 让Quarkus处理HTTP2伪标的可行方案
方案A:自定义Lambda请求处理器
绕过Quarkus默认的LambdaHttpHandler,自行编写Lambda请求处理逻辑:
- 解析Gloo传入的事件,提取HTTP2伪标头(
:method、:path、:scheme、:authority) - 将这些伪标头映射为标准HTTP请求属性:
:method→ 请求方法:path→ 请求路径:scheme→ 请求协议:authority→ Host头
- 过滤掉
headers中的伪标头,构造符合Quarkus要求的请求对象,再转发给Quarkus的HTTP处理链。
方案B:在Gloo端转换事件格式
虽然无法直接移除伪标头,但可以通过Gloo的路由转换规则,将HTTP2伪标头映射为Lambda事件的标准字段,而非放入headers中:
- 配置Gloo将
:method映射到Lambda事件的requestContext.http.method字段 - 将
:path映射到requestContext.http.path字段 - 将
:scheme映射到requestContext.http.protocol字段 - 将
:authority映射为标准host头,替换原headers中的伪标头
3. 禁用标头验证的方案(不推荐)
如果必须保留伪标头且无法在网关端处理,可以通过以下方式禁用Vert.x的标头验证:
自定义VertxOptions配置
创建Quarkus扩展类,全局禁用Vert.x的HTTP头验证:
import io.quarkus.vertx.core.runtime.config.VertxOptionsCustomizer; import io.vertx.core.VertxOptions; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DisableHeaderValidation implements VertxOptionsCustomizer { @Override public void customize(VertxOptions options) { options.setHttpHeadersValidationEnabled(false); } }
此配置会全局关闭Vert.x的头验证逻辑,解决伪标头的合法性检查问题,但可能引入非法标头导致的安全风险,需谨慎使用。
注意事项
- 原
application.properties中的vertx.disableHttpHeadersValidation=true无效,是因为Quarkus的Lambda HTTP适配器未正确读取该配置,需通过代码自定义VertxOptions实现。
内容的提问来源于stack exchange,提问作者Duncan Doyle
相关产品推荐
相关产品推荐

