Spring Boot在无效的If-Modified-Since值上抛出异常

mic*_*cko 5 java spring http spring-mvc

对不起,如果这是错误的地方.

根据定义的http规范:http://tools.ietf.org/html/rfc7232#section-3.3

如果接收的字段值不是有效的HTTP日期,或者请求方法既不是GET也不是HEAD,则接收方必须忽略If-Modified-Since标头字段.

Spring Boot没有这样做.它抛出一个IllegalArgumentException,它不会被检查标头值的代码处理.

以下是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");
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您发送标头If-Modified-Since:0,您将获得异常,而不是返回http规范中定义的新GET响应.

有没有其他人认为这是一个问题?

小智 3

我已经看到了这个问题,最近创建了一个票证提交了一个 PR来修复它同时,您可以使用过滤器删除标头来解决该问题,例如

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);
}
Run Code Online (Sandbox Code Playgroud)