HTTP Reference
本文阐明了 Quarkus 中可用的不同 HTTP 功能。 Eclipse Vert.x 提供了基本 HTTP 层。对于 Servlet 支持,Quarkus 采用基于 Vert.x 运行的定制化 Undertow 版本,而 Jakarta REST 支持则通过 RESTEasy 传递。 在存在 Undertow 时,RESTEasy 作为 Servlet 过滤器运行。在不存在时,RESTEasy 直接在 Vert.x 上运行,不涉及 Servlet。
- Serving static resources
- Configuring the Context path
- Supporting secure connections with TLS/SSL
- Additional HTTP Headers
- Support 100-Continue in vert.x
- HTTP/2 Support
- Listening on a Random Port
- CORS filter
- HTTP Limits Configuration
- Configure traffic shaping
- Configuring HTTP Access Logs
- Arbitrary customizations
- How to execute logic when HTTP server started
- Running behind a reverse proxy
- SameSite cookies
- Servlet Config
Serving static resources
如果您正在针对 Web 应用程序使用 Quarkus,请查看 Quarkus for the Web 指南。
From the application jar
若要从应用程序 jar 提供静态资源,您必须将它们放在应用程序的 META-INF/resources
目录中。选择此位置是因为它是 jar
文件中资源的标准位置(如 Servlet 规范中定义的)。尽管 Quarkus 可以独立于 Servlet 使用,但遵循此惯例可以让将资源放在此位置的现有代码正常运行。
From web dependencies like webjars or mvnpm
请参阅 Web dependency locator 指南,了解有关如何使用 WebJars、 mvnpm 和 importmaps 的详细信息
From a local directory
可以通过在 Vert.x 路由器中安装附加路由,从本地目录提供静态资源。
例如,要从相对于 [role="bare"][role="bare"]http://localhost:8080/static/ 的当前路径提供 static/
目录中的资源,您可以安装以下路由:
package org.acme;
import io.quarkus.runtime.StartupEvent;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.StaticHandler;
import jakarta.enterprise.event.Observes;
public class StaticResources {
void installRoute(@Observes StartupEvent startupEvent, Router router) {
router.route()
.path("/static/*")
.handler(StaticHandler.create("static/"));
}
}
HTTP Compression
默认情况下,静态资源的响应正文不会被压缩。您可以通过 quarkus.http.enable-compression=true
启用 HTTP 压缩支持。如果启用了压缩支持,则当资源的文件名派生的 Content-Type
标头为通过 quarkus.http.compress-media-types
配置的压缩媒体类型时,响应正文会压缩。
以下媒体类型列表默认压缩: |
如果客户端在请求标头(例如 |
默认情况下不提供 Brotli 压缩。您可以通过设置 |
Configuring the Context path
默认情况下,Quarkus 将通过根上下文提供内容。如果您想更改此内容,可以使用 quarkus.http.root-path
配置密钥设置上下文路径。
如果您正在使用 Servlet,则可以通过 quarkus.servlet.context-path
控制 Servlet 上下文路径。此项相对于上述 http 根,并且只会影响 Servlet 和在 Servlet 上运行的内容。大多数应用程序都会希望使用 HTTP 根,因为这会影响 Quarkus 提供的所有内容。
如果同时指定,则所有非 Servlet Web 端点将与 quarkus.http.root-path
相关联,而 Servlet 将与 {quarkus.http.root-path}/{quarkus.servlet.context-path}
相关联。
如果使用 REST Assured 进行测试并且设置了 quarkus.http.root-path
,那么 Quarkus 将自动配置基本 URL 以用于 Quarkus 测试,所以测试 URL 不应该包括根目录。
通常情况下,Web 内容的路径配置相对于 quarkus.http.root-path
(默认情况下为 /)进行解释。
-
要在该上下文根目录中指定路径,请使用不以正斜杠开始的相对路径。
-
如果你想明确指定 URI,且该 URI 始终与
quarkus.http.root-path
的值无关,请使用一个以正斜杠开头的绝对路径。
例如,如果一个扩展配置了 service
路径,则该端点将从 ${quarkus.http.root-path}/service
提供服务。如果你将该路径的配置更改为 /service
,则该端点将从 /service
提供服务。
Path Resolution in Quarkus 博客文章进一步解释了路径解析如何针对用户和扩展定义的路径运行。
quarkus.http.root-path
仅用于主 HTTP 服务器。如果你启用了管理界面(使用 quarkus.management.enabled=true
属性),你可以使用 quarkus.management.root-path
配置管理界面的根路径。
请参阅 management interface reference 了解更多信息。
Supporting secure connections with TLS/SSL
为了让 Quarkus 支持安全连接,你必须提供证书和关联密钥文件,或提供密钥库。
在这两种情况下,都必须提供密码。请参阅指定段落,了解如何提供密码的详细描述。
若要支持原生可执行文件中的 TLS/SSL,请参阅我们的 Using SSL With Native Executables guide。 |
Using the TLS centralized configuration
Quarkus 提供一个 TLS centralized configuration,可用于配置服务器的 TLS 上下文。这是配置 HTTPS 的建议方法。
若要配置 HTTP 服务器以使用 HTTPS,可以使用以下配置:
quarkus.tls.key-store.pem.0.cert=server.crt
quarkus.tls.key-store.pem.0.key=server.key
quarkus.http.insecure-requests=disabled # Reject HTTP requests
因此,你使用 p12
(PKCS12)密钥库,请使用以下配置:
quarkus.tls.key-store.p12.path=server-keystore.p12
quarkus.tls.key-store.p12.password=secret
quarkus.http.insecure-requests=disabled # Reject HTTP requests
你可以使用命名配置,而不是默认配置:
quarkus.tls.https.key-store.p12.path=server-keystore.p12
quarkus.tls.https.key-store.p12.password=secret
quarkus.http.insecure-requests=disabled
quarkus.http.tls-configuration-name=https
Configuring the HTTP server directly
如果你不想使用 TLS 注册表,可以直接配置 HTTP 服务器。
如果尚未将证书加载到密钥库中,可以使用下面列出的属性直接提供证书。Quarkus 首先会尝试将给定文件加载为资源,并使用文件系统作为后备。证书/密钥对将在启动时加载到新创建的密钥库中。
你的 application.properties
的外观如下所示:
quarkus.http.ssl.certificate.files=/path/to/certificate
quarkus.http.ssl.certificate.key-files=/path/to/key
另一种解决方法是直接提供一个密钥库,其中已经包含具有证书的默认条目。你至少需要提供文件和密码。
与证书/密钥文件组合一样,Quarkus 首先将尝试将给定路径解析为资源,然后尝试从文件系统读取该资源。
将以下属性添加到你的 application.properties
:
quarkus.http.ssl.certificate.key-store-file=/path/to/keystore
作为可选提示,可以将密钥库的类型提供为所列选项之一。如果未提供类型,Quarkus 将尝试从文件扩展名推断类型。
quarkus.http.ssl.certificate.key-store-file-type=[one of JKS, JCEKS, P12, PKCS12, PFX]
在上述两种情况下,都需要提供密码来创建/加载密钥库。可以使用以下属性在 application.properties
中设置密码(纯文本):
quarkus.http.ssl.certificate.key-store-password=your-password
但是,不要在配置文件中将密码作为纯文本提供(这被认为是不良做法),而是可以使用 MicroProfile Config 作为环境变量 QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD
提供密码。这也可以与 Kubernetes secrets 协同工作。
Note: To remain compatible with earlier versions of Quarkus (before 0.16) the default password is set to "password". It is therefore not a mandatory parameter!
Configure the HTTPS port
默认情况下,Quarkus 监听端口 8443 以用于 SSL 保护的连接,并监听端口 8444 以运行测试。
可以在 application.properties
中使用属性 quarkus.http.ssl-port
和 quarkus.http.test-ssl-port
配置这些端口。
Disable the HTTP port
可以禁用 HTTP 端口并仅支持安全请求。这是通过 application.properties
中的 quarkus.http.insecure-requests
属性完成的。有三种可能值:
enabled
-
The default, HTTP works as normal
redirect
-
HTTP requests will be redirected to the HTTPS port
disabled
-
The HTTP port will not be opened.
如果你使用 |
Reloading the certificates
密钥库、信任库和证书文件可以定期重新加载。配置 quarkus.http.ssl.certificate.reload-period
属性以指定应重新加载证书的时间间隔:
quarkus.http.ssl.certificate.files=/mount/certs/tls.crt
quarkus.http.ssl.certificate.key-files=/mount/certs/tls.key
quarkus.http.ssl.certificate.reload-period=1h
文件从最初加载时相同的文件夹重新加载。如果没有内容更改,则重新加载将是无操作。如果重新加载失败,则服务器将继续使用以前的证书。
Additional HTTP Headers
要启用在每个响应上发送 HTTP 标头,请添加以下属性:
quarkus.http.header."X-Content-Type-Options".value=nosniff
这将在对应用程序中任何资源执行的请求的响应上包含 X-Content-Type-Options: nosniff
HTTP 标头。
你还可以指定 path
模式和需要应用 HTTP methods
标头的资源:
quarkus.http.header.Pragma.value=no-cache
quarkus.http.header.Pragma.path=/headers/pragma
quarkus.http.header.Pragma.methods=GET,HEAD
这将仅在使用 GET
或 HEAD
方法调用 /headers/pragma
资源时应用 Pragma
标头
Unresolved include directive in modules/ROOT/pages/http-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-vertx-http_quarkus.http.header.adoc[]
Additional HTTP Headers per path
如果您根据路径需要不同的标头值,您可以使用以下配置:
quarkus.http.filter.index.header."Cache-Control"=none
quarkus.http.filter.index.matches=/index.html
当调用 /index.html
时,它会将 Cache-Control
标头设置为 none
。
键中 quarkus.http.filter
后面的 index
用于分组并且(作为一个示例)可以根据您的喜好命名。
您可以在路径中使用正则表达式,还可以指定设置 HTTP 标头的 HTTP 方法:
quarkus.http.filter.static.header."Cache-Control"=max-age=31536000
quarkus.http.filter.static.methods=GET,HEAD
quarkus.http.filter.static.matches=/static/.*
如果配置中重叠的路径,您可以指定一个顺序(较高的值优先)。例如,具有以下配置:
quarkus.http.filter.just-order.order=10
quarkus.http.filter.just-order.header."Cache-Control"=max-age=5000
quarkus.http.filter.just-order.matches=/paths/order
quarkus.http.filter.any-order.order=11
quarkus.http.filter.any-order.header."Cache-Control"=max-age=1
quarkus.http.filter.any-order.matches=/paths/order.*
当请求 /paths/order
时,将包含 Cache-Control: max-age=1
标头。
Unresolved include directive in modules/ROOT/pages/http-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-vertx-http_quarkus.http.filter.adoc[]
Support 100-Continue in vert.x
要支持 100-continue
,quarkus.http.handle-100-continue-automatically
选项需要显式启用。有关其他信息,请查看 100-continue 和相关的 Vert.x documentation。
quarkus.http.handle-100-continue-automatically=true
HTTP/2 Support
HTTP/2 默认已启用,如果使用 SSL,浏览器将使用它。即使在没有使用 SSL 的情况下,也支持通过明文升级的 HTTP/2,非浏览器客户端也可能使用它。
如果您想禁用 HTTP/2,则可以设置:
quarkus.http.http2=false
请注意,某些配置属性特定于 HTTP/2。例如,为了配置最大标头列表大小(~ 标头),您需要配置 quarkus.http.limits.max-header-list-size
属性。您还可以使用 quarkus.http.http2-push-enabled
启用或禁用 HTTP/2 推送。
Listening on a Random Port
如果您不想指定端口,则可以设置 quarkus.http.port=0
或 quarkus.http.test-port=0
。系统会选择一个随机打开的端口,并在控制台中打印一条日志消息。绑定端口时, quarkus.http.port
系统属性将被设置为实际选择的端口,因此您可以使用它从应用程序内部获取实际端口号。如果您正在进行测试,则可以正常注入 URL,对此进行实际端口配置,并且 REST Assured 也将被适当地配置。
由于这会设置系统属性,因此您可以通过 MicroProfile Config 访问 quarkus.http.port
,但是如果您使用注入,注入的值可能并不总是正确的。此端口分配是 Quarkus 启动中最后要发生的事情之一,因此如果您被注入的对象在端口打开前就被急切创建,那么注入的值将不正确。
CORS filter
为了使您的 Quarkus 应用程序可供在不同域上运行的另一个应用程序访问,您需要配置跨源资源共享 (CORS)。有关 Quarkus 提供的 CORS 过滤器的详细信息,请参阅“跨源资源共享”指南的 Quarkus CORS filter 小节。
HTTP Limits Configuration
Unresolved include directive in modules/ROOT/pages/http-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-vertx-http_quarkus.http.limits.adoc[]
Configure traffic shaping
流量整形允许您限制所有信道(即连接)中的带宽,而不管打开信道的数量。当您想控制整体网络流量以防止拥塞或优先处理某些类型的流量时,这将非常有用。
要启用流量整形,请在应用程序配置中添加以下属性:
quarkus.http.traffic-shaping.enabled=true # Required to enable traffic shaping
流量整形允许您配置各种参数,例如写和读限制(以每秒字节为单位)、检查间隔(两个带宽计算之间的延迟)和最长等待时间:
quarkus.http.traffic-shaping.enabled=true # Required to enable traffic shaping
quarkus.http.traffic-shaping.check-interval=30s
quarkus.http.traffic-shaping.outbound-global-bandwidth=1M
quarkus.http.traffic-shaping.inbound-global-bandwidth=1M
quarkus.http.traffic-shaping.max-delay=10s
检查间隔表示计算流量的时间段,较高的间隔可能导致不那么精确的流量整形。尽管接受 0(没有计算),但建议为检查间隔设置一个正值,即使它是高的,因为流量整形精度取决于计算流量的时间段。在这种情况下,建议的值接近 5 或 10 分钟。
outbound-global-bandwidth
和 inbound-global-bandwidth
参数分别表示写入和读取操作中每秒的最大字节数。您还应考虑在读取或写入操作中使对象大小相对地适应您需要的带宽。例如,为 10KB/s 处理 10 MB 大小的对象会导致突发,而为 1 MB/s 处理 100 KB 大小的对象则应由流量整形平稳进行处理。
此外,您可以设置允许的最大等待时间(max-delay
),它为时间整形设置一个上限。默认情况下设置为 15 秒。它必须小于 HTTP 超时时间。当某个阈值达到时,在此时间段内不进行任何写入操作。
Configuring HTTP Access Logs
您可以在 application.properties
中进行配置,以添加 HTTP 请求记录。记录有两个选项,可以在标准 JBoss 记录输出中记录,也可以记录到一个专用文件中。
Unresolved include directive in modules/ROOT/pages/http-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-vertx-http_quarkus.http.access-log.adoc[]
Attribute | Short Form | Long Form |
---|---|---|
Remote IP address |
|
|
Local IP address |
|
|
发送的字节数(不包括 HTTP 头部),如果没有发送字节,则为“-” |
|
|
发送的字节数(不包括 HTTP 头部) |
|
|
Remote host name |
|
|
Request protocol |
|
|
Request method |
|
|
Local port |
|
|
查询字符串(如果存在,则以“?”开头,否则为空字符串) |
|
|
请求的第一行 |
|
|
响应的 HTTP 状态代码 |
|
|
以通用日志格式格式的日期和时间 |
|
|
由符合 DateTimeFormatter 标准的字符串定义的日期和时间 |
|
|
经过验证的远程用户 |
|
|
Requested URL path |
|
|
Request relative path |
|
|
Local server name |
|
|
处理请求所花费的时间(毫秒) |
|
|
处理请求所花费的时间(秒) |
|
|
处理请求所花费的时间(微妙时间) |
|
|
处理请求所花费的时间(纳秒时间) |
|
|
Current request thread name |
|
|
SSL cypher |
|
|
SSL client certificate |
|
|
SSL session id |
|
|
All request headers |
|
|
Cookie value |
|
|
Query parameter |
|
|
Request header |
|
|
Response header |
|
|
Vert.x 路由上下文内部数据 |
|
|
Vert.x MDC 数据(例如 OpenTelemetry 中的“traceId”) |
|
将 quarkus.http.access-log.consolidate-rerouted-requests=true
设置为启用对修饰符 <
的支持。对于已在内部重定向以咨询原始请求的请求,可以使用此修饰符。下列属性支持该修饰符:
Attribute | Short Form | Long Form |
---|---|---|
请求的第一行 |
|
|
Request method |
|
|
Request relative path |
|
|
Requested URL path |
|
|
查询字符串(如果存在,则以“?”开头,否则为空字符串) |
|
|
Query parameter |
|
使用任何与记录请求处理时间相关的属性时,将 |
假设已为该应用程序设置了安全性(请参阅我们的 guide 了解更多详情),则记录属性 |
使用 |
Arbitrary customizations
Quarkus 允许用户通过使用 io.quarkus.vertx.http.HttpServerOptionsCustomizer
任意自定义 Quarkus 启动的 HTTP 服务器的选项。例如,如果需要以编程方式设置 HTTP 端口,则可以使用以下代码:
import jakarta.inject.Singleton;
import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
@Singleton 1
public class MyCustomizer implements HttpServerOptionsCustomizer {
@Override
public void customizeHttpServer(HttpServerOptions options) { 2
options.setPort(9998);
}
}
1 | 通过使类成为托管 bean,Quarkus 在启动 Vert.x 服务器时会考虑定制器 |
2 | 在这种情况下,我们只关心定制 HTTP 服务器,所以我们只需覆盖 customizeHttpServer 方法,但是用户应注意,HttpServerOptionsCustomizer 也允许配置 HTTPS 和域套接字服务器 |
How to execute logic when HTTP server started
为了在启动 HTTP 服务器时执行某些自定义操作,您需要声明一个 asynchronous CDI 观察者方法。Quarkus asynchronously 在相应的 HTTP 服务器开始侦听已配置的主机和端口上时触发 io.quarkus.vertx.http.HttpServerStart
、io.quarkus.vertx.http.HttpsServerStart
和 io.quarkus.vertx.http.DomainSocketServerStart
类型事件。
HttpServerStart
example@ApplicationScoped
public class MyListener {
void httpStarted(@ObservesAsync HttpServerStart start) { 1
// ...notified when the HTTP server starts listening
}
}
1 | 可以通过使用 @jakarta.enterprise.event.ObservesAsync 为 HttpServerStart 参数添加注释来声明一个异步 HttpServerStart 观察者方法。 |
对于此特定用例来说,不能使用 |
Running behind a reverse proxy
Quarkus 可以通过代理访问,代理会另外生成标头(例如 X-Forwarded-Host
),以防止来自代理服务器客户端所面对端的信息在它们被涉及时遭到更改或丢失。在此类场景中,Quarkus 可以被配置为自动更新协议、主机、端口和 URI,反映这些标头中的值。
激活此功能后,服务器将面临多个安全问题(即,信息欺骗)。请考虑仅在反向代理后面运行的情况下激活此功能。
要设置此功能,请在 src/main/resources/application.properties
中包含以下行:
quarkus.http.proxy.proxy-address-forwarding=true
仅要考虑事实上的标准标头(Forwarded
标头),请在 src/main/resources/application.properties
中包含以下行:
quarkus.http.proxy.allow-forwarded=true
仅要考虑非标准标头,请改在 src/main/resources/application.properties
中包含以下行:
quarkus.http.proxy.proxy-address-forwarding=true
quarkus.http.proxy.allow-x-forwarded=true
quarkus.http.proxy.enable-forwarded-host=true
quarkus.http.proxy.enable-forwarded-prefix=true
quarkus.http.proxy.trusted-proxies=127.0.0.1 1
1 | 使用 IP 地址 127.0.0.1 配置受信任的代理。将忽略来自任何其他地址的请求标头。 |
与标准标头和非标准标头相关的配置都可以组合,尽管标准标头配置将具有优先权。然而,组合它们会产生安全影响,因为客户端可以伪造转发标头请求,而代理不会覆盖此类标头。因此,代理应该从客户端剥离意外的 X-Forwarded
或 X-Forwarded-*
标头。
支持的转发地址标头包括:
-
Forwarded
-
X-Forwarded-Proto
-
X-Forwarded-Host
-
X-Forwarded-Port
-
X-Forwarded-Ssl
-
X-Forwarded-Prefix
SameSite cookies
可以通过列出 cookie 名称和 SameSite
属性轻松地向 Quarkus 端点设置的任何 cookie 添加 SameSite cookie 属性,例如:
quarkus.http.same-site-cookie.jwt.value=Lax
quarkus.http.same-site-cookie.session.value=Strict
使用此配置后,jwt
cookie 将具有 SameSite=Lax
属性,session
cookie 将具有 SameSite=Strict
属性。
Servlet Config
要使用 Servlet,你需要明确包含 quarkus-undertow
:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-undertow</artifactId>
</dependency>
implementation("io.quarkus:quarkus-undertow")
undertow-handlers.conf
你可以使用 undertow-handlers.conf
文件来利用 Undertow 断言语言。此文件应放置在你应用程序 jar 的 META-INF
目录中。此文件包含使用 Undertow predicate language 定义的处理器。
Built-in route order values
路由顺序值是通过 Vert.x 路由 io.vertx.ext.web.Route.order(int)
函数指定的值。
Quarkus 用特定的顺序值注册了几条路由。常量在 io.quarkus.vertx.http.runtime.RouteConstants
类中定义,如下表所示。自定义路由应定义 20000 或更高版本的值,以便它不会干扰 Quarkus 和扩展提供的功能。
在 io.quarkus.vertx.http.runtime.RouteConstants
中定义的路由顺序常量和已知扩展:
Route order value |
Constant name |
Origin |
|
|
访问日志处理器(如果在配置中启用)。 |
|
|
添加开始时间的处理器(如果在配置中启用)。 |
|
|
-replacement body handler. |
|
|
用于管理路由器的正文处理器。 |
|
|
添加在配置中指定的头部的处理器。 |
|
|
管理路由器的 CORS 原始处理器。 |
|
|
Body handler. |
|
|
强制执行上传正文大小限制的路由。 |
|
|
Compression handler. |
|
|
优先级高于默认路由的路由(从此值中添加一个偏移量)。 |
|
|
默认路由顺序(即静态资源、Servlet)。 |
|
|
优先级低于默认路由的路由(从此值中添加一个偏移量) |