# HTTP Reference

This document explains various HTTP features that you can use in Quarkus.

HTTP is provided using Eclipse Vert.x as the base HTTP layer. Servlet’s are supported using a modified version of Undertow that runs on top of Vert.x, and RESTEasy is used to provide Jakarta REST support. If Undertow is present RESTEasy will run as a Servlet filter, otherwise it will run directly on top of Vert.x with no Servlet involvement.

## 1. Serving Static Resources

### 1.1. From the application jar

To serve static resources from the application jar, you must place them in the `META-INF/resources` directory of your application. This location was chosen as it is the standard location for resources in `jar` files as defined by the Servlet spec. Even though Quarkus can be used without Servlet, following this convention allows existing code that places its resources in this location to function correctly.

### 1.2. From WebJars

If you are using webjars, like the following JQuery one:

pom.xml

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>jquery</artifactId>
        <version>3.1.1</version>
    </dependency>

build.gradle

    implementation("org.webjars:jquery:3.1.1")

and rather write `/webjars/jquery/jquery.min.js` instead of `/webjars/jquery/3.1.1/jquery.min.js` in your HTML files, you can add the `quarkus-webjars-locator` extension to your project. To use it, add the following to your project’s dependencies:

pom.xml

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-webjars-locator</artifactId>
    </dependency>

build.gradle

    implementation("io.quarkus:quarkus-webjars-locator")

### 1.3. From a local directory

Static resources can be served from a local directory by installing an additional route in the Vert.x router.

For instance, to serve resources from the `static/` directory relative to the current path at http://localhost:8080/static/, you can install the following route:

    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/"));
        }
    }

### 1.4. HTTP Compression

The response body of a static resource is not compressed by default. You can enable the HTTP compression support by means of `quarkus.http.enable-compression=true`. If compression support is enabled then the response body is compressed if the `Content-Type` header derived from the file name of a resource is a compressed media type as configured via `quarkus.http.compress-media-types`.

| By default, the following list of media types is compressed: `text/html`, `text/plain`, `text/xml`, `text/css`, `text/javascript` and `application/javascript`.

| If the client does not support HTTP compression then the response body is not compressed.

### 1.5. Other Configurations

