Hi,

I'd like to enable HTTP/2 on the management endpoints when they are exposed on a different port (set via management.server.port).

In particular I enabled the following configration

@Component
public class SecurityAuthTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addConnectorCustomizers(connector -> {
            connector.addUpgradeProtocol(new Http2Protocol());
        });
    }
}

Currently if the management port is not set, the actuators use the same web infrastructure, as such

curl --verbose --http2-prior-knowledge localhost:8080/actuator/health
$ curl --verbose --http2-prior-knowledge localhost:18080/actuator/health
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 18080 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f9a8e809200)
> GET /actuator/health HTTP/2
> Host: localhost:18080
> User-Agent: curl/7.64.1
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
< x-correlation-id: 2fd83d95-9d92-4f43-bb38-c755ae8f5022
< content-type: application/vnd.spring-boot.actuator.v3+json
< content-length: 168
< date: Thu, 01 Apr 2021 08:03:05 GMT
< 
* Connection #0 to host localhost left intact
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":499963174912,"free":55731302400,"threshold":10485760,"exists":true}},"ping":{"status":"UP"}}}* Closing connection 0

However when the management endpoints are exposed on a different port, this doesn't work.

curl --verbose --http2-prior-knowledge localhost:8081/actuator/health
$ curl --verbose --http2 localhost:8081/actuator/health
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> GET /actuator/health HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.64.1
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> 
< HTTP/1.1 200 
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Thu, 01 Apr 2021 07:54:22 GMT
< 
* Connection #0 to host localhost left intact
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":499963174912,"free":55733653504,"threshold":10485760,"exists":true}},"ping":{"status":"UP"}}}* Closing connection 0

However I supposed the customizer were also picked by org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer and run in the invokeCustomizers method :

https://github.com/spring-projects/spring-boot/blob/52b58f8b4754948537b0c1e68e3b9a06dfb0fb01/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java#L96-L99

However my customizer do not appear in this list.

Is there a way to enable HTTP/2 when the management enpoints are exposed on a different port ?


Spring Boot 2.4.4 OpenJDK 11.0.10 up to OpenJDK 16 Server Tomcat

Comment From: wilkinsona

This is a duplicate of https://github.com/spring-projects/spring-boot/issues/14302.

At the moment, you need to use a class like this:

package com.example.demo;

import org.apache.coyote.http2.Http2Protocol;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;

@ManagementContextConfiguration
class WebServerConfiguration {

    @Bean
    WebServerFactoryCustomizer<TomcatServletWebServerFactory> enableH2c() {
        return (factory) -> factory.addConnectorCustomizers((connector) -> 
            connector.addUpgradeProtocol(new Http2Protocol()));
    }

}

And register it in META-INF/spring.factories under the org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration key:

org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\
com.example.demo.WebServerConfiguration

Comment From: bric3

Ahhh thank you !

Thanks for linking the duplicate, it didn't showed up in my research.


I take this opportunity to express my gratitude to your work in general ! THANK YOU in capitals :)