-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
21.0.4
-
x86_64
-
linux
ADDITIONAL SYSTEM INFORMATION :
Same on both Linux based and Windows, Java JDK or JRE version 21.0.4.
A DESCRIPTION OF THE PROBLEM :
The Java HttpClient does not respect the default retry limit of 3 retries in case of invalid credentials supplied with a basic auth scheme.
Instead of 3 retries it goes for 4 times.
This is true even if custom retry limit is used e.g. 1 or 2 (via property "jdk.httpclient.auth.retrylimit"), it goes for 2 or 3 retries respective.
The number of retries is always one larger than the actual limit.
Seems the problem lies in this condition in the source code for the client: https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L323
The condition in the if statement "au.retries > retry_limit" should maybe be "au.retries >= retry_limit"?
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the following code (that on purpose uses invalid credentials) and observe the printouts and the error message printed from the exception stack:
public static void main(String[] args)
{
int i[] = { 1 };
try
{
HttpClient client = HttpClient.newBuilder()
.authenticator(new Authenticator(){
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
System.out.println("Try no. " + i[0]++);
return new PasswordAuthentication("username", "password".toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(new URI("https://postman-echo.com/basic-auth"))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
}
catch (Exception e)
{
System.out.println("Happens at try no. " + --i[0]);
e.printStackTrace();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expected scenario is that an exception will happen at try no. 3 as that is the default limit for retries according to https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L55
Other scenario that might be expected is that a try no. 4 will not happen i.e. the client will not try to get the credentials for the 4th time if the limit is 3.
ACTUAL -
The retry logic does not stop at 3 and it actually goes for another round and executes 4 times thus retrieving and executing the request 4 times instead of 3 times according to the limit and here is also the error from the exception than states that the limit is 3 but 4 times were tried.
CUSTOMER SUBMITTED WORKAROUND :
No workaround as of now.
It seems the condition check in is wrong?
I should be ">=" instead of ">"?
FREQUENCY : always
Same on both Linux based and Windows, Java JDK or JRE version 21.0.4.
A DESCRIPTION OF THE PROBLEM :
The Java HttpClient does not respect the default retry limit of 3 retries in case of invalid credentials supplied with a basic auth scheme.
Instead of 3 retries it goes for 4 times.
This is true even if custom retry limit is used e.g. 1 or 2 (via property "jdk.httpclient.auth.retrylimit"), it goes for 2 or 3 retries respective.
The number of retries is always one larger than the actual limit.
Seems the problem lies in this condition in the source code for the client: https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L323
The condition in the if statement "au.retries > retry_limit" should maybe be "au.retries >= retry_limit"?
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the following code (that on purpose uses invalid credentials) and observe the printouts and the error message printed from the exception stack:
public static void main(String[] args)
{
int i[] = { 1 };
try
{
HttpClient client = HttpClient.newBuilder()
.authenticator(new Authenticator(){
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
System.out.println("Try no. " + i[0]++);
return new PasswordAuthentication("username", "password".toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(new URI("https://postman-echo.com/basic-auth"))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
}
catch (Exception e)
{
System.out.println("Happens at try no. " + --i[0]);
e.printStackTrace();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expected scenario is that an exception will happen at try no. 3 as that is the default limit for retries according to https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L55
Other scenario that might be expected is that a try no. 4 will not happen i.e. the client will not try to get the credentials for the 4th time if the limit is 3.
ACTUAL -
The retry logic does not stop at 3 and it actually goes for another round and executes 4 times thus retrieving and executing the request 4 times instead of 3 times according to the limit and here is also the error from the exception than states that the limit is 3 but 4 times were tried.
CUSTOMER SUBMITTED WORKAROUND :
No workaround as of now.
It seems the condition check in is wrong?
I should be ">=" instead of ">"?
FREQUENCY : always