Additionally, the index page for static resources can be changed from default `index.html`, the hidden files (e.g. dot files) can be indicated as not served, the range requests can be disabled, and the caching support (e.g. caching headers and file properties cache) can be configured.

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.static-resources.index-page` Set the index page when serving static resources. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_INDEX_PAGE` | string | `index.html`
`quarkus.http.static-resources.include-hidden` Set whether hidden files should be served. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_INCLUDE_HIDDEN` | boolean | `true`
`quarkus.http.static-resources.enable-range-support` Set whether range requests (resumable downloads; media streaming) should be enabled. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_ENABLE_RANGE_SUPPORT` | boolean | `true`
`quarkus.http.static-resources.caching-enabled` Set whether cache handling is enabled. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_CACHING_ENABLED` | boolean | `true`
`quarkus.http.static-resources.cache-entry-timeout` Set the cache entry timeout. The default is `30` seconds. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_CACHE_ENTRY_TIMEOUT` | Duration | `30S`
`quarkus.http.static-resources.max-age` Set value for max age in caching headers. The default is `24` hours. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_MAX_AGE` | Duration | `24H`
`quarkus.http.static-resources.max-cache-size` Set the max cache size. Environment variable: `QUARKUS_HTTP_STATIC_RESOURCES_MAX_CACHE_SIZE` | int | `10000`

| About the Duration format The format for durations uses the standard `java.time.Duration` format. You can learn more about it in the Duration#parse() javadoc. You can also provide duration values starting with a number. In this case, if the value consists only of a number, the converter treats the value as seconds. Otherwise, `PT` is implicitly prepended to the value to obtain a standard `java.time.Duration` format.

## 2. Configuring the Context path

By default, Quarkus will serve content from under the root context. If you want to change this you can use the `quarkus.http.root-path` config key to set the context path.

If you are using Servlet you can control the Servlet context path via `quarkus.servlet.context-path`. This item is relative to the http root above, and will only affect Servlet and things that run on top of Servlet. Most applications will want to use the HTTP root as this affects everything that Quarkus serves.

If both are specified then all non-Servlet web endpoints will be relative to `quarkus.http.root-path`, while Servlet’s will be served relative to `{quarkus.http.root-path}/{quarkus.servlet.context-path}`.

If REST Assured is used for testing and `quarkus.http.root-path` is set then Quarkus will automatically configure the base URL for use in Quarkus tests, so test URL’s should not include the root path.

In general, path configurations for web content are interpreted relative to `quarkus.http.root-path` (which is / by default).

- To specify paths within this context root, use a relative path that does not begin with a forward slash.

- If you want to specify the URI explicitly, so it is always the same regardless of the value of `quarkus.http.root-path`, use an absolute path that begins with a forward slash.

As an example, if an extension configures a `service` path, that endpoint will be served from `${quarkus.http.root-path}/service`. If you change the configuration of that path to `/service`, that endpoint will be served from `/service`.

The Path Resolution in Quarkus blog post further explains how path resolution works for both user and extension defined paths.

| Management Interface `quarkus.http.root-path` is only used for the main HTTP server. If you enabled the management interface (using the `quarkus.management.enabled=true` property), you can configure the root path of the management interface using: `quarkus.management.root-path`. Refer to the management interface reference for more information.

## 3. Supporting secure connections with SSL

In order to have Quarkus support secure connections, you must either provide a certificate and associated key file, or supply a keystore.

In both cases, a password must be provided. See the designated paragraph for a detailed description of how to provide it.

| To enable SSL support with native executables, please refer to our Using SSL With Native Executables guide.

### 3.1. Providing a certificate and key file

If the certificate has not been loaded into a keystore, it can be provided directly using the properties listed below. Quarkus will first try to load the given files as resources, and uses the filesystem as a fallback. The certificate / key pair will be loaded into a newly created keystore on startup.

Your `application.properties` would then look like this:

    quarkus.http.ssl.certificate.files=/path/to/certificate
    quarkus.http.ssl.certificate.key-files=/path/to/key

### 3.2. Providing a keystore

An alternate solution is to directly provide a keystore which already contains a default entry with a certificate. You will need to at least provide the file and a password.

As with the certificate/key file combination, Quarkus will first try to resolve the given path as a resource, before attempting to read it from the filesystem.

Add the following property to your `application.properties`:

    quarkus.http.ssl.certificate.key-store-file=/path/to/keystore

As an optional hint, the type of keystore can be provided as one of the options listed. If the type is not provided, Quarkus will try to deduce it from the file extensions, defaulting to type JKS.

    quarkus.http.ssl.certificate.key-store-file-type=[one of JKS, JCEKS, P12, PKCS12, PFX]

### 3.3. Setting the password

In both aforementioned scenarios, a password needs to be provided to create/load the keystore with. The password can be set in your `application.properties` (in plain-text) using the following property:

    quarkus.http.ssl.certificate.key-store-password=your-password

However, instead of providing the password as plain-text in the configuration file (which is considered bad practice), it can instead be supplied (using MicroProfile Config) as the environment variable `QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD`. This will also work in tandem with Kubernetes secrets.

Note: in order 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!

### 3.4. Configure the HTTPS port

By default, Quarkus listens to port 8443 for SSL secured connections and 8444 when running tests.

These ports can be configured in your `application.properties` with the properties `quarkus.http.ssl-port` and `quarkus.http.test-ssl-port`.

### 3.5. Disable the HTTP port

It is possible to disable the HTTP port and only support secure requests. This is done via the `quarkus.http.insecure-requests` property in `application.properties`. There are three possible values:

`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.

