Skip to content

Allow custom NettyRoutingFilter & NettyWriteResponseFilter - Reactive Gateway #3823

Closed as not planned
@usrivastava92

Description

@usrivastava92

Is your feature request related to a problem? Please describe.
We have encountered scenarios where the current customization options for the Netty HTTP client within the Spring Cloud Gateway's reactive framework are insufficient. Specifically, we need the ability to apply proxy settings on a per-route basis. For instance, some routes require the HTTP client to use a proxy, while others do not. Achieving this is more straightforward by creating a custom Netty routing filter that extends the base Netty routing filter and overrides the getHttpClient method. Similarly, we might want to add specific behaviors to the Netty write response filter, such as recording the time to the first byte. While the existing configuration options are generally satisfactory, it would be beneficial if the Gateway's auto-configuration could conditionally register the default Netty routing filter only when no custom filter is defined.

Describe the solution you'd like

@Component
class CustomNettyRoutingFilter(
    httpClient: HttpClient,
    headersFiltersProvider: ObjectProvider<List<HttpHeadersFilter>>,
    properties: HttpClientProperties,
) : NettyRoutingFilter(httpClient, headersFiltersProvider, properties) {
    private val httpClientCacheMap = ConcurrentHashMap<String, HttpClient>()
    override fun getHttpClient(
        route: Route,
        exchange: ServerWebExchange,
    ): HttpClient? {
        val proxyUrl = route.metadata[PROXY_URL_ATTR] as? String
        val client = super.getHttpClient(route, exchange)
        return httpClientCacheMap.getOrPut(route.id) {
            when {
                proxyUrl?.isNotBlank() == true -> {
                    val url = URI.create(proxyUrl)
                    client.proxy {
                        it.type(ProxyProvider.Proxy.HTTP)
                            .host(url.host)
                            .port(url.port)
                    }
                }
                else -> client
            }
        }
    }
}

By adding a @ConditionalOnMissingBean annotation to the GatewayAutoConfiguration, we can ensure that the default Netty routing filter is registered only when a custom filter is not present, thus achieving the desired flexibility.

Describe alternatives you've considered
One alternative would be to disable global filters and use custom filter with this behaviour, but this is not ideal as global filters play a crucial role in the Spring Cloud Gateway framework.

Additional context
This feature request aims to enhance the configurability and flexibility of the Spring Cloud Gateway, particularly in environments where route-specific customization is necessary. We welcome any additional insights or suggestions that could further improve this proposal.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions