From 7b5dacc59c38d1ca5fdd57428929c71d882a80f9 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 8 Apr 2020 14:55:03 +0200 Subject: [PATCH] Issue #4760 Response.setLocale should override previous Signed-off-by: Jan Bartel --- .../eclipse/jetty/http/encoding.properties | 4 +- .../org/eclipse/jetty/server/Response.java | 2 +- .../eclipse/jetty/server/ResponseTest.java | 62 +++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties b/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties index 3f2d2dd358eb..9fbebc6191a0 100644 --- a/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties +++ b/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties @@ -1,6 +1,6 @@ # Mapping of mime type to inferred or assumed charset -# inferred charsets are used for encoding/decoding and explicitly set in associated metadata -# assumed charsets are used for encoding/decoding, but are not set in associated metadata +# inferred charsets are used for encoding/decoding and explicitly set in Content-Type +# assumed charsets are used for encoding/decoding, but are not set in Content-Type # In this file, assumed charsets are indicated with a leading '-' text/html=utf-8 diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 4a8eea246a9c..c4441d9ff802 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -107,7 +107,7 @@ private enum EncodingFrom NOT_SET, INFERRED, SET_LOCALE, SET_CONTENT_TYPE, SET_CHARACTER_ENCODING } - private static final EnumSet __localeOverride = EnumSet.of(EncodingFrom.NOT_SET, EncodingFrom.INFERRED); + private static final EnumSet __localeOverride = EnumSet.of(EncodingFrom.NOT_SET, EncodingFrom.INFERRED, EncodingFrom.SET_LOCALE); private static final EnumSet __explicitCharset = EnumSet.of(EncodingFrom.SET_LOCALE, EncodingFrom.SET_CHARACTER_ENCODING); public Response(HttpChannel channel, HttpOutput out) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index 273e28ad360c..cb79e3f39233 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -53,6 +53,7 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.AbstractEndPoint; import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -473,6 +474,67 @@ public void testResponseCharacterEncoding() throws Exception response.getWriter(); assertThat("iso-8859-1", Matchers.equalTo(response.getCharacterEncoding())); } + + @Test + public void testLocaleAndContentTypeEncoding() throws Exception + { + _server.stop(); + MimeTypes.getInferredEncodings().put("text/html", "iso-8859-1"); + ContextHandler handler = new ContextHandler(); + handler.addLocaleEncoding("ja", "euc-jp"); + handler.addLocaleEncoding("zh_CN", "gb18030"); + _server.setHandler(handler); + handler.setHandler(new DumpHandler()); + _server.start(); + + Response response = getResponse(); + response.getHttpChannel().getRequest().setContext(handler.getServletContext()); + + response.setContentType("text/html"); + assertEquals("iso-8859-1", response.getCharacterEncoding()); + + // setLocale should change character encoding based on + // locale-encoding-mapping-list + response.setLocale(Locale.JAPAN); + assertEquals("euc-jp", response.getCharacterEncoding()); + + // setLocale should change character encoding based on + // locale-encoding-mapping-list + response.setLocale(Locale.CHINA); + assertEquals("gb18030", response.getCharacterEncoding()); + + // setContentType here doesn't define character encoding + response.setContentType("text/html"); + assertEquals("gb18030", response.getCharacterEncoding()); + + // setCharacterEncoding should still be able to change encoding + response.setCharacterEncoding("utf-8"); + assertEquals("utf-8", response.getCharacterEncoding()); + + // setLocale should not override explicit character encoding request + response.setLocale(Locale.JAPAN); + assertEquals("utf-8", response.getCharacterEncoding()); + + // setContentType should still be able to change encoding + response.setContentType("text/html;charset=gb18030"); + assertEquals("gb18030", response.getCharacterEncoding()); + + // setCharacterEncoding should still be able to change encoding + response.setCharacterEncoding("utf-8"); + assertEquals("utf-8", response.getCharacterEncoding()); + + // getWriter should freeze the character encoding + PrintWriter pw = response.getWriter(); + assertEquals("utf-8", response.getCharacterEncoding()); + + // setCharacterEncoding should no longer be able to change the encoding + response.setCharacterEncoding("iso-8859-1"); + assertEquals("utf-8", response.getCharacterEncoding()); + + // setLocale should not override explicit character encoding request + response.setLocale(Locale.JAPAN); + assertEquals("utf-8", response.getCharacterEncoding()); + } @Test public void testContentTypeCharacterEncoding() throws Exception