| if you use `redirect` or `disabled` and have not added an SSL certificate or keystore, your server will not start!

## 4. Additional HTTP Headers

To enable HTTP headers to be sent on every response, add the following properties:

    quarkus.http.header."X-Content-Type-Options".value=nosniff

This will include the `X-Content-Type-Options: nosniff` HTTP Header on responses for requests performed on any resource in the application.

You can also specify a `path` pattern and the HTTP `methods` the header needs to be applied:

    quarkus.http.header.Pragma.value=no-cache
    quarkus.http.header.Pragma.path=/headers/pragma
    quarkus.http.header.Pragma.methods=GET,HEAD

This will apply the `Pragma` header only when the `/headers/pragma` resource is called with a `GET` or a `HEAD` method

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.header."header".path` The path this header should be applied Environment variable: `QUARKUS_HTTP_HEADER__HEADER__PATH` | string | `/*`
`quarkus.http.header."header".value` The value for this header configuration Environment variable: `QUARKUS_HTTP_HEADER__HEADER__VALUE` | string | required
`quarkus.http.header."header".methods` The HTTP methods for this header configuration Environment variable: `QUARKUS_HTTP_HEADER__HEADER__METHODS` | list of string |
`quarkus.management.header."header".path` The path this header should be applied Environment variable: `QUARKUS_MANAGEMENT_HEADER__HEADER__PATH` | string | `/*`
`quarkus.management.header."header".value` The value for this header configuration Environment variable: `QUARKUS_MANAGEMENT_HEADER__HEADER__VALUE` | string | required
`quarkus.management.header."header".methods` The HTTP methods for this header configuration Environment variable: `QUARKUS_MANAGEMENT_HEADER__HEADER__METHODS` | list of string |

### 4.1. Additional HTTP Headers per path

If you need different header values depending on the path, you can use the following configuration:

    quarkus.http.filter.index.header."Cache-Control"=none
    quarkus.http.filter.index.matches=/index.html

This will set the `Cache-Control` header to `none` when `/index.html` is called.

| The `index` after `quarkus.http.filter` in the key is used for grouping and (as an example) can be named as you like.

You can use a regular expression in the path and also specify the HTTP methods where the HTTP header will be set:

    quarkus.http.filter.static.header."Cache-Control"=max-age=31536000
    quarkus.http.filter.static.methods=GET,HEAD
    quarkus.http.filter.static.matches=/static/.*

In case of overlapping paths in the configuration, you can specify an order (higher values take precedence). For example, having the following configuration:

    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.*

Will include the `Cache-Control: max-age=1` header when `/paths/order` is requested.

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.filter."filter".matches` A regular expression for the paths matching this configuration Environment variable: `QUARKUS_HTTP_FILTER__FILTER__MATCHES` | string | required
`quarkus.http.filter."filter".header` Additional HTTP Headers always sent in the response Environment variable: `QUARKUS_HTTP_FILTER__FILTER__HEADER` | `Map<String,String>` |
`quarkus.http.filter."filter".methods` The HTTP methods for this path configuration Environment variable: `QUARKUS_HTTP_FILTER__FILTER__METHODS` | list of string |
`quarkus.http.filter."filter".order` Environment variable: `QUARKUS_HTTP_FILTER__FILTER__ORDER` | int |
`quarkus.management.filter."filter".matches` A regular expression for the paths matching this configuration Environment variable: `QUARKUS_MANAGEMENT_FILTER__FILTER__MATCHES` | string | required
`quarkus.management.filter."filter".header` Additional HTTP Headers always sent in the response Environment variable: `QUARKUS_MANAGEMENT_FILTER__FILTER__HEADER` | `Map<String,String>` |
`quarkus.management.filter."filter".methods` The HTTP methods for this path configuration Environment variable: `QUARKUS_MANAGEMENT_FILTER__FILTER__METHODS` | list of string |
`quarkus.management.filter."filter".order` Environment variable: `QUARKUS_MANAGEMENT_FILTER__FILTER__ORDER` | int |

## 5. Support 100-Continue in vert.x

In order to support `100-continue`, the `quarkus.http.handle-100-continue-automatically` option needs to be enabled explicitly For additional information check 100-continue and the related Vert.x documentation.

    quarkus.http.handle-100-continue-automatically=true

## 6. HTTP/2 Support

HTTP/2 is enabled by default, and will be used by browsers if SSL is in use on JDK11 or higher. JDK8 does not support ALPN so cannot be used to run HTTP/2 over SSL. Even if SSL is not in use HTTP/2 via cleartext upgrade is supported, and may be used by non-browser clients.

If you want to disable HTTP/2 you can set:

    quarkus.http.http2=false

Note that some configuration attributes are specific to HTTP/2. For example, to configure the max header list size (~ header), you need to configure the `quarkus.http.limits.max-header-list-size` attribute. You can also enable or disable HTTP/2 push using `quarkus.http.http2-push-enabled`.

## 7. Listening on a Random Port

If you don’t want to specify a port you can set `quarkus.http.port=0` or `quarkus.http.test-port=0`. A random open port will be picked by the OS, and a log message printed in the console. When the port is bound the `quarkus.http.port` system property will be set to the actual port that was selected, so you can use this to get the actual port number from inside the application. If you are in a test you can inject the URL normally and this will be configured with the actual port, and REST Assured will also be configured appropriately.

| As this sets a system property you can access `quarkus.http.port` via MicroProfile Config, however if you use injection the injected value may not always be correct. This port allocation is one of the last things to happen in Quarkus startup, so if your object that is being injected is created eagerly before the port has opened the injected value will not be correct.

## 8. CORS filter

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.

Quarkus comes with a CORS filter which implements the `jakarta.servlet.Filter` interface and intercepts all incoming HTTP requests. It can be enabled in the Quarkus configuration file, `src/main/resources/application.properties`:

    quarkus.http.cors=true

If the filter is enabled and an HTTP request is identified as cross-origin, the CORS policy and headers defined using the following properties will be applied before passing the request on to its actual target (servlet, Jakarta REST resource, etc.):

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.cors.origins` Origins allowed for CORS Comma separated list of valid URLs, e.g.: http://www.quarkus.io,http://localhost:3000 In case an entry of the list is surrounded by forward slashes, it is interpreted as a regular expression. Environment variable: `QUARKUS_HTTP_CORS_ORIGINS` | list of string |
`quarkus.http.cors.methods` HTTP methods allowed for CORS Comma separated list of valid methods. ex: GET,PUT,POST The filter allows any method if this is not set. default: returns any requested method as valid Environment variable: `QUARKUS_HTTP_CORS_METHODS` | list of string |
`quarkus.http.cors.headers` HTTP headers allowed for CORS Comma separated list of valid headers. ex: X-Custom,Content-Disposition The filter allows any header if this is not set. default: returns any requested header as valid Environment variable: `QUARKUS_HTTP_CORS_HEADERS` | list of string |
`quarkus.http.cors.exposed-headers` HTTP headers exposed in CORS Comma separated list of valid headers. ex: X-Custom,Content-Disposition default: empty Environment variable: `QUARKUS_HTTP_CORS_EXPOSED_HEADERS` | list of string |
`quarkus.http.cors.access-control-max-age` The `Access-Control-Max-Age` response header value indicating how long the results of a pre-flight request can be cached. Environment variable: `QUARKUS_HTTP_CORS_ACCESS_CONTROL_MAX_AGE` | Duration |
`quarkus.http.cors.access-control-allow-credentials` The `Access-Control-Allow-Credentials` header is used to tell the browsers to expose the response to front-end JavaScript code when the request’s credentials mode Request.credentials is “include”. The value of this header will default to `true` if `quarkus.http.cors.origins` property is set and there is a match with the precise `Origin` header. Environment variable: `QUARKUS_HTTP_CORS_ACCESS_CONTROL_ALLOW_CREDENTIALS` | boolean |

| About the Duration format The format for durations uses the standard `java.time.Duration` format. You can learn more about it in the Duration#parse() javadoc. You can also provide duration values starting with a number. In this case, if the value consists only of a number, the converter treats the value as seconds. Otherwise, `PT` is implicitly prepended to the value to obtain a standard `java.time.Duration` format.

Here’s what a full CORS filter configuration could look like, including a regular expression defining an allowed origin:

    quarkus.http.cors=true
    quarkus.http.cors.origins=http://foo.com,http://www.bar.io,/https://([a-z0-9\\-_]+)\\\\.app\\\\.mydomain\\\\.com/
    quarkus.http.cors.methods=GET,PUT,POST
    quarkus.http.cors.headers=X-Custom
    quarkus.http.cors.exposed-headers=Content-Disposition
    quarkus.http.cors.access-control-max-age=24H
    quarkus.http.cors.access-control-allow-credentials=true

`/https://([a-z0-9\\-_]+)\\\\.app\\\\.mydomain\\\\.com/` is treated as a regular expression because it is surrounded by forward slash characters.

| If you use regular expressions in an `application.properties` file, make sure 4 backward slashes are used to represent `.` and other regular expression metadata characters as normal characters, for example, `\\\\.` represents a `.` character while `\\.` represents a metadata character allowing for any character.

### 8.1. Support all origins in devmode

Having to configure required origins when you start developing a Quarkus application requiring CORS support can be difficult and, in such cases, you may want to allow all origins in dev mode only in order to focus on the actual development first:

    quarkus.http.cors=true
    %dev.quarkus.http.cors.origins=/.*/

