* Issue #4719 Keep previous charencoding if not set in content type Signed-off-by: Jan Bartel <janb@webtide.com> * Issue #4719 - Adding unit tests for charset reset/change Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
4837fe1c86
commit
3f7d04ff96
|
@ -1017,11 +1017,9 @@ public class Response implements HttpServletResponse
|
|||
_contentType = contentType;
|
||||
_mimeType = MimeTypes.CACHE.get(contentType);
|
||||
|
||||
String charset;
|
||||
if (_mimeType != null && _mimeType.getCharset() != null && !_mimeType.isCharsetAssumed())
|
||||
String charset = MimeTypes.getCharsetFromContentType(contentType);
|
||||
if (charset == null && _mimeType != null && _mimeType.isCharsetAssumed())
|
||||
charset = _mimeType.getCharsetString();
|
||||
else
|
||||
charset = MimeTypes.getCharsetFromContentType(contentType);
|
||||
|
||||
if (charset == null)
|
||||
{
|
||||
|
@ -1030,11 +1028,10 @@ public class Response implements HttpServletResponse
|
|||
case NOT_SET:
|
||||
break;
|
||||
case INFERRED:
|
||||
case SET_CONTENT_TYPE:
|
||||
if (isWriting())
|
||||
{
|
||||
_mimeType = null;
|
||||
_contentType = _contentType + ";charset=" + _characterEncoding;
|
||||
_mimeType = MimeTypes.CACHE.get(_contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1042,11 +1039,12 @@ public class Response implements HttpServletResponse
|
|||
_characterEncoding = null;
|
||||
}
|
||||
break;
|
||||
case SET_CONTENT_TYPE:
|
||||
case SET_LOCALE:
|
||||
case SET_CHARACTER_ENCODING:
|
||||
{
|
||||
_contentType = contentType + ";charset=" + _characterEncoding;
|
||||
_mimeType = null;
|
||||
_mimeType = MimeTypes.CACHE.get(_contentType);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1056,10 +1054,10 @@ public class Response implements HttpServletResponse
|
|||
else if (isWriting() && !charset.equalsIgnoreCase(_characterEncoding))
|
||||
{
|
||||
// too late to change the character encoding;
|
||||
_mimeType = null;
|
||||
_contentType = MimeTypes.getContentTypeWithoutCharset(_contentType);
|
||||
if (_characterEncoding != null)
|
||||
if (_characterEncoding != null && (_mimeType == null || !_mimeType.isCharsetAssumed()))
|
||||
_contentType = _contentType + ";charset=" + _characterEncoding;
|
||||
_mimeType = MimeTypes.CACHE.get(_contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -501,6 +501,17 @@ public class ResponseTest
|
|||
response.setCharacterEncoding("ISO-8859-1");
|
||||
assertEquals("text/xml;charset=utf-8", response.getContentType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentEncodingViaContentTypeChange() throws Exception
|
||||
{
|
||||
Response response = getResponse();
|
||||
response.setContentType("text/html;charset=Shift_Jis");
|
||||
assertEquals("Shift_Jis", response.getCharacterEncoding());
|
||||
|
||||
response.setContentType("text/xml");
|
||||
assertEquals("Shift_Jis", response.getCharacterEncoding());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterEncodingContentType() throws Exception
|
||||
|
@ -624,7 +635,7 @@ public class ResponseTest
|
|||
|
||||
response.setContentType("wrong/answer;charset=utf-8");
|
||||
response.setContentType("foo/bar");
|
||||
assertEquals("foo/bar", response.getContentType());
|
||||
assertEquals("foo/bar;charset=utf-8", response.getContentType());
|
||||
response.setContentType("wrong/answer;charset=utf-8");
|
||||
response.getWriter();
|
||||
response.setContentType("foo2/bar2;charset=utf-16");
|
||||
|
|
|
@ -43,6 +43,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.BadMessageException;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.tools.HttpTester;
|
||||
import org.eclipse.jetty.logging.StacklessLogging;
|
||||
import org.eclipse.jetty.server.Dispatcher;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
|
@ -60,6 +62,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
@ -101,6 +104,7 @@ public class ErrorPageTest
|
|||
_context.addServlet(UnavailableServlet.class, "/unavailable/*");
|
||||
_context.addServlet(DeleteServlet.class, "/delete/*");
|
||||
_context.addServlet(ErrorAndStatusServlet.class, "/error-and-status/*");
|
||||
_context.addServlet(ErrorContentTypeCharsetWriterInitializedServlet.class, "/error-mime-charset-writer/*");
|
||||
|
||||
HandlerWrapper noopHandler = new HandlerWrapper()
|
||||
{
|
||||
|
@ -140,6 +144,36 @@ public class ErrorPageTest
|
|||
_server.join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorOverridesMimeTypeAndCharset() throws Exception
|
||||
{
|
||||
StringBuilder rawRequest = new StringBuilder();
|
||||
rawRequest.append("GET /error-mime-charset-writer/ HTTP/1.1\r\n");
|
||||
rawRequest.append("Host: test\r\n");
|
||||
rawRequest.append("Connection: close\r\n");
|
||||
rawRequest.append("Accept: */*\r\n");
|
||||
rawRequest.append("Accept-Charset: *\r\n");
|
||||
rawRequest.append("\r\n");
|
||||
|
||||
String rawResponse = _connector.getResponse(rawRequest.toString());
|
||||
System.out.println(rawResponse);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
assertThat(response.getStatus(), is(595));
|
||||
String actualContentType = response.get(HttpHeader.CONTENT_TYPE);
|
||||
// should not expect to see charset line from servlet
|
||||
assertThat(actualContentType, not(containsString("charset=US-ASCII")));
|
||||
String body = response.getContent();
|
||||
|
||||
assertThat(body, containsString("ERROR_PAGE: /595"));
|
||||
assertThat(body, containsString("ERROR_MESSAGE: 595"));
|
||||
assertThat(body, containsString("ERROR_CODE: 595"));
|
||||
assertThat(body, containsString("ERROR_EXCEPTION: null"));
|
||||
assertThat(body, containsString("ERROR_EXCEPTION_TYPE: null"));
|
||||
assertThat(body, containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$ErrorContentTypeCharsetWriterInitializedServlet-"));
|
||||
assertThat(body, containsString("ERROR_REQUEST_URI: /error-mime-charset-writer/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorOverridesStatus() throws Exception
|
||||
{
|
||||
|
@ -612,6 +646,18 @@ public class ErrorPageTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class ErrorContentTypeCharsetWriterInitializedServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
response.setContentType("text/html; charset=US-ASCII");
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.println("Intentionally using sendError(595)");
|
||||
response.sendError(595);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ErrorAndStatusServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.ByteBuffer;
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -73,6 +74,65 @@ public class ResponseHeadersTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class CharsetResetToJsonMimeTypeServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// We set an initial desired behavior.
|
||||
response.setContentType("text/html; charset=US-ASCII");
|
||||
PrintWriter writer = response.getWriter();
|
||||
|
||||
// We reset the response, as we don't want it to be HTML anymore.
|
||||
response.reset();
|
||||
|
||||
// switch to json operation
|
||||
// The use of application/json is always assumed to be UTF-8
|
||||
// and should never have a `charset=` entry on the `Content-Type` response header
|
||||
response.setContentType("application/json");
|
||||
writer.println("{ \"what\": \"should this be?\" }");
|
||||
}
|
||||
}
|
||||
|
||||
public static class CharsetChangeToJsonMimeTypeServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// We set an initial desired behavior.
|
||||
response.setContentType("text/html; charset=US-ASCII");
|
||||
|
||||
// switch to json behavior.
|
||||
// The use of application/json is always assumed to be UTF-8
|
||||
// and should never have a `charset=` entry on the `Content-Type` response header
|
||||
response.setContentType("application/json");
|
||||
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.println("{ \"what\": \"should this be?\" }");
|
||||
}
|
||||
}
|
||||
|
||||
public static class CharsetChangeToJsonMimeTypeSetCharsetToNullServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// We set an initial desired behavior.
|
||||
|
||||
response.setContentType("text/html; charset=us-ascii");
|
||||
PrintWriter writer = response.getWriter();
|
||||
|
||||
// switch to json behavior.
|
||||
// The use of application/json is always assumed to be UTF-8
|
||||
// and should never have a `charset=` entry on the `Content-Type` response header
|
||||
response.setContentType("application/json");
|
||||
// attempt to indicate that there is truly no charset meant to be used in the response header
|
||||
response.setCharacterEncoding(null);
|
||||
|
||||
writer.println("{ \"what\": \"should this be?\" }");
|
||||
}
|
||||
}
|
||||
|
||||
private static Server server;
|
||||
private static LocalConnector connector;
|
||||
|
||||
|
@ -89,6 +149,9 @@ public class ResponseHeadersTest
|
|||
|
||||
context.addServlet(new ServletHolder(new SimulateUpgradeServlet()), "/ws/*");
|
||||
context.addServlet(new ServletHolder(new MultilineResponseValueServlet()), "/multiline/*");
|
||||
context.addServlet(CharsetResetToJsonMimeTypeServlet.class, "/charset/json-reset/*");
|
||||
context.addServlet(CharsetChangeToJsonMimeTypeServlet.class, "/charset/json-change/*");
|
||||
context.addServlet(CharsetChangeToJsonMimeTypeSetCharsetToNullServlet.class, "/charset/json-change-null/*");
|
||||
|
||||
server.start();
|
||||
}
|
||||
|
@ -149,4 +212,64 @@ public class ResponseHeadersTest
|
|||
expected = expected.trim(); // trim whitespace at start/end
|
||||
assertThat("Response Header X-example", response.get("X-Example"), is(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharsetResetToJsonMimeType() throws Exception
|
||||
{
|
||||
HttpTester.Request request = new HttpTester.Request();
|
||||
request.setMethod("GET");
|
||||
request.setURI("/charset/json-reset/");
|
||||
request.setVersion(HttpVersion.HTTP_1_1);
|
||||
request.setHeader("Connection", "close");
|
||||
request.setHeader("Host", "test");
|
||||
|
||||
ByteBuffer responseBuffer = connector.getResponse(request.generate());
|
||||
// System.err.println(BufferUtil.toUTF8String(responseBuffer));
|
||||
HttpTester.Response response = HttpTester.parseResponse(responseBuffer);
|
||||
|
||||
// Now test for properly formatted HTTP Response Headers.
|
||||
assertThat("Response Code", response.getStatus(), is(200));
|
||||
// The Content-Type should not have a charset= portion
|
||||
assertThat("Response Header Content-Type", response.get("Content-Type"), is("application/json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharsetChangeToJsonMimeType() throws Exception
|
||||
{
|
||||
HttpTester.Request request = new HttpTester.Request();
|
||||
request.setMethod("GET");
|
||||
request.setURI("/charset/json-change/");
|
||||
request.setVersion(HttpVersion.HTTP_1_1);
|
||||
request.setHeader("Connection", "close");
|
||||
request.setHeader("Host", "test");
|
||||
|
||||
ByteBuffer responseBuffer = connector.getResponse(request.generate());
|
||||
// System.err.println(BufferUtil.toUTF8String(responseBuffer));
|
||||
HttpTester.Response response = HttpTester.parseResponse(responseBuffer);
|
||||
|
||||
// Now test for properly formatted HTTP Response Headers.
|
||||
assertThat("Response Code", response.getStatus(), is(200));
|
||||
// The Content-Type should not have a charset= portion
|
||||
assertThat("Response Header Content-Type", response.get("Content-Type"), is("application/json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharsetChangeToJsonMimeTypeSetCharsetToNull() throws Exception
|
||||
{
|
||||
HttpTester.Request request = new HttpTester.Request();
|
||||
request.setMethod("GET");
|
||||
request.setURI("/charset/json-change-null/");
|
||||
request.setVersion(HttpVersion.HTTP_1_1);
|
||||
request.setHeader("Connection", "close");
|
||||
request.setHeader("Host", "test");
|
||||
|
||||
ByteBuffer responseBuffer = connector.getResponse(request.generate());
|
||||
// System.err.println(BufferUtil.toUTF8String(responseBuffer));
|
||||
HttpTester.Response response = HttpTester.parseResponse(responseBuffer);
|
||||
|
||||
// Now test for properly formatted HTTP Response Headers.
|
||||
assertThat("Response Code", response.getStatus(), is(200));
|
||||
// The Content-Type should not have a charset= portion
|
||||
assertThat("Response Header Content-Type", response.get("Content-Type"), is("application/json"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue