Skip to content

Commit

Permalink
Parse Retry-After header responses that include decimal points (OpenF…
Browse files Browse the repository at this point in the history
…eign#980)

rfc7231 section 7.1.3 states that the Retry-After header can return delay-seconds value
that is a non-negative decimal integer, representing time in seconds.

Some servers return the second delay with a decimal point.  Eg instead of 2 they return 2.0
This patch handles this case where the server has included a decimal point in their response.
  • Loading branch information
rdwallis authored and velo committed Jun 30, 2019
1 parent 6f1c0fe commit 88f50b1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
22 changes: 12 additions & 10 deletions core/src/main/java/feign/codec/ErrorDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,22 @@
*/
package feign.codec;

import static feign.FeignException.errorStatus;
import static feign.Util.RETRY_AFTER;
import static feign.Util.checkNotNull;
import static java.util.Locale.US;
import static java.util.concurrent.TimeUnit.SECONDS;

import feign.FeignException;
import feign.Response;
import feign.RetryableException;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import feign.FeignException;
import feign.Response;
import feign.RetryableException;
import static feign.FeignException.errorStatus;
import static feign.Util.RETRY_AFTER;
import static feign.Util.checkNotNull;
import static java.util.Locale.US;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
* Allows you to massage an exception into a application-specific one. Converting out to a throttle
Expand Down Expand Up @@ -143,7 +144,8 @@ public Date apply(String retryAfter) {
if (retryAfter == null) {
return null;
}
if (retryAfter.matches("^[0-9]+$")) {
if (retryAfter.matches("^[0-9]+\\.?0*$")) {
retryAfter = retryAfter.replaceAll("\\.0*$", "");
long deltaMillis = SECONDS.toMillis(Long.parseLong(retryAfter));
return new Date(currentTimeMillis() + deltaMillis);
}
Expand Down
15 changes: 11 additions & 4 deletions core/src/test/java/feign/codec/RetryAfterDecoderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
*/
package feign.codec;

import org.junit.Test;
import java.text.ParseException;
import feign.codec.ErrorDecoder.RetryAfterDecoder;
import static feign.codec.ErrorDecoder.RetryAfterDecoder.RFC822_FORMAT;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import feign.codec.ErrorDecoder.RetryAfterDecoder;

import java.text.ParseException;

import org.junit.Test;

public class RetryAfterDecoderTest {

private RetryAfterDecoder decoder = new RetryAfterDecoder(RFC822_FORMAT) {
Expand Down Expand Up @@ -48,4 +50,9 @@ public void rfc822Parses() throws ParseException {
public void relativeSecondsParses() throws ParseException {
assertEquals(RFC822_FORMAT.parse("Sun, 2 Jan 2000 00:00:00 GMT"), decoder.apply("86400"));
}

@Test
public void relativeSecondsParseDecimalIntegers() throws ParseException {
assertEquals(RFC822_FORMAT.parse("Sun, 2 Jan 2000 00:00:00 GMT"), decoder.apply("86400.0"));
}
}

0 comments on commit 88f50b1

Please sign in to comment.