It is important that you enable all origins only for the dev profile, allowing all origins in production is not recommended and could expose your applications to serious security issues.

## 9. HTTP Limits Configuration

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.limits.max-header-size` The maximum length of all headers. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_HEADER_SIZE` | MemorySize | `20K`
`quarkus.http.limits.max-body-size` The maximum size of a request body. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_BODY_SIZE` | MemorySize | `10240K`
`quarkus.http.limits.max-chunk-size` The max HTTP chunk size Environment variable: `QUARKUS_HTTP_LIMITS_MAX_CHUNK_SIZE` | MemorySize | `8192`
`quarkus.http.limits.max-initial-line-length` The maximum length of the initial line (e.g. `"GET / HTTP/1.0"`). Environment variable: `QUARKUS_HTTP_LIMITS_MAX_INITIAL_LINE_LENGTH` | int | `4096`
`quarkus.http.limits.max-form-attribute-size` The maximum length of a form attribute. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_FORM_ATTRIBUTE_SIZE` | MemorySize | `2048`
`quarkus.http.limits.max-connections` The maximum number of connections that are allowed at any one time. If this is set it is recommended to set a short idle timeout. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_CONNECTIONS` | int |
`quarkus.http.limits.header-table-size` Set the SETTINGS_HEADER_TABLE_SIZE HTTP/2 setting. Allows the sender to inform the remote endpoint of the maximum size of the header compression table used to decode header blocks, in octets. The encoder can select any size equal to or less than this value by using signaling specific to the header compression format inside a header block. The initial value is `4,096` octets. Environment variable: `QUARKUS_HTTP_LIMITS_HEADER_TABLE_SIZE` | long |
`quarkus.http.limits.max-concurrent-streams` Set SETTINGS_MAX_CONCURRENT_STREAMS HTTP/2 setting. Indicates the maximum number of concurrent streams that the sender will allow. This limit is directional: it applies to the number of streams that the sender permits the receiver to create. Initially, there is no limit to this value. It is recommended that this value be no smaller than 100, to not unnecessarily limit parallelism. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_CONCURRENT_STREAMS` | long |
`quarkus.http.limits.max-frame-size` Set the SETTINGS_MAX_FRAME_SIZE HTTP/2 setting. Indicates the size of the largest frame payload that the sender is willing to receive, in octets. The initial value is `2^14` (16,384) octets. Environment variable: `QUARKUS_HTTP_LIMITS_MAX_FRAME_SIZE` | int |
`quarkus.http.limits.max-header-list-size` Set the SETTINGS_MAX_HEADER_LIST_SIZE HTTP/2 setting. This advisory setting informs a peer of the maximum size of header list that the sender is prepared to accept, in octets. The value is based on the uncompressed size of header fields, including the length of the name and value in octets plus an overhead of 32 octets for each header field. The default value is `8192` Environment variable: `QUARKUS_HTTP_LIMITS_MAX_HEADER_LIST_SIZE` | long |
`quarkus.management.limits.max-header-size` The maximum length of all headers. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_HEADER_SIZE` | MemorySize | `20K`
`quarkus.management.limits.max-body-size` The maximum size of a request body. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_BODY_SIZE` | MemorySize | `10240K`
`quarkus.management.limits.max-chunk-size` The max HTTP chunk size Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_CHUNK_SIZE` | MemorySize | `8192`
`quarkus.management.limits.max-initial-line-length` The maximum length of the initial line (e.g. `"GET / HTTP/1.0"`). Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_INITIAL_LINE_LENGTH` | int | `4096`
`quarkus.management.limits.max-form-attribute-size` The maximum length of a form attribute. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_FORM_ATTRIBUTE_SIZE` | MemorySize | `2048`
`quarkus.management.limits.max-connections` The maximum number of connections that are allowed at any one time. If this is set it is recommended to set a short idle timeout. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_CONNECTIONS` | int |
`quarkus.management.limits.header-table-size` Set the SETTINGS_HEADER_TABLE_SIZE HTTP/2 setting. Allows the sender to inform the remote endpoint of the maximum size of the header compression table used to decode header blocks, in octets. The encoder can select any size equal to or less than this value by using signaling specific to the header compression format inside a header block. The initial value is `4,096` octets. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_HEADER_TABLE_SIZE` | long |
`quarkus.management.limits.max-concurrent-streams` Set SETTINGS_MAX_CONCURRENT_STREAMS HTTP/2 setting. Indicates the maximum number of concurrent streams that the sender will allow. This limit is directional: it applies to the number of streams that the sender permits the receiver to create. Initially, there is no limit to this value. It is recommended that this value be no smaller than 100, to not unnecessarily limit parallelism. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_CONCURRENT_STREAMS` | long |
`quarkus.management.limits.max-frame-size` Set the SETTINGS_MAX_FRAME_SIZE HTTP/2 setting. Indicates the size of the largest frame payload that the sender is willing to receive, in octets. The initial value is `2^14` (16,384) octets. Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_FRAME_SIZE` | int |
`quarkus.management.limits.max-header-list-size` Set the SETTINGS_MAX_HEADER_LIST_SIZE HTTP/2 setting. This advisory setting informs a peer of the maximum size of header list that the sender is prepared to accept, in octets. The value is based on the uncompressed size of header fields, including the length of the name and value in octets plus an overhead of 32 octets for each header field. The default value is `8192` Environment variable: `QUARKUS_MANAGEMENT_LIMITS_MAX_HEADER_LIST_SIZE` | long |

| About the MemorySize format A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes.

## 10. Configuring HTTP Access Logs

You can add HTTP request logging by configuring it in `application.properties`. There are two options for logging, either logging to the standard JBoss logging output, or logging to a dedicated file.

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.http.access-log.enabled` If access logging is enabled. By default this will log via the standard logging facility Environment variable: `QUARKUS_HTTP_ACCESS_LOG_ENABLED` | boolean | `false`
`quarkus.http.access-log.exclude-pattern` A regular expression that can be used to exclude some paths from logging. Environment variable: `QUARKUS_HTTP_ACCESS_LOG_EXCLUDE_PATTERN` | string |
`quarkus.http.access-log.pattern` The access log pattern. If this is the string `common`, `combined` or `long` then this will use one of the specified named formats: common: `%h %l %u %t "%r" %s %b` combined: `%h %l %u %t "%r" %s %b "%{i,Referer}" "%{i,User-Agent}"` long: `%r\n%{ALL_REQUEST_HEADERS}` Otherwise, consult the Quarkus documentation for the full list of variables that can be used. Environment variable: `QUARKUS_HTTP_ACCESS_LOG_PATTERN` | string | `common`
`quarkus.http.access-log.log-to-file` If logging should be done to a separate file. Environment variable: `QUARKUS_HTTP_ACCESS_LOG_LOG_TO_FILE` | boolean | `false`
`quarkus.http.access-log.base-file-name` The access log file base name, defaults to 'quarkus' which will give a log file name of 'quarkus.log'. Environment variable: `QUARKUS_HTTP_ACCESS_LOG_BASE_FILE_NAME` | string | `quarkus`
`quarkus.http.access-log.log-directory` The log directory to use when logging access to a file If this is not set then the current working directory is used. Environment variable: `QUARKUS_HTTP_ACCESS_LOG_LOG_DIRECTORY` | string |
`quarkus.http.access-log.log-suffix` The log file suffix Environment variable: `QUARKUS_HTTP_ACCESS_LOG_LOG_SUFFIX` | string | `.log`
`quarkus.http.access-log.category` The log category to use if logging is being done via the standard log mechanism (i.e. if base-file-name is empty). Environment variable: `QUARKUS_HTTP_ACCESS_LOG_CATEGORY` | string | `io.quarkus.http.access-log`
`quarkus.http.access-log.rotate` If the log should be rotated daily Environment variable: `QUARKUS_HTTP_ACCESS_LOG_ROTATE` | boolean | `true`

