Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot throwing exception on invalid If-Modified-Since value

Sorry if this is the wrong place for this.

According the http spec as defined: https://www.rfc-editor.org/rfc/rfc7232#section-3.3

A recipient MUST ignore the If-Modified-Since header field if the received field-value is not a valid HTTP-date, or if the request method is neither GET nor HEAD.

Spring Boot is not doing this. It is throwing an IllegalArgumentException that is not being handled by the code checking the header value.

Here is the conversion code in org.springframework.http.HttpHeaders.java

/**
 * Return the value of the {@code If-Modified-Since} header.
 * <p>The date is returned as the number of milliseconds since
 * January 1, 1970 GMT. Returns -1 when the date is unknown.
 */
public long getIfModifiedSince() {
    return getFirstDate(IF_MODIFIED_SINCE);
}

/**
 * Parse the first header value for the given header name as a date,
 * return -1 if there is no value, or raise {@link IllegalArgumentException}
 * if the value cannot be parsed as a date.
 */
public long getFirstDate(String headerName) {
    String headerValue = getFirst(headerName);
    if (headerValue == null) {
        return -1;
    }
    for (String dateFormat : DATE_FORMATS) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, Locale.US);
        simpleDateFormat.setTimeZone(GMT);
        try {
            return simpleDateFormat.parse(headerValue).getTime();
        }
        catch (ParseException ex) {
            // ignore
        }
    }
    throw new IllegalArgumentException("Cannot parse date value \"" + headerValue +
            "\" for \"" + headerName + "\" header");
}

So if you send the header If-Modified-Since:0 you will get an exception, instead of returning the fresh GET response as defined in the http spec.

Does anyone else see this as an issue?

like image 475
micko Avatar asked Nov 19 '15 14:11

micko


2 Answers

I've seen this and recently created a ticket and submitted a PR to fix it In the meantime you might be able work around the issue using a filter to remove the header, e.g.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {

        @Override
        public Enumeration<String> getHeaderNames() {
            List<String> hdrs = Collections.list(super.getHeaderNames())
                    .stream()
                    .filter(h -> !h.equals(IF_MODIFIED_SINCE))
                    .collect(Collectors.toList());

            return Collections.enumeration(hdrs);
        }
    };
    chain.doFilter(wrapper, response);
}
like image 68
danc Avatar answered Nov 20 '22 01:11

danc


encountered the same issue, using Spring - 4.2.5. upgraded to 4.2.6 -> issue solved.

like image 25
amazia Avatar answered Nov 20 '22 03:11

amazia