Skip to content

Commit

Permalink
Bug 474366 - JSON response corrupted when default charset is not UTF-8
Browse files Browse the repository at this point in the history
Gzip filter must obey the response character encoding when
constructing a PrintWriter.
  • Loading branch information
mamacdon committed Aug 7, 2015
1 parent 8d3f532 commit d76d3fc
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 3 deletions.
Expand Up @@ -12,6 +12,7 @@

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;
Expand Down Expand Up @@ -88,9 +89,10 @@ public PrintWriter getWriter() throws IOException {
if (_servletOutputStream != null) {
throw new IllegalStateException();
}
((HttpServletResponse) getResponse()).setHeader("Content-Encoding", "gzip");
_servletOutputStream = new ServletOutputStreamWrapper(new GZIPOutputStream(getResponse().getOutputStream()));
_printWriter = new PrintWriter(_servletOutputStream);
HttpServletResponse response = (HttpServletResponse) getResponse();
response.setHeader("Content-Encoding", "gzip");
_servletOutputStream = new ServletOutputStreamWrapper(new GZIPOutputStream(response.getOutputStream()));
_printWriter = new PrintWriter(new OutputStreamWriter(_servletOutputStream, response.getCharacterEncoding()));
}
return _printWriter;
}
Expand Down
Expand Up @@ -11,6 +11,7 @@
package org.eclipse.orion.server.tests;

import org.eclipse.orion.server.tests.cf.AllCFTests;
import org.eclipse.orion.server.tests.filters.ExcludedExtensionGzipFilterTest;
import org.eclipse.orion.server.tests.metastore.ProjectInfoTests;
import org.eclipse.orion.server.tests.metastore.SimpleMetaStoreConcurrencyTests;
import org.eclipse.orion.server.tests.metastore.SimpleMetaStoreLiveMigrationConcurrencyTests;
Expand Down Expand Up @@ -47,6 +48,7 @@
Base64Test.class, //
BasicUsersTest.class, //
CoreFilesTest.class, //
ExcludedExtensionGzipFilterTest.class, //
MetaStoreTest.class, //
PreferenceTest.class, //
ProjectInfoTests.class, //
Expand Down
@@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.tests.filters;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import org.eclipse.orion.internal.server.core.metastore.SimpleMetaStore;
import org.eclipse.orion.server.servlets.ExcludedExtensionGzipFilter;
import org.eclipse.orion.server.tests.servlets.files.FileSystemTest;
import org.junit.Before;
import org.junit.Test;

import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;

/**
* Tests for {@link ExcludedExtensionGzipFilter}.
*/
public class ExcludedExtensionGzipFilterTest extends FileSystemTest {
private static final String CONTENT_ENCODING = "Content-Encoding";

@Before
public void setUp() throws Exception {
webConversation = new WebConversation();
webConversation.setExceptionsThrownOnErrorStatus(false);
setUpAuthorization();
createWorkspace(SimpleMetaStore.DEFAULT_WORKSPACE_NAME);
createTestProject(testName.getMethodName());
}

@Test
public void testExcludedExtensions() throws Exception {
assertGzipped(getFileResponse("/file/foo.txt"));
assertGzipped(getFileResponse("/file/bar"));

assertNotGzipped(getFileResponse("/file/baz.gif"));
assertNotGzipped(getFileResponse("/file/qux.png"));
}

private static void assertGzipped(WebResponse res) throws Exception {
assertEquals("gzip", res.getHeaderField(CONTENT_ENCODING));
}

private static void assertNotGzipped(WebResponse res) throws Exception {
assertNotEquals("gzip", res.getHeaderField(CONTENT_ENCODING));
}

private WebResponse getFileResponse(String location) throws Exception {
WebRequest request = getGetFilesRequest(location);
WebResponse response = webConversation.getResponse(request);
return response;
}

}
Expand Up @@ -20,6 +20,7 @@
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -1068,4 +1069,34 @@ public void testWriteFileInvalidUTF8() throws Exception {
assertTrue("Invalid file content", Arrays.equals(fileContent, bytes.toByteArray()));
}

/**
* Test that the gzip filter correctly encodes a UTF-8 response when the JVM's default charset is not UTF-8.
* Regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=474366
*/
@Test
public void testGzippedResponseCharset() throws Exception {
// This test is only valid when default charset is not UTF-8
if ("UTF-8".equals(Charset.defaultCharset().name())) {
return;
}

// Create folder
String directoryPath = "sample/directory/path" + System.currentTimeMillis();
createDirectory(directoryPath);
final String filename = "\u4f60\u597d\u4e16\u754c.txt";

// Create empty file in the folder
WebRequest request = getPostFilesRequest(directoryPath, getNewFileJSON(filename).toString(), filename);
WebResponse response = webConversation.getResponse(request);
assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode());

// Check metadata
request = getGetFilesRequest(response.getHeaderField(ProtocolConstants.KEY_LOCATION) + "?parts=meta");
response = webConversation.getResponse(request);
JSONObject metadata = new JSONObject(response.getText());
assertEquals("gzip", response.getHeaderField("Content-Encoding"));
assertTrue(response.getCharacterSet().contains("UTF-8"));
assertEquals("Name was encoded correctly", filename, metadata.optString(ProtocolConstants.KEY_NAME));
}

}

0 comments on commit d76d3fc

Please sign in to comment.