Attribute | Short Form | Long Form
--- | --- | ---
Remote IP address | `%a` | `%{REMOTE_IP}`
Local IP address | `%A` | `%{LOCAL_IP}`
Bytes sent, excluding HTTP headers, or '-' if no bytes were sent | `%b` |
Bytes sent, excluding HTTP headers | `%B` | `%{BYTES_SENT}`
Remote host name | `%h` | `%{REMOTE_HOST}`
Request protocol | `%H` | `%{PROTOCOL}`
Request method | `%m` | `%{METHOD}`
Local port | `%p` | `%{LOCAL_PORT}`
Query string (prepended with a '?' if it exists, otherwise an empty string) | `%q` | `%{QUERY_STRING}`
First line of the request | `%r` | `%{REQUEST_LINE}`
HTTP status code of the response | `%s` | `%{RESPONSE_CODE}`
Date and time, in Common Log Format format | `%t` | `%{DATE_TIME}`
Remote user that was authenticated | `%u` | `%{REMOTE_USER}`
Requested URL path | `%U` | `%{REQUEST_URL}`
Request relative path | `%R` | `%{REQUEST_PATH}`
Local server name | `%v` | `%{LOCAL_SERVER_NAME}`
Time taken to process the request, in millis | `%D` | `%{RESPONSE_TIME}`
Time taken to process the request, in seconds | `%T` |
Time taken to process the request, in micros |  | `%{RESPONSE_TIME_MICROS}`
Time taken to process the request, in nanos |  | `%{RESPONSE_TIME_NANOS}`
Current request thread name | `%I` | `%{THREAD_NAME}`
SSL cypher |  | `%{SSL_CIPHER}`
SSL client certificate |  | `%{SSL_CLIENT_CERT}`
SSL session id |  | `%{SSL_SESSION_ID}`
All request headers |  | `%{ALL_REQUEST_HEADERS}`
Cookie value |  | `%{c,cookie_name}`
Query parameter |  | `%{q,query_param_name}`
Request header |  | `%{i,request_header_name}`
Response header |  | `%{o,response_header_name}`
Vert.x Routing Context Internal Data |  | `%{d,map_key}`
Vert.x MDC data (e.g. 'traceId' for OpenTelemetry) |  | `%{X,mdc-key}`

| Use `quarkus.http.access-log.exclude-pattern=/some/path/.*` to exclude all entries concerning the path `/some/path/…​` (including subsequent paths) from the log.

## 11. Arbitrary customizations

Quarkus allows users to arbitrarily customize the options of HTTP servers started by Quarkus via the use of `io.quarkus.vertx.http.HttpServerOptionsCustomizer`. For example, if the HTTP port needs to be set programmatically, then the following code could be used:

    import jakarta.inject.Singleton;
    import io.quarkus.vertx.http.HttpServerOptionsCustomizer;

    @Singleton (1)
    public static class MyCustomizer implements HttpServerOptionsCustomizer {

        @Override
        public void customizeHttpServer(HttpServerOptions options) { (2)
            options.setPort(9998);
        }
    }

1 | By making the class a managed bean, Quarkus will take the customizer into account when it starts the Vert.x servers
2 | In this case, we only care about customizing the HTTP server, so we just override the `customizeHttpServer` method, but users should be aware that `HttpServerOptionsCustomizer` allows configuring the HTTPS and Domain Socket servers as well

## 12. Running behind a reverse proxy

Quarkus could be accessed through proxies that additionally generate headers (e.g. `X-Forwarded-Host`) to keep information from the client-facing side of the proxy servers that is altered or lost when they are involved. In those scenarios, Quarkus can be configured to automatically update information like protocol, host, port and URI reflecting the values in these headers.

| Activating this feature leaves the server exposed to several security issues (i.e. information spoofing). Consider activate it only when running behind a reverse proxy.

To set up this feature, please include the following lines in `src/main/resources/application.properties`:

    quarkus.http.proxy.proxy-address-forwarding=true

To consider only de-facto standard header (`Forwarded` header), please include the following lines in `src/main/resources/application.properties`:

    quarkus.http.proxy.allow-forwarded=true

To consider only non-standard headers, please include the following lines instead in `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 | Configure trusted proxy with the IP address `127.0.0.1`. Request headers from any other address are going to be ignored.

Both configurations related to standard and non-standard headers can be combined, although the standard headers configuration will have precedence. However, combining them has security implications as clients can forge requests with a forwarded header that is not overwritten by the proxy. Therefore, proxies should strip unexpected `X-Forwarded` or `X-Forwarded-*` headers from the client.

Supported forwarding address headers are:

- `Forwarded`

- `X-Forwarded-Proto`

- `X-Forwarded-Host`

- `X-Forwarded-Port`

- `X-Forwarded-Ssl`

- `X-Forwarded-Prefix`

## 13. SameSite cookies

One can easily add a SameSite cookie property to any of the cookies set by a Quarkus endpoint by listing a cookie name and a `SameSite` attribute, for example:

    quarkus.http.same-site-cookie.jwt.value=Lax
    quarkus.http.same-site-cookie.session.value=Strict

Given this configuration, the `jwt` cookie will have a `SameSite=Lax` attribute and the `session` cookie will have a `SameSite=Strict` attribute.

## 14. Servlet Config

To use Servlet you need to explicitly include `quarkus-undertow`:

pom.xml

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-undertow</artifactId>
    </dependency>

build.gradle

    implementation("io.quarkus:quarkus-undertow")

### 14.1. undertow-handlers.conf

You can make use of the Undertow predicate language using an `undertow-handlers.conf` file. This file should be placed in the `META-INF` directory of your application jar. This file contains handlers defined using the Undertow predicate language.

### 14.2. web.xml

If you are using a `web.xml` file as your configuration file, you can place it in the `src/main/resources/META-INF` directory.