Skip to content
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

The www-authenticate header breaks JettyClientHttpConnector #34112

Closed
Canocles opened this issue Dec 18, 2024 · 4 comments
Closed

The www-authenticate header breaks JettyClientHttpConnector #34112

Canocles opened this issue Dec 18, 2024 · 4 comments
Assignees
Labels
for: external-project Needs a fix in external project in: web Issues in web modules (web, webmvc, webflux, websocket) status: invalid An issue that we don't feel is valid

Comments

@Canocles
Copy link

Environment

  • Spring Boot 3.3.4
  • Spring Web 6.1.1

Old surroundings where it operated

  • Spring Boot 2.7.18
  • Spring Web 5.3.31

Context

We have migrated from a Spring Boot 2.7.18 environment to Spring Boot 3.3.4 and we have detected that when using a WebClient with a JettyClientHttpConnector with its respective HttpClient, in case the call comes with a www-authenticate header, it gets stuck making calls infinitely and we never get it to respond correctly.

All this worked perfectly in the Spring Boot 2 version, where upon receiving the call, it responded without any problem.

We have tried to define the connector in the most basic way possible, but it always breaks, in case of receiving that header.

Examples and Code

We have done the test, simply by telling WebClient that the connector we are going to use is JettyClientHttpConnector.

WebClient client =
        WebClient.builder()
            .baseUrl("your-url-with-www-authenticate-header-in-response")
            .clientConnector(new JettyClientHttpConnector())
            .build();

If you try to make a call to any endpoint, which returns the www-authenticate header, you can see that it gets stuck and after passing the timeout, it throws this error:

onFillableFail SslConnection@10ac4a81::SocketChannelEndPoint@4d09e077[{l=null,r=null,CLOSED,fill=-,flush=-,to=7/30000}{io=1/1,kio=-1,kro=-1}]->[SslConnection@10ac4a81{NOT_HANDSHAKING,eio=-1/-1,di=-1,fill=INTERESTED,flush=IDLE}~>{l=null,r=null,CLOSED,fill=FI,flush=-,to=30027/30000}=>HttpConnectionOverHTTP@46f46e11(l:null <-> r:null,closed=true)=>HttpChannelOverHTTP@11d2c7ca(exchange=null)[send=HttpSenderOverHTTP@4f015fae(req=QUEUED,failure=null)[HttpGenerator@3d8bec8d{s=START}],recv=HttpReceiverOverHTTP@69f1010a(ex=null,rsp=IDLE,failure=null)[HttpParser{s=START,0 of -1}]]]
java.nio.channels.ClosedChannelException: null
	at org.eclipse.jetty.io.FillInterest.onClose(FillInterest.java:147)
	at org.eclipse.jetty.io.AbstractEndPoint.onClose(AbstractEndPoint.java:336)
	at org.eclipse.jetty.io.SelectableChannelEndPoint.onClose(SelectableChannelEndPoint.java:165)
	at org.eclipse.jetty.io.AbstractEndPoint.onClose(AbstractEndPoint.java:326)
	at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:253)
	at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:217)
	at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:200)
	at org.eclipse.jetty.io.ssl.SslConnection$SslEndPoint.disconnect(SslConnection.java:1399)
	at org.eclipse.jetty.io.ssl.SslConnection$SslEndPoint.doShutdownOutput(SslConnection.java:1381)
	at org.eclipse.jetty.io.ssl.SslConnection$SslEndPoint.doClose(SslConnection.java:1449)
	at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:248)
	at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:217)
	at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:200)
	at org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP.close(HttpConnectionOverHTTP.java:298)
	at org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP.onIdleExpired(HttpConnectionOverHTTP.java:237)
	at org.eclipse.jetty.io.ssl.SslConnection.onIdleExpired(SslConnection.java:371)
	at org.eclipse.jetty.io.AbstractEndPoint.onIdleExpired(AbstractEndPoint.java:389)
	at org.eclipse.jetty.io.IdleTimeout.checkIdleTimeout(IdleTimeout.java:172)
	at org.eclipse.jetty.io.IdleTimeout.idleCheck(IdleTimeout.java:113)

Also, it seems to retry the call until finally the error appears, but the call gets hung up and never resolves.

[DEBUG] [ o.e.j.u.t.ReservedThreadExecutor: 348 ]  waiting for task
[DEBUG] [ com.zaxxer.hikari.pool.HikariPool: 405 ]  HikariPool-1 - Pool stats (total=10, active=0, idle=10, waiting=0)
[DEBUG] [ com.zaxxer.hikari.pool.HikariPool: 510 ]  HikariPool-1 - Fill pool skipped, pool has sufficient level or currently being filled.
[DEBUG] [ o.e.j.util.thread.QueuedThreadPool: 1015 ]  Evict check, period=60000ms QueuedThreadPool[HttpClient@7218bb00]@42681628{STARTED,8<=12<=200,i=3,r=-1,t=-67ms,q=0}[ReservedThreadExecutor@7457d199{capacity=16,threads=ThreadIdPool@397ce9d8{capacity=16}}]
[DEBUG] [ o.e.j.util.thread.QueuedThreadPool: 1033 ]  Evict skipped, threshold=59932ms in the future QueuedThreadPool[HttpClient@7218bb00]@42681628{STARTED,8<=12<=200,i=3,r=-1,t=-67ms,q=0}[ReservedThreadExecutor@7457d199{capacity=16,threads=ThreadIdPool@397ce9d8{capacity=16}}]
[DEBUG] [ o.e.j.u.t.ReservedThreadExecutor: 348 ]  waiting for task
[DEBUG] [ o.e.j.util.thread.QueuedThreadPool: 1015 ]  Evict check, period=60000ms QueuedThreadPool[HttpClient@7218bb00]@42681628{STARTED,8<=12<=200,i=3,r=-1,t=-74ms,q=0}[ReservedThreadExecutor@7457d199{capacity=16,threads=ThreadIdPool@397ce9d8{capacity=16}}]
[DEBUG] [ o.e.j.util.thread.QueuedThreadPool: 1033 ]  Evict skipped, threshold=59925ms in the future QueuedThreadPool[HttpClient@7218bb00]@42681628{STARTED,8<=12<=200,i=3,r=-1,t=-75ms,q=0}[ReservedThreadExecutor@7457d199{capacity=16,threads=ThreadIdPool@397ce9d8{capacity=16}}]
[DEBUG] [ com.zaxxer.hikari.pool.PoolBase: 133 ]  HikariPool-1 - Closing connection oracle.jdbc.driver.T4CConnection@24c9581b: (connection has passed maxLifetime)
[DEBUG] [ com.zaxxer.hikari.pool.HikariPool: 728 ]  HikariPool-1 - Added connection oracle.jdbc.driver.T4CConnection@c485e55
[DEBUG] [ com.zaxxer.hikari.pool.HikariPool: 405 ]  HikariPool-1 - Connection not added, stats (total=10, active=0, idle=10, waiting=0)

However, with exactly the same code in Spring Boot 2, it resolves the call without a problem.

Thanks for the support! :)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 18, 2024
@bclozel bclozel self-assigned this Dec 18, 2024
@bclozel
Copy link
Member

bclozel commented Dec 18, 2024

I can reproduce this behavior without Spring being involved. The "www-authenticate" header is not required, a 401 HTTP response is enough to trigger this behavior.

I've opened jetty/jetty.project#12652 and will close this issue. I'll reopen it if it turns out this is an integration issue on our side. Thanks for the report!

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Dec 18, 2024
@bclozel bclozel added status: invalid An issue that we don't feel is valid for: external-project Needs a fix in external project in: web Issues in web modules (web, webmvc, webflux, websocket) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 18, 2024
@Canocles
Copy link
Author

Thank you for your promptness! @bclozel

@bclozel
Copy link
Member

bclozel commented Dec 18, 2024

Thanks to Simone's comment on the Jetty issue, you can use this workaround in the meantime:

HttpClient httpClient = new HttpClient();
httpClient.start();
httpClient.getProtocolHandlers().remove(WWWAuthenticationProtocolHandler.NAME);

WebClient webClient = builder
		.clientConnector(new JettyClientHttpConnector(httpClient))
		.baseUrl("https://httpbin.org").build();

@Canocles
Copy link
Author

Thank you very much to both for your time.

Indeed, I have tried using the header removal in the same way you have done and everything seems to work as it should. For the moment, it is a good temporary solution.

Again, thanks for your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project Needs a fix in external project in: web Issues in web modules (web, webmvc, webflux, websocket) status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants