Chapter 15. Configuring the Web Server (Undertow) in JBoss EAP


This chapter focuses on configuring the Undertow web server, the default server embedded within JBoss EAP. Here, you will find detailed instructions on enabling SSL/TLS for secure communication, leveraging HTTP/2 for enhanced performance, and fine-tuning server settings to align with your operational requirements.

15.1. Undertow subsystem overview

In JBoss EAP 8.0, the Undertow subsystem serves as the web layer within the application server. It provides the core web server and servlet container functionality, supporting advanced features like the Jakarta Servlet 6.0 specification, websockets, and HTTP upgrade. Undertow can also act as a high-performance reverse proxy with mod_cluster support, contributing to improved scalability, efficiency, and flexibility in handling web traffic.

The undertow subsystem allows you to configure the web server and servlet container settings. It implements the Jakarta Servlet 6.0 Specification as well as websockets. It also supports HTTP upgrade and using high performance non-blocking handlers in servlet deployments. The undertow subsystem also has the ability to act as a high performance reverse proxy which supports mod_cluster.

Within the undertow subsystem, there are five main components to configure:

  • Buffer caches
  • Server
  • Servlet container
  • Handlers
  • Filters
Note

While JBoss EAP does offer the ability to update the configuration for each of these components, the default configuration is suitable for most use cases and provides reasonable performance settings.

Default undertow subsystem configuration

<subsystem xmlns="{UndertowSubsystemNamespace}" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
        <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <http-invoker security-realm="ApplicationRealm"/>
        </host>
    </server>
    <servlet-container name="default">
        <jsp-config/>
        <websockets/>
    </servlet-container>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
</subsystem>
Important

The undertow subsystem also relies on the io subsystem to provide XNIO workers and buffer pools. The io subsystem is configured separately and provides a default configuration which should give optimal performance in most cases.

15.1.1. Using Elytron with undertow subsystem

As a web application is deployed, the name of the security domain required by that application will be identified. This will either be from within the deployment or, if the deployment does not have a security domain, the default-security-domain as defined in the undertow subsystem will be assumed. By default, the default-security-domain is ApplicationDomain. To ensure proper mapping from the name of the security domain required by the application to the appropriate Elytron configuration, an application-security-domain resource can be added to the undertow subsystem.

Example: Adding a mapping.

/subsystem=undertow/application-security-domain=ApplicationDomain:add(security-domain=ApplicationDomain)

The addition of mapping is successful if the result is:

<subsystem xmlns="{UndertowSubsystemNamespace}" ... default-security-domain="other">
...
    <application-security-domains>
        <application-security-domain name="ApplicationDomain" security-domain="ApplicationDomain"/>
    </application-security-domains>
...
</subsystem>

Note
  • If the deployment was already deployed at this point, the application server should be reloaded for the application security domain mapping to take effect.
  • In current web service-Elytron integration, the name of the security domain specified to secure a web service endpoint and the Elytron security domain name must be the same.

This simple form is suitable where a deployment is using the standard HTTP mechanism as defined within the Servlet specification like BASIC, CLIENT_CERT, DIGEST, FORM. Here, the authentication will be performed against the ApplicationDomain security domain. This form is also suitable where an application is not using any authentication mechanism and instead is using programmatic authentication or is trying to obtain the SecurityDomain associated with the deployment and use it directly.

Example: Advanced form of the mapping:

/subsystem=undertow/application-security-domain=MyAppSecurity:add(http-authentication-factory=application-http-authentication)

The advanced mapping is successful if the result is:

<subsystem xmlns="{UndertowSubsystemNamespace}" ... default-security-domain="other">
...
    <application-security-domains>
        <application-security-domain name="MyAppSecurity" http-authentication-factory="application-http-authentication"/>
    </application-security-domains>
...
</subsystem>

In this form of the configuration, instead of referencing a security domain, an http-authentication-factory is referenced. This is the factory that will be used to obtain the instances of the authentication mechanisms and is in turn associated with the security domain.

You should reference an http-authentication-factory attribute when using custom HTTP authentication mechanisms or where additional configuration must be defined for mechanisms such as principal transformers, credential factories, and mechanism realms. It is also better to reference an http-authentication-factory attribute when using mechanisms other than the four described in the Servlet specification.

When the advanced form of mapping is used, another configuration option is available, override-deployment-config. The referenced http-authentication-factory can return a complete set of authentication mechanisms. By default, these are filtered to just match the mechanisms requested by the application. If this option is set to true, then the mechanisms offered by the factory will override the mechanisms requested by the application.

The application-security-domain resource also has one additional option enable-jacc. If this is set to true, Java Authorization Contract for Containers will be enabled for any deployments matching this mapping.

15.1.1.1. Runtime information

Where an application-security-domain mapping is in use, it can be useful to double check that deployments did match against it as expected. If the resource is read with include-runtime=true, the deployments that are associated with the mapping will also be shown as:

/subsystem=undertow/application-security-domain=MyAppSecurity:read-resource(include-runtime=true)
{
    "outcome" => "success",
    "result" => {
        "enable-jacc" => false,
        "http-authentication-factory" => undefined,
        "override-deployment-config" => false,
        "referencing-deployments" => ["simple-webapp.war"],
        "security-domain" => "ApplicationDomain",
        "setting" => undefined
    }
}

In this output, the referencing-deployments attribute shows that the deployment simple-webapp.war has been deployed using the mapping.

15.1.2. Configuring buffer caches

This procedure guides you through configuring buffer caches in JBoss EAP, which help cache static resources to improve performance. Different deployments can use different cache sizes to optimize resource management. The total amount of space used can be calculated by multiplying the buffer size by the number of buffers per region by the maximum number of regions. The default size of a buffer cache is 10MB.

Note

JBoss EAP provides a single cache by default.

<subsystem xmlns="{UndertowSubsystemNamespace}" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
    <buffer-cache name="default"/>
    ...
</subsystem>

Prerequisites

  • Ensure JBoss EAP is installed and you have administrative access to the management CLI.

Procedure

  1. Update an existing buffer cache:

    • Modify the buffer size attribute:

      /subsystem=undertow/buffer-cache=default/:write-attribute(name=buffer-size,value=2048)
      reload
  2. Create a new buffer cache:

    • Add a new buffer cache:

      /subsystem=undertow/buffer-cache=new-buffer:add
  3. Delete a buffer cache:

    • Remove an existing buffer cache:

      /subsystem=undertow/buffer-cache=new-buffer:remove
      reload

Additional resources

15.1.3. Configuring byte buffer Pool

Undertow byte buffer pools are used to allocate pooled NIO ByteBuffer instances. All listeners have a byte buffer pool and you can use different buffer pools and workers for each listener. Byte buffer pools can be shared between different server instances.

These buffers are used for IO operations, and the buffer size has a big impact on application performance. For most servers, the ideal size is usually 16k.

Prerequisites

  • Ensure JBoss EAP is installed and you have administrative access to the management CLI.

Procedure

  1. Update an Existing Byte Buffer Pool.

    • Modify the buffer size attribute:

      /subsystem=undertow/byte-buffer-pool=myByteBufferPool:write-attribute(name=buffer-size,value=1024)
      reload
  2. Create a New Byte Buffer Pool.

    • Add a new byte buffer pool:

      /subsystem=undertow/byte-buffer-pool=newByteBufferPool:add
  3. Delete a Byte Buffer Pool.

    • Remove an existing byte buffer pool:

      /subsystem=undertow/byte-buffer-pool=newByteBufferPool:remove
      reload

Verification

  • Verify the changes by checking the buffer pool settings in the management console.

Additional resources

15.1.4. Understanding server configuration in undertow

A server represents an instance of Undertow and consists of several elements:

  • host
  • http-listener
  • https-listener
  • ajp-listener

The host element provides a virtual host configuration, while the three listeners provide connections of that type to the Undertow instance.

The default behavior of the server is to queue requests while the server is starting. You can change this default behavior using the queue-requests-on-start attribute on the host. If this attribute is set to true (the default), then requests that arrive when the server is starting will be held until the server is ready. If this attribute is set to false, then requests that arrive before the server has completely started will be rejected with the default response code.

Regardless of the attribute value, request processing does not start until the server is completely started.

You can configure the queue-requests-on-start attribute using the management console by navigating to Configuration Subsystems Web (Undertow) Server, selecting the server, clicking View, and selecting the Hosts tab. For a managed domain, you must specify which profile to configure.

Note

Multiple servers can be configured, allowing deployments and servers to be completely isolated. This can be useful in certain scenarios such as multi-tenant environments.

JBoss EAP provides a server by default:

15.1.5. Default undertow subsystem configuration

This reference provides the default configuration of the Undertow subsystem.

<subsystem xmlns="{UndertowSubsystemNamespace}" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
        <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <http-invoker security-realm="ApplicationRealm"/>
        </host>
    </server>
    ...
</subsystem>

15.1.6. Configuring a server using the management CLI

This procedure explains how to manage servers in the Undertow subsystem using the management CLI. You can update existing servers, create new ones, or delete servers as needed.

Note

You can also configure a server using the management console by navigating to Configuration Subsystems Web (Undertow) Server.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Update an existing server

    /subsystem=undertow/server=default-server:write-attribute(name=default-host,value=default-host)
    reload
  2. Create a new server

    /subsystem=undertow/server=new-server:add
    reload
  3. Delete a server

    /subsystem=undertow/server=new-server:remove
    reload

15.1.7. Access logging

You can configure access logging on each host you define.

Two access logging options are available: standard access logging and console access logging.

Note that the additional processing required for access logging can affect system performance.

15.1.7.1. Standard Access logging

Standard access logging writes log entries to a log file.

By default, the log file is stored in the directory standalone/log/access_log.log.

To enable standard access logging, add the access-log setting to the host for which you want to capture access log data. The following CLI command illustrates the configuration on the default host in the default JBoss EAP server:

/subsystem=undertow/server=default-server/host=default-host/setting=access-log:add
Note

You must reload the server after enabling standard access logging.

By default, the access log record includes the following data:

  • Remote host name
  • Remote logical user name (always -)
  • Remote user that was authenticated
  • The date and time of the request, in Common Log Format
  • The first line of the request
  • The HTTP status code of the response
  • The number of bytes sent, excluding HTTP headers

This set of data is defined as the common pattern. Another pattern, combined, is also available. In addition to the data logged in the common pattern, the combined pattern includes the referer and user agent from the incoming header.

You can change the data logged using the pattern attribute. The following CLI command illustrates updating the pattern attribute to use the combined pattern:

/subsystem=undertow/server=default-server/host=default-host/setting=access-log:write-attribute(name=pattern,value="combined"
Note

You must reload the server after updating the pattern attribute.

Table 15.1. Available patterns
PatternDescription

%a

Remote IP address

%A

Local IP address

%b

Bytes sent, excluding HTTP headers or - if no bytes were sent

%B

Bytes sent, excluding HTTP headers

%h

Remote host name

%H

Request protocol

%l

Remote logical username from identd (always returns -; included for Apache access log compatibility)

%m

Request method

%p

Local port

%q

Query string (excluding the ? character)

%r

First line of the request

%s

HTTP status code of the response

%t

Date and time, in Common Log Format format

%u

Remote user that was authenticated

%U

Requested URL path

%v

Local server name

%D

Time taken to process the request, in milliseconds

%T

Time taken to process the request, in seconds

%I

Current Request thread name (can compare later with stack traces)

common

%h %l %u %t "%r" %s %b

combined

%h %l %u %t "%r" %s %b "%{i,Referer}" "%{i,User-Agent}"

You can also write information from the cookie, the incoming header and response header, or the session. The syntax is modeled after the Apache syntax:

  • %{i,xxx} for incoming headers
  • %{o,xxx} for outgoing response headers
  • %{c,xxx} for a specific cookie
  • %{r,xxx} where xxx is an attribute in the ServletRequest
  • %{s,xxx} where xxx is an attribute in the HttpSession

Additional configuration options are available for this log. For more information see "access-log Attributes" in the appendix.

15.1.7.2. Console access logging

Console access logging writes data to stdout as structured as JSON data.

Each access log record is a single line of data. You can capture this data for processing by log aggregation systems.

To configure console access logging, add the console-access-log setting to the host for which you want to capture access log data. The following CLI command illustrates the configuration on the default host in the default JBoss EAP server:

/subsystem=undertow/server=default-server/host=default-host/setting=console-access-log:add

By default, the console access log record includes the following data:

Table 15.2. Default console access log data
Log data field nameDescription

eventSource

The source of the event in the request

hostName

The JBoss EAP host that processed the request

bytesSent

The number of bytes the JBoss EAP server sent in response to the request

dateTime

The date and time that the request was processed by the JBoss EAP server

remoteHost

The IP address of the machine where the request originated

remoteUser

The user name associated with the remote request

requestLine

The request submitted

responseCode

The HTTP response code returned by the JBoss EAP server

Default properties are always included in the log output. You can use the attributes attribute to change the labels of the default log data, and in some cases to change the data configuration. You can also use the attributes attribute to add additional log data to the output.

Table 15.3. Available console access log data
Log data field nameDescriptionFormat

authentication-type

The authentication type used to authenticate the user associated with the request. Default label: authenticationType Use the key option to change the label for this property.

authentication-type{} authentication-type={key="authType"}

bytes-sent

The number of bytes returned for the request, excluding HTTP headers. Default label: bytesSent Use the key option to change the label for this property.

bytes-sent={} bytes-sent={key="sent-bytes"}

date-time

The date and time that the request was received and processed. Default label: dateTime Use the key option to change the label for this property. Use the date-format to define the pattern used to format the date-time record. The pattern must be a Java SimpleDateFormatter pattern. Use the time-zone option to specify the time zone used to format the date and/or time data if the date-format option is defined. This value must be a valid java.util.TimeZone.

date-time={key="<keyname>", date-format="<date-time format>"} date-time={key="@timestamp", date-format="yyyy-MM-dd’T’HH:mm:ssSSS"}

host-and-port

The host and port queried by the request. Default label: hostAndPort Use the key option to change the label for this property.

host-and-port{} host-and-port={key="port-host"}

local-ip

The IP address of the local connection. Use the key option to change the label for this property. Default label: localIp Use the key option to change the label for this property.

local-ip{} local-ip{key=”localIP”}

local-port

The port of the local connection. Default label: localPort Use the key option to change the label for this property.

local-port{} local-port{key=”LocalPort”}

local-server-name

The name of the local server that processed the request. Default label: localServerName Use the key option to change the label for this property.

local-server-name {} local-server-name {key=LocalServerName}

path-parameter

One or more path or URI parameters included in the request. The names property is a comma-separated list of names used to resolve the exchange values. Use the key-prefix property to make the keys unique. If the key-prefix is specified, the prefix is prepended to the name of each path parameter in the output.

path-parameter{names={store,section}} path-parameter{names={store,section}, key-prefix=”my-”}

predicate

The name of the predicate context. The names property is a comma-separated list of names used to resolve the exchange values. Use the key-prefix property to make the keys unique. If the key-prefix is specified, the prefix is prepended to the name of each path parameter in the output.

predicate{names={store,section}} predicate{names={store,section}, key-prefix=”my-”}

query-parameter

One or query parameters included in the request. The names property is a comma-separated list of names used to resolve the exchange values. Use the key-prefix property to make the keys unique. If the key-prefix is specified, the prefix is prepended to the name of each path parameter in the output.

query-parameter{names={store,section}} query-parameter{names={store,section}, key-prefix=”my-”}

query-string

The query string of the request. Default label: queryString Use the key option to change the label for this property. Use the include-question-mark property to specify whether the query string should include the question mark. By default, the question mark is not included.

query-string{} query-string{key=”QueryString”, include-question-mark=”true”}

relative-path

The relative path of the request. Default label: relativePath Use the key option to change the label for this property.

relative-path{} relative-path{key=”RelativePath”}

remote-host

The remote host name. Default label: remoteHost Use the key option to change the label for this property.

remote-host{} remote-host{key=”RemoteHost”}

remote-ip

The remote IP address. Default label: remoteIp Use the key options to change the label for this property. Use the obfuscated property to obfuscate the IP address in the output log record. The default value is false.

remote-ip{} remote-ip{key=”RemoteIP”, obfuscated=”true”}

remote-user

Remote user that was authenticated. Default label: remoteUser Use the key options to change the label for this property.

remote-user{} remote-user{key=”RemoteUser”}

request-header

The name of a request header. The key for the structured data is the name of the header; the value is the value of the named header. The names property is a comma-separated list of names used to resolve the exchange values. Use the key-prefix property to make the keys unique. If the key-prefix is specified, the prefix is prepended to the name of the request headers in the log output.

request-header{names={store,section}} request-header{names={store,section}, key-prefix=”my-”}

request-line

The request line. Default label: requestLine Use the key option to change the label for this property.

request-line{} request-line{key=”Request-Line”}

request-method

The request method. Default label: requestMethod Use the key option to change the label for this property.

request-method{} request-method{key=”RequestMethod”}

request-path

The relative path for the request. Default label: requestPath Use the key option to change the label for this property.

request-path{} request-path{key=”RequestPath”}

request-protocol

The protocol for the request. Default label: requestProtocol Use the key option to change the label for this property.

request-protocol{} request-protocol{key=”RequestProtocol”}

request-scheme

The URI scheme of the request. Default label: requestScheme Use the key option to change the label for this property.

request-scheme{} request-scheme{key=”RequestScheme”}

request-url

The original request URI. Includes host name, protocol, and so forth, if specified by the client. Default label: requestUrl Use the key option to change the label for this property.

request-url{} request-url{key=”RequestURL”}

resolved-path

The resolved path. Default Label: resolvedPath Use the key option to change the label for this property.

resolved-path{} resolved-path{key=”ResolvedPath”}

response-code

The response code. Default label: responseCode Use the key option to change the label for this property.

response-code{} response-code{key=”ResponseCode”}

response-header

The name of a response header. The key for the structured data is the name of the header; the value is the value of the named header. The names property is a comma-separated list of names used to resolve the exchange values. Use the key-prefix property to make the keys unique. If the key-prefix is specified, the prefix is prepended to the name of the request headers in the log output.

response-header{names={store,section}} response-header{names={store,section}, key-prefix=”my-”}

response-reason-phrase

The text reason for the response code. Default label: responseReasonPhrase Use the key option to change the label for this property.

response-reason-phrase{} response-reason-phrase{key=”ResponseReasonPhrase”}

response-time

The time used to process the request. Default label: responseTime Use the key option to change the label for this property. The default time unit is MILLISECONDS. Available time units include: * NANOSECONDS * MICROSECONDS * MILLISECONDS * SECONDS

response-time{} response-time{key=”ResponseTime”, time-unit=SECONDS}

secure-exchange

Indicates whether the exchange was secure. Default label: secureExchange Use the key option to change the label for this property.

secure-exchange{} secure-exchange{key=”SecureExchange”}

ssl-cipher

The SSL cipher for the request. Default label: sslCipher Use the key option to change the label for this property.

ssl-cipher{} ssl-cipher{key=”SSLCipher”}

ssl-client-cert

The SSL client certificate for the request. Default label: sslClientCert Use the key option to change the label for this property.

ssl-client-cert{} ssl-client-cert{key=”SSLClientCert”}

ssl-session-id

The SSL session id of the request. Default label: sslSessionId Use the key option to change the label for this property.

ssl-session-id{} stored-response

The stored response to the request. Default label: storedResponse Use the key option to change the label for this property.

stored-response{} stored-response{key=”StoredResponse”}

thread-name

The thread name of the current thread. Default label: threadName Use the key option to change the label for this property.

thread-name{} thread-name{key=”ThreadName”}

transport-protocol

You can use the metadata attribute to configure additional arbitrary data to include in the access log record. The value of the metadata attribute is a set of key:value pairs that defines the data to include in the access log record. The value in a pair can be a management model expression. Management model expressions are resolved when the server is started or reloaded. Key-value pairs are comma-separated.

The following CLI command demonstrates an example of a complex console log configuration, including additional log data, customization of log data, and additional metadata:

/subsystem=undertow/server=default-server/host=default-host/setting=console-access-log:add(metadata={"@version"="1", "qualifiedHostName"=${jboss.qualified.host.name:unknown}}, attributes={bytes-sent={}, date-time={key="@timestamp", date-format="yyyy-MM-dd'T'HH:mm:ssSSS"}, remote-host={}, request-line={}, response-header={key-prefix="responseHeader", names=["Content-Type"]}, response-code={}, remote-user={}})

The resulting access log record would resemble the following additional JSON data (Note: the example output below is formatted for readability; in an actual record, all data would be output as a single line):

{
    "eventSource":"web-access",
    "hostName":"default-host",
    "@version":"1",
    "qualifiedHostName":"localhost.localdomain",
    "bytesSent":1504,
    "@timestamp":"2019-05-02T11:57:37123",
    "remoteHost":"127.0.0.1",
    "remoteUser":null,
    "requestLine":"GET / HTTP/2.0",
    "responseCode":200,
    "responseHeaderContent-Type":"text/html"
}

The following command illustrates updates to the log data after activating the console access log:

/subsystem=undertow/server=default-server/host=default-host/setting=console-access-log:write-attribute(name=attributes,value={bytes-sent={}, date-time={key="@timestamp", date-format="yyyy-MM-dd'T'HH:mm:ssSSS"}, remote-host={}, request-line={}, response-header={key-prefix="responseHeader", names=["Content-Type"]}, response-code={}, remote-user={}})

The following command illustrates updates to the custom metadata after activating the console access log:

/subsystem=undertow/server=default-server/host=default-host/setting=console-access-log:write-attribute(name=metadata,value={"@version"="1", "qualifiedHostName"=${jboss.qualified.host.name:unknown}})

15.2. Configuring a servlet container

A servlet container provides all servlet, JavaServer Pages Jakarta Server Pages, and WebSocket-related configuration, including session-related settings. While most servers will only need a single servlet container, it is possible to configure multiple servlet containers by adding additional servlet-container elements. Having multiple servlet containers enables behavior such as allowing multiple deployments to be deployed to the same context path on different virtual hosts.

Note

Much of the configuration provided by the servlet container can be individually overridden by deployed applications using their web.xml file.

15.2.1. The default undertow subsystem configuration

JBoss EAP provides a servlet container by default. This reference provides the default configuration of the Undertow subsystem, including the servlet container.

<subsystem xmlns="{UndertowSubsystemNamespace}">
  <buffer-cache name="default"/>
  <server name="default-server">
    ...
  </server>
  <servlet-container name="default">
    <jsp-config/>
    <websockets/>
  </servlet-container>
  ...
</subsystem>

15.2.2. Managing servlet containers using the management CLI and management console

This procedure explains how to manage servlet containers in the Undertow subsystem using the management CLI and the management console. You can update existing servlet containers, create new ones, or delete servlet containers as needed.

Prerequisites

  • You have access to the management CLI.
  • You have access to the management console.
  • You have Permissions to modify server configurations.

Managing servlet containers in the Undertow subsystem using the management Console

You can also configure a servlet container using the management console by navigating to Configuration Subsystems Web (Undertow) Servlet Container.

Managing servlet containers in the Undertow subsystem using the management CLI

The following examples show how to configure a servlet container using the management CLI

Procedure

  1. Connect to the management CLI:
  2. Run the following command to update the servlet container’s attribute:

         ----
         /subsystem=undertow/servlet-container=default:write-attribute(name=ignore-flush,value=true)
         ----
  3. Reload the server to apply the changes: +

         ----
         reload
         ----

Creating a new servlet container

  1. Connect to the management CLI:
  2. Run the following command to create a new servlet container:

         ----
         /subsystem=undertow/servlet-container=new-servlet-container:add
         ----
  3. Reload the server to apply the changes:

         ----
         reload
         ----

Deleting a servlet container

  1. Connect to the management CLI.
  2. Run the following command to delete the servlet container:

         ----
         /subsystem=undertow/servlet-container=new-servlet-container:remove
         ----
  3. Reload the server to apply the changes:

         ----
         reload
         ----

15.3. Configuring a servlet extension

Servlet extensions allow you to hook into the servlet deployment process and modify aspects of a servlet deployment. This can be useful in cases where you need to add additional authentication mechanisms to a deployment or use native Undertow handlers as part of a servlet deployment.

To create a custom servlet extension, it is necessary to implement the io.undertow.servlet.ServletExtension interface and then add the name of your implementation class to the META-INF/services/io.undertow.servlet.ServletExtension file in the deployment. You also need to include the compiled class file of the ServletExtension implementation. When Undertow deploys the servlet, it loads all the services from the deployments class loader and then invokes their handleDeployment methods.

An Undertow DeploymentInfo structure, which contains a complete and mutable description of the deployment, is passed to this method. You can modify this structure to change any aspect of the deployment.

The DeploymentInfo structure is the same structure that is used by the embedded API, so in effect a ServletExtension has the same amount of flexibility that you have when using Undertow in embedded mode.

15.4. Configuring Handlers

JBoss EAP allows you to configure two types of handlers:

  • File Handlers
  • Reverse-Proxy Handlers

File handlers serve static files. Each file handler must be attached to a location in a virtual host. Reverse-proxy handlers allow JBoss EAP to serve as a high-performance reverse proxy.

15.4.1. The default undertow subsystem configuration for configuring Handlers

JBoss EAP provides a file handler by default. This reference provides the default configuration of the Undertow subsystem for Handlers.

<subsystem xmlns="{UndertowSubsystemNamespace}" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
    <buffer-cache name="default"/>
    <server name="default-server">
        ...
    </server>
    <servlet-container name="default">
        ...
    </servlet-container>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
</subsystem>

15.4.2. Managing file Handlers using the management CLI

This procedure explains how to manage file handlers in the Undertow subsystem using the management CLI. You can update existing file handlers, create new ones, or delete file handlers as needed.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  • Updating an Existing File Handler

    1. Connect to the management CLI.
    2. Run the following command to update the file handler’s attribute:

      ----
      /subsystem=undertow/configuration=handler/file=welcome-content:write-attribute(name=case-sensitive,value=true)
      ----
    3. Reload the server to apply the changes:

      ----
      reload
      ----
  • Creating a New File Handler

    1. Connect to the management CLI.
    2. Run the following command to create a new file handler:

      ----
      /subsystem=undertow/configuration=handler/file=new-file-handler:add(path="${jboss.home.dir}/welcome-content")
      ----
      [WARNING]
      ====
      If you set a file handler's `path` directly to a file instead of a directory, any `location` elements that reference that file handler must not end with a forward slash (`/`). Otherwise, the server will return a `404 - Not Found` response.
      ====
  • Deleting a File Handler

    1. Connect to the management CLI.
    2. Run the following command to delete the file handler:

      ----
      /subsystem=undertow/configuration=handler/file=new-file-handler:remove
      ----
    3. Reload the server to apply the changes:

      ----
      reload
      ----

15.5. Configuring Filters

A filter enables some aspect of a request to be modified and can use predicates to control when a filter executes. Some common use cases for filters include setting headers or doing GZIP compression.

Note

A filter is functionally equivalent to a global valve used in JBoss EAP 6.

The following types of filters can be defined:

  • custom-filter
  • error-page
  • expression-filter
  • gzip
  • mod-cluster
  • request-limit
  • response-header
  • rewrite

15.5.1. Managing file Handlers using the management CLI and management console

This procedure explains how to manage filters in the Undertow subsystem using the management CLI and the management console. You can update existing filters, create new ones, or delete filters as needed.

Prerequisites

  • You have access to the management CLI.
  • You have access to the management console.
  • You have permissions to modify server configurations.

Managing file Handlers using the management console

You can configure a filter using the management console by navigating to Configuration Subsystems Web (Undertow) Filters.

Managing file Handlers using the management CLI

The following procedure shows how to configure a filter using the management CLI

Procedure

  • Updating an existing Filter

    1. Connect to the management CLI.
    2. Run the following command to update the filter’s attribute:

      ----
      /subsystem=undertow/configuration=filter/response-header=myHeader:write-attribute(name=header-value,value="JBoss-EAP")
      ----
    3. Reload the server to apply the changes:

      ----
      reload
      ----
  • Creating a new Filter

    1. Connect to the management CLI.
    2. Run the following command to create a new filter:

      ----
      /subsystem=undertow/configuration=filter/response-header=new-response-header:add(header-name=new-response-header,header-value="My Value")
      ----
  • Deleting a Filter

    1. Connect to the management CLI.
    2. Run the following command to delete the filter:

      ----
      /subsystem=undertow/configuration=filter/response-header=new-response-header:remove
      ----
    3. Reload the server to apply the changes:

      ----
      reload
      ----

15.5.1.1. Configuring the buffer-request Handler

A request from the client or the browser consists of two parts: the header and the body. In a typical situation, the header and the body are sent to JBoss EAP without any delays in between. However, if the header is sent first and then after few seconds, the body is sent, there is a delay sending the complete request. This scenario creates a thread in JBoss EAP to show as waiting to execute the complete request.

The delay caused in sending the header and the body of the request can be corrected using the buffer-request handler. The buffer-request handler attempts to consume the request from a non-blocking IO thread before allocating it to a worker thread. When no buffer-request handler is added, the thread allocation to the worker thread happens directly. However, when the buffer-request handler is added, the handler attempts to read the amount of data that it can buffer in a non-blocking manner using the IO thread before allocating it to the worker thread.

You can use the following management CLI commands to configure the buffer-request handler:

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Run the following command to add the buffer-request handler:

       ----
       /subsystem=undertow/configuration=filter/expression-filter=buf:add(expression="buffer-request(buffers=1)")
       ----
  2. Attach the handler to your server and host by running:

       ----
       /subsystem=undertow/server=default-server/host=default-host/filter-ref=buf:add
       ----
  3. Calculate the buffer request size:

    `Total_size = num_buffers {MultiplicationSign} buffer_size`
    Where:
    • Total_size is the size of data that will be buffered before the request is dispatched to a worker thread.
    • num_buffers is the number of buffers, set by the buffers parameter on the handler (in this example, it’s set to 1).
    • buffer_size is the size of each buffer, set in the io subsystem (default is 16KB per request).

      Warning

      Avoid configuring very large buffer requests, or else you might run out of memory.

  4. Reload the server to apply the changes:

       ----
       reload
       ----

15.5.1.2. Understanding the SameSite attribute

Use the SameSite attribute to define the accessibility of a cookie within the same site. This attribute helps prevent cross-site request forgery attacks because browsers do not send the cookie with cross-site requests.

You can configure the SameSite attribute for cookies with SameSiteCookieHandler in the undertow subsystem. With this configuration, you do not need to change your application code.

15.5.1.3. SameSiteCookieHandler parameters

The following table details the parameters of SameSiteCookieHandler:

Table 15.4. SameSiteCookieHandler parameters
Parameter NamePresenceDescription

add-secure-for-none

Optional

Adds a Secure attribute to the cookie when the SameSite attribute mode is None. The default value is true.

case-sensitive

Optional

Indicates if the cookie-pattern is case-sensitive. The default value is true.

cookie-pattern

Optional

Accepts a regex pattern for the cookie name. If not specified, the attribute SameSite=<specified-mode> is added to all cookies.

enable-client-checker

Optional

Verifies if client applications are incompatible with the SameSite=None attribute. The default value is true.

If you use this default value and set the SameSite attribute mode to a value other than None, the parameter ignores verification.

To prevent issues with incompatible clients, this parameter skips setting the SameSite attribute mode to None and has no effect. For requests from compatible clients, the parameter applies the SameSite attribute mode None as expected.

mode

Mandatory

Specifies the SameSite attribute mode, which can be set to Strict, Lax, or None.

To improve security against cross-site request forgery attacks, some browsers set the default SameSite attribute mode to Lax. For detailed information, see the Additional resources section.

SameSiteCookieHandler adds the attribute SameSite=<specified-mode> to cookies that match cookie-pattern or to all cookies when cookie-pattern is not specified. The cookie-pattern is matched according to the value set in case-sensitive.

Before configuring the SameSite attribute, consider the following points:

  • Review your application to identify whether the cookies require the SameSite attribute and whether those cookies need to be secured.
  • Setting the SameSite attribute mode to None for all cookies can make the application more susceptible to attacks.

15.5.1.4. Configuring SameSiteCookieHandler using an expression Filter

This procedure explains how to configure SameSiteCookieHandler on the server using an expression-filter.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Create a new expression-filter with the SameSiteCookieHandler:

    ----
    /subsystem=undertow/configuration=filter/expression-filter=addSameSiteLax:add(expression="path-prefix('/mypathprefix') -> samesite-cookie(Lax)")
    ----
  2. Enable the expression-filter in the undertow web server:

    ----
    /subsystem=undertow/server=default-server/host=default-host/filter-ref=addSameSiteLax:add
    ----

15.5.1.5. Configuring SameSiteCookieHandler using a configuration file

This procedure explains how to configure SameSiteCookieHandler in your application by adding the undertow-handlers.conf file.

Prerequisites

  • Access to your application’s source code.
  • Permissions to modify application files.

Procedure

  1. Add an undertow-handlers.conf file to your WAR’s WEB-INF directory.
  2. In the undertow-handlers.conf file, add the following command with a specific SameSiteCookieHandler parameter:

    ----
    samesite-cookie(mode=<mode>)
    ----
    Replace `<mode>` with one of the valid values: `Strict`, `Lax`, or `None`.
    You can also configure other `SameSiteCookieHandler` parameters, such as `cookie-pattern`, `case-sensitive`, `enable-client-checker`, or `add-secure-for-none`.
  3. Save the file and redeploy your application if necessary.

15.6. Configure the default welcome web application

JBoss EAP includes a default Welcome application, which displays at the root context on port 8080 by default.

There is a default server preconfigured in Undertow that serves up the welcome content.

Default Undertow Subsystem Configuration

<subsystem xmlns="{UndertowSubsystemNamespace}" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
    ...
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
        <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <http-invoker security-realm="ApplicationRealm"/>
        </host>
    </server>
    ...
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
</subsystem>

The default server, default-server, has a default host, default-host, configured. The default host is configured to handle requests to the server’s root, using the <location> element, with the welcome-content file handler. The welcome-content handler serves up the content in the location specified in the path property.

This default Welcome application can be replaced with your own web application. This can be configured in one of two ways:

You can also disable the welcome content.

15.6.1. Changing the welcome-content file Handler

This procedure explains how to change the welcome-content file handler to point to your own web application.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Modify the existing welcome-content file handler’s path to point to your new content:

       ----
       /subsystem=undertow/configuration=handler/file=welcome-content:write-attribute(name=path,value="/path/to/your/content")
       ----

    Alternatively, you can create a new file handler to be used by the server’s root:

       ----
       /subsystem=undertow/configuration=handler/file=NEW_FILE_HANDLER:add(path="/path/to/your/content")
       /subsystem=undertow/server=default-server/host=default-host/location=\/:write-attribute(name=handler,value=NEW_FILE_HANDLER)
       ----
  2. Reload the server for the changes to take effect:

       ----
       reload
       ----

15.6.2. Changing the default-web-module

This procedure explains how to map a deployed web application to the server’s root by changing the default-web-module.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Map your deployed web application to the server’s root.

       ----
       /subsystem=undertow/server=default-server/host=default-host:write-attribute(name=default-web-module,value=your-application.war)
       ----
  2. Reload the server for the changes to take effect:
   ----
   reload
   ----

15.6.3. Disabling the default welcome web application

This procedure explains how to disable the default welcome web application by removing the location entry for the root context.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Remove the location entry / for the default-host:

       ----
       /subsystem=undertow/server=default-server/host=default-host/location=\/:remove
       ----
  2. Reload the server for the changes to take effect:

       ----
       reload
       ----

15.7. Configuring HTTP session timeout

The HTTP session timeout defines the period of inactive time needed to declare an HTTP session invalid. For example, when a user accesses an application deployed to JBoss EAP, an HTTP session is created. If that user then attempts to access the application again after the HTTP session timeout period has elapsed, the original HTTP session will be invalidated, and the user will be forced to create a new HTTP session. This may result in the loss of unpersisted data or require the user to reauthenticate.

The HTTP session timeout is typically configured in an application’s web.xml file. However, a default HTTP session timeout can also be specified within JBoss EAP. The server’s timeout value will apply to all deployed applications unless overridden by an application’s web.xml file.

The server value is specified in the default-session-timeout property within the servlet-container section of the undertow subsystem. The value of default-session-timeout is specified in minutes, and the default is 30.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Connect to the management CLI.
  2. Set the default-session-timeout value.

    Run the following command to set the `default-session-timeout` value to `60` minutes:
    ----
    /subsystem=undertow/servlet-container=default:write-attribute(name=default-session-timeout, value=60)
    ----
  3. Reload the server for the changes to take effect.

    ----
    reload
    ----

15.8. Configuring HTTP-only session management cookies

Session management cookies can be accessed by both HTTP APIs and non-HTTP APIs such as JavaScript. JBoss EAP offers the ability to send the HttpOnly header as part of the Set-Cookie response header to the client, usually a browser. In supported browsers, enabling this header tells the browser to prevent accessing session management cookies through non-HTTP APIs. Restricting session management cookies to only HTTP APIs can help mitigate the threat of session cookie theft via cross-site scripting attacks. To enable this behavior, the http-only attribute should be set to true.

Important

Using the HttpOnly header does not actually prevent cross-site scripting attacks by itself; it merely notifies the browser. The browser must also support HttpOnly for this behavior to take effect.

Important

Using the http-only attribute only applies the restriction to session management cookies and not to other browser cookies.

The http-only attribute is set in two places in the undertow subsystem:

  • In the servlet container as a session cookie setting.
  • In the host section of the server as a single sign-on property.

15.8.2. Configuring http-only for the host single sign-On

This procedure explains how to configure the http-only property for the host single sign-on in the undertow subsystem.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Add the single sign-on setting to the host.

    Run the following command:
    ----
    /subsystem=undertow/server=default-server/host=default-host/setting=single-sign-on:add
    ----
  2. Set the http-only attribute to true.

    Run the following command:
    ----
    /subsystem=undertow/server=default-server/host=default-host/setting=single-sign-on:write-attribute(name=http-only,value=true)
    ----
  3. Reload the server for the changes to take effect.

    ----
    reload
    ----

15.9. Understanding HTTP/2 in undertow

Undertow allows for the use of the HTTP/2 standard, which reduces latency by compressing headers and multiplexing many streams over the same TCP connection. It also provides the ability for a server to push resources to the client before it has requested them, leading to faster page loads.

Be aware that HTTP/2 only works with clients and browsers that also support the HTTP/2 standard.

Important

Most modern browsers enforce HTTP/2 over a secured TLS connection, known as h2, and may not support HTTP/2 over plain HTTP, known as h2c. It is still possible to configure JBoss EAP to use HTTP/2 with h2c, without using HTTPS and only using plain HTTP with HTTP upgrade. In that case, you can simply enable HTTP/2 in the HTTP listener:

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=enable-http2,value=true)

15.9.1. Configuring HTTP/2 in Undertow

This procedure explains how to enable HTTP/2 in Undertow by configuring the HTTPS listener.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Enable HTTP/2 on the HTTPS listener:

       ----
       /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=enable-http2,value=true)
       ----
  2. Reload the server to apply the changes:

       ----
       reload
       ----
Note

In order to utilize HTTP/2 with the elytron subsystem, you will need to ensure that the configured ssl-context in the https-listener of the Undertow is configured as modifiable. This can be achieved by setting the wrap attribute of the appropriate server-ssl-context to false. By default, the wrap attribute is set to false. This is required by Undertow to make modifications in the ssl-context about the ALPN. If the provided ssl-context is not writable, ALPN cannot be used and the connection falls back to HTTP/1.1.

Additional resources

For more information on the HTTPS listener and configuring Undertow to use HTTPS for web applications, see Configure One-way and Two-way SSL/TLS for Applications in How to Configure Server Security.

15.9.2. ALPN support when using HTTP/2

When using HTTP/2 over a secured TLS connection, a TLS stack that supports the Application-Layer Protocol Negotiation (ALPN) TLS protocol extension is required. Obtaining this stack varies based on the installed JDK.

  • As of Java 9, the JDK supports ALPN natively; however, using the ALPN TLS protocol extension support from the OpenSSL provider should also result in better performance when using Java 9 or later.

Instructions for installing OpenSSL to obtain the ALPN TLS protocol extension support are available in Install OpenSSL from JBoss Core Services. The standard system OpenSSL is supported on Red Hat Enterprise Linux 8, and no additional OpenSSL is required.

Once OpenSSL has been installed, follow the instructions in xref:"configure-jboss-eap-to-use-openssl_configuring-the-web-server-undertow-in-jboss-eap"[Configure JBoss EAP to Use OpenSSL].

15.9.3. Verifying HTTP/2 usage

To verify that Undertow is using HTTP/2, you will need to inspect the headers coming from Undertow. Navigate to your JBoss EAP instance using https, for example https://localhost:8443, and use your browser’s developer tools to inspect the headers. Some browsers, for example Google Chrome, will show HTTP/2 pseudo headers, such as :path, :authority, :method and :scheme, when using HTTP/2. Other browsers, for example Firefox and Safari, will report the status or version of the header as HTTP/2.0.

15.10. Understanding the RequestDumping Handler

The RequestDumping handler, io.undertow.server.handlers.RequestDumpingHandler, logs the details of request and corresponding response objects handled by Undertow within JBoss EAP.

Important

While this handler can be useful for debugging, it may also log sensitive information. Please keep this in mind when enabling this handler.

Note

The RequestDumping handler replaces the RequestDumperValve from JBoss EAP 6.

You can configure a RequestDumping handler either at the server level directly in JBoss EAP or within an individual application.

15.10.1. Configuring a RequestDumping Handler on the server

This procedure explains how to configure a RequestDumping handler at the server level using an expression filter.

Prerequisites

  • You have access to the management CLI.
  • You have permissions to modify server configurations.

Procedure

  1. Create a new expression filter with the RequestDumping handler:

       ----
       /subsystem=undertow/configuration=filter/expression-filter=requestDumperExpression:add(expression="dump-request")
       ----
  2. Enable the expression filter in the Undertow web server:

       ----
       /subsystem=undertow/server=default-server/host=default-host/filter-ref=requestDumperExpression:add
       ----
Important

All requests and corresponding responses handled by the Undertow web server will be logged when enabling the RequestDumping handler as an expression filter in this manner.

15.10.1.1. Configuring a Handler for specific URLs

In addition to logging all requests, you can also use an expression filter to only log requests and corresponding responses for specific URLs. This can be accomplished using a predicate in your expression such as path, path-prefix, or path-suffix. For example, if you want to log all requests and corresponding responses to /myApplication/test, you can use the expression "path(/myApplication/test) -> dump-request" instead of the expression "dump-request" when creating your expression filter. This will only direct requests with a path exactly matching /myApplication/test to the RequestDumping handler.

15.10.1.2. Configuring a RequestDumping Handler within an application

This procedure explains how to configure a RequestDumping handler within an individual application. This limits the scope of the handler to that specific application.

Procedure

  1. Create or edit the WEB-INF/undertow-handlers.conf file in your application.
  2. To log all requests and corresponding responses for this application, add the following line to undertow-handlers.conf:

    ----
    dump-request
    ----

    Alternatively, to log requests and responses for specific URLs within the application, use a predicate in your expression.

    Replace `/test` with the desired path relative to the application's context root.
    [source]
    ----
    path(/test) -> dump-request
    ----
    Note

    When using predicates such as path, path-prefix, or path-suffix in expressions defined in the application’s WEB-INF/undertow-handlers.conf, the value used is relative to the context root of the application.

    For example, if the application’s context root is /myApplication and you use the expression path(/test) dump-request, it will log requests to /myApplication/test.

  3. Redeploy the application if necessary to apply the changes.

15.12. Additional resources

Configuring HTTPS

Tuning the Undertow Subsystem

  • For tips on optimizing performance for the undertow subsystem, see the Undertow Subsystem Tuning section of the Performance tuning for JBoss EAP.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.