-
Notifications
You must be signed in to change notification settings - Fork 656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for dynamic proxy configuration at the HTTP protocol level #3593
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@raccoonback Thanks for the PR!
public final HttpClient proxyWhen(BiConsumer<HttpClientConfig, ? super ProxyProvider.TypeSpec> proxyBuilder) { | ||
Objects.requireNonNull(proxyBuilder, "proxyBuilder"); | ||
HttpClient dup = duplicate(); | ||
dup.configuration() | ||
.deferredConf( | ||
config -> { | ||
ProxyProvider.TypeSpec spec = ProxyProvider.builder(); | ||
proxyBuilder.accept(config, spec); | ||
|
||
if (((ProxyProvider.Validator) spec).isConfiguredCorrectly()) { | ||
ProxyProvider proxyProvider = ((ProxyProvider.Builder) spec).build(); | ||
config.proxyProvider(proxyProvider); | ||
} | ||
|
||
return Mono.just(config); | ||
} | ||
); | ||
return dup; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think if we use Mono
for the proxy configuration? Imagine that you need to resolve something else before providing the proxy configuration.
Something similar to what we have for the headers e.g. this test case:
Line 85 in c5e4a96
.headersWhen(h -> login(disposableServer.port()).map(token -> h.set("Authorization", token))) |
public final HttpClient proxyWhen(BiConsumer<HttpClientConfig, ? super ProxyProvider.TypeSpec> proxyBuilder) { | |
Objects.requireNonNull(proxyBuilder, "proxyBuilder"); | |
HttpClient dup = duplicate(); | |
dup.configuration() | |
.deferredConf( | |
config -> { | |
ProxyProvider.TypeSpec spec = ProxyProvider.builder(); | |
proxyBuilder.accept(config, spec); | |
if (((ProxyProvider.Validator) spec).isConfiguredCorrectly()) { | |
ProxyProvider proxyProvider = ((ProxyProvider.Builder) spec).build(); | |
config.proxyProvider(proxyProvider); | |
} | |
return Mono.just(config); | |
} | |
); | |
return dup; | |
} | |
public final HttpClient proxyWhen(BiFunction<HttpClientConfig, ? super ProxyProvider.TypeSpec, | |
Mono<? extends ProxyProvider.Builder>> proxyBuilder) { | |
Objects.requireNonNull(proxyBuilder, "proxyBuilder"); | |
HttpClient dup = duplicate(); | |
dup.configuration().deferredConf(config -> { | |
Mono<? extends ProxyProvider.Builder> mono = proxyBuilder.apply(config, ProxyProvider.builder()); | |
return mono == Mono.<ProxyProvider.Builder>empty() ? | |
Mono.just(config) : | |
mono.map(builder -> { | |
config.proxyProvider(builder.build()); | |
return config; | |
}); | |
}); | |
return dup; | |
} |
Motivation
The existing
proxy(...)
andnoProxy()
methods are static, applying the same configuration to all requests. In scenarios where proxy behavior needs to change dynamically based on the request (e.g., host-specific proxies, conditional proxy usage), this static approach is insufficient.The
proxyWhen(...)
method fills this gap by allowing developers to provide a function that resolves proxy settings dynamically during request execution.Description
proxyWhen(BiConsumer<HttpClientConfig, ? super ProxyProvider.TypeSpec>)
method toHttpClient
.HttpClientConfig
function.proxyWhen(...)
evaluates the configuration function for each HTTP request, allowing fine-grained control over proxy settings.proxyWhen(...)
is used, any static proxy configurations applied viaproxy(...)
ornoProxy()
will be ignored.deferredConfig
to set theproxyProvider
at theHttpClientConnect.connect()
stage.Backward Compatibility
proxyWhen(...)
method is additive and does not interfere with existing static configurations unless explicitly used.proxy(...)
andnoProxy()
) remain unchanged and fully functional.Related Issue