Skip to content

Commit

Permalink
Issue #4719 - Adding unit tests for charset reset/change
Browse files Browse the repository at this point in the history
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
  • Loading branch information
joakime committed Mar 26, 2020
1 parent b730529 commit e0b322f
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
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;
Expand All @@ -60,6 +62,7 @@

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;
Expand Down Expand Up @@ -101,6 +104,7 @@ public void init() throws Exception
_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()
{
Expand Down Expand Up @@ -140,6 +144,36 @@ public void destroy() throws Exception
_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
{
Expand Down Expand Up @@ -612,6 +646,18 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -73,6 +74,64 @@ protected void doGet(HttpServletRequest req, HttpServletResponse response) throw
}
}

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");
response.setCharacterEncoding(null);

writer.println("{ \"what\": \"should this be?\" }");
}
}

private static Server server;
private static LocalConnector connector;

Expand All @@ -89,6 +148,9 @@ public static void startServer() throws Exception

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();
}
Expand Down Expand Up @@ -149,4 +211,64 @@ public void testMultilineResponseHeaderValue() throws Exception
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-reset-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"));
}
}

0 comments on commit e0b322f

Please sign in to comment.