MockHttpServletRequest leniently handles invalid Accept-Language header

Issue: SPR-16454
This commit is contained in:
Juergen Hoeller 2018-02-02 11:34:22 +01:00
parent 7f96827ade
commit b3e21ec737
3 changed files with 52 additions and 41 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -473,7 +473,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
this.characterEncoding = mediaType.getCharset().name(); this.characterEncoding = mediaType.getCharset().name();
} }
} }
catch (Exception ex) { catch (IllegalArgumentException ex) {
// Try to get charset value anyway // Try to get charset value anyway
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
if (charsetIndex != -1) { if (charsetIndex != -1) {
@ -985,15 +985,19 @@ public class MockHttpServletRequest implements HttpServletRequest {
public void addHeader(String name, Object value) { public void addHeader(String name, Object value) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) { !this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
setContentType(value.toString()); setContentType(value.toString());
} }
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) && else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) { !this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) {
try {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString()); headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
setPreferredLocales(headers.getAcceptLanguageAsLocales()); setPreferredLocales(headers.getAcceptLanguageAsLocales());
}
catch (IllegalArgumentException ex) {
// Invalid Accept-Language format -> store plain header instead
doAddHeaderValue(name, value, true);
}
} }
else { else {
doAddHeaderValue(name, value, false); doAddHeaderValue(name, value, false);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -52,10 +52,6 @@ public class MockHttpServletRequestTests {
private static final String HOST = "Host"; private static final String HOST = "Host";
private static final String CONTENT_TYPE = "Content-Type";
private static final String IF_MODIFIED_SINCE = "If-Modified-Since";
private final MockHttpServletRequest request = new MockHttpServletRequest(); private final MockHttpServletRequest request = new MockHttpServletRequest();
@Rule @Rule
@ -121,7 +117,7 @@ public class MockHttpServletRequestTests {
String contentType = "test/plain"; String contentType = "test/plain";
request.setContentType(contentType); request.setContentType(contentType);
assertEquals(contentType, request.getContentType()); assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE)); assertEquals(contentType, request.getHeader(HttpHeaders.CONTENT_TYPE));
assertNull(request.getCharacterEncoding()); assertNull(request.getCharacterEncoding());
} }
@ -130,34 +126,34 @@ public class MockHttpServletRequestTests {
String contentType = "test/plain;charset=UTF-8"; String contentType = "test/plain;charset=UTF-8";
request.setContentType(contentType); request.setContentType(contentType);
assertEquals(contentType, request.getContentType()); assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE)); assertEquals(contentType, request.getHeader(HttpHeaders.CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding()); assertEquals("UTF-8", request.getCharacterEncoding());
} }
@Test @Test
public void contentTypeHeader() { public void contentTypeHeader() {
String contentType = "test/plain"; String contentType = "test/plain";
request.addHeader("Content-Type", contentType); request.addHeader(HttpHeaders.CONTENT_TYPE, contentType);
assertEquals(contentType, request.getContentType()); assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE)); assertEquals(contentType, request.getHeader(HttpHeaders.CONTENT_TYPE));
assertNull(request.getCharacterEncoding()); assertNull(request.getCharacterEncoding());
} }
@Test @Test
public void contentTypeHeaderUTF8() { public void contentTypeHeaderUTF8() {
String contentType = "test/plain;charset=UTF-8"; String contentType = "test/plain;charset=UTF-8";
request.addHeader("Content-Type", contentType); request.addHeader(HttpHeaders.CONTENT_TYPE, contentType);
assertEquals(contentType, request.getContentType()); assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE)); assertEquals(contentType, request.getHeader(HttpHeaders.CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding()); assertEquals("UTF-8", request.getCharacterEncoding());
} }
@Test // SPR-12677 @Test // SPR-12677
public void setContentTypeHeaderWithMoreComplexCharsetSyntax() { public void setContentTypeHeaderWithMoreComplexCharsetSyntax() {
String contentType = "test/plain;charset=\"utf-8\";foo=\"charset=bar\";foocharset=bar;foo=bar"; String contentType = "test/plain;charset=\"utf-8\";foo=\"charset=bar\";foocharset=bar;foo=bar";
request.addHeader("Content-Type", contentType); request.addHeader(HttpHeaders.CONTENT_TYPE, contentType);
assertEquals(contentType, request.getContentType()); assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE)); assertEquals(contentType, request.getHeader(HttpHeaders.CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding()); assertEquals("UTF-8", request.getCharacterEncoding());
} }
@ -166,7 +162,7 @@ public class MockHttpServletRequestTests {
request.setContentType("test/plain"); request.setContentType("test/plain");
request.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8");
assertEquals("test/plain", request.getContentType()); assertEquals("test/plain", request.getContentType());
assertEquals("test/plain;charset=UTF-8", request.getHeader(CONTENT_TYPE)); assertEquals("test/plain;charset=UTF-8", request.getHeader(HttpHeaders.CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding()); assertEquals("UTF-8", request.getCharacterEncoding());
} }
@ -175,7 +171,7 @@ public class MockHttpServletRequestTests {
request.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8");
request.setContentType("test/plain"); request.setContentType("test/plain");
assertEquals("test/plain", request.getContentType()); assertEquals("test/plain", request.getContentType());
assertEquals("test/plain;charset=UTF-8", request.getHeader(CONTENT_TYPE)); assertEquals("test/plain;charset=UTF-8", request.getHeader(HttpHeaders.CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding()); assertEquals("UTF-8", request.getCharacterEncoding());
} }
@ -302,6 +298,13 @@ public class MockHttpServletRequestTests {
Locale.forLanguageTag("en"), Locale.forLanguageTag("de")), actual); Locale.forLanguageTag("en"), Locale.forLanguageTag("de")), actual);
} }
@Test
public void invalidAcceptLanguageHeader() {
request.addHeader("Accept-Language", "en_US");
assertEquals(Locale.ENGLISH, request.getLocale());
assertEquals("en_US", request.getHeader("Accept-Language"));
}
@Test @Test
public void getServerNameWithDefaultName() { public void getServerNameWithDefaultName() {
assertEquals("localhost", request.getServerName()); assertEquals("localhost", request.getServerName());
@ -473,39 +476,39 @@ public class MockHttpServletRequestTests {
@Test @Test
public void httpHeaderDate() { public void httpHeaderDate() {
Date date = new Date(); Date date = new Date();
request.addHeader(IF_MODIFIED_SINCE, date); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, date);
assertEquals(date.getTime(), request.getDateHeader(IF_MODIFIED_SINCE)); assertEquals(date.getTime(), request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
} }
@Test @Test
public void httpHeaderTimestamp() { public void httpHeaderTimestamp() {
long timestamp = new Date().getTime(); long timestamp = new Date().getTime();
request.addHeader(IF_MODIFIED_SINCE, timestamp); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, timestamp);
assertEquals(timestamp, request.getDateHeader(IF_MODIFIED_SINCE)); assertEquals(timestamp, request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
} }
@Test @Test
public void httpHeaderRfcFormatedDate() { public void httpHeaderRfcFormatedDate() {
request.addHeader(IF_MODIFIED_SINCE, "Tue, 21 Jul 2015 10:00:00 GMT"); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, "Tue, 21 Jul 2015 10:00:00 GMT");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE)); assertEquals(1437472800000L, request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
} }
@Test @Test
public void httpHeaderFirstVariantFormatedDate() { public void httpHeaderFirstVariantFormatedDate() {
request.addHeader(IF_MODIFIED_SINCE, "Tue, 21-Jul-15 10:00:00 GMT"); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, "Tue, 21-Jul-15 10:00:00 GMT");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE)); assertEquals(1437472800000L, request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
} }
@Test @Test
public void httpHeaderSecondVariantFormatedDate() { public void httpHeaderSecondVariantFormatedDate() {
request.addHeader(IF_MODIFIED_SINCE, "Tue Jul 21 10:00:00 2015"); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, "Tue Jul 21 10:00:00 2015");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE)); assertEquals(1437472800000L, request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void httpHeaderFormatedDateError() { public void httpHeaderFormatedDateError() {
request.addHeader(IF_MODIFIED_SINCE, "This is not a date"); request.addHeader(HttpHeaders.IF_MODIFIED_SINCE, "This is not a date");
request.getDateHeader(IF_MODIFIED_SINCE); request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -455,7 +455,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
this.characterEncoding = mediaType.getCharset().name(); this.characterEncoding = mediaType.getCharset().name();
} }
} }
catch (Exception ex) { catch (IllegalArgumentException ex) {
// Try to get charset value anyway // Try to get charset value anyway
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
if (charsetIndex != -1) { if (charsetIndex != -1) {
@ -962,15 +962,19 @@ public class MockHttpServletRequest implements HttpServletRequest {
public void addHeader(String name, Object value) { public void addHeader(String name, Object value) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) { !this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
setContentType(value.toString()); setContentType(value.toString());
} }
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) && else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) { !this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) {
try {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString()); headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
setPreferredLocales(headers.getAcceptLanguageAsLocales()); setPreferredLocales(headers.getAcceptLanguageAsLocales());
}
catch (IllegalArgumentException ex) {
// Invalid Accept-Language format -> store plain header instead
doAddHeaderValue(name, value, true);
}
} }
else { else {
doAddHeaderValue(name, value, false); doAddHeaderValue(name, value, false);