/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.wink.itests.contentencode; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import junit.framework.TestCase; import org.apache.wink.client.ClientConfig; import org.apache.wink.client.ClientResponse; import org.apache.wink.client.RestClient; import org.apache.wink.client.internal.handlers.DeflateHandler; import org.apache.wink.client.internal.handlers.GzipHandler; import org.apache.wink.common.internal.providers.entity.StringProvider; import org.apache.wink.test.integration.ServerEnvironmentInfo; public class ContentEncodedTest extends TestCase { private static String getRepeatedString() { StringBuilder sb = new StringBuilder(); for (int c = 0; c < 1000; ++c) { sb.append("Hello world! "); } return sb.toString(); } protected static String getBaseURI() { if (ServerEnvironmentInfo.isRestFilterUsed()) { return ServerEnvironmentInfo.getBaseURI(); } return ServerEnvironmentInfo.getBaseURI() + "/rest"; } private static void verifyResponseNotContentEncodedForRepeatedStrings(ClientResponse response) { assertEquals(200, response.getStatusCode()); assertEquals(getRepeatedString(), response.getEntity(String.class)); assertNull(response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertNull(response.getHeaders().getFirst(HttpHeaders.VARY)); } private static void verifyResponseGZIPContentEncodedForRepeatedStrings(ClientResponse response) throws IOException { assertEquals(200, response.getStatusCode()); InputStream is = response.getEntity(InputStream.class); GZIPInputStream gzipIS = new GZIPInputStream(is); StringProvider sp = new StringProvider(); String responseEntity = sp.readFrom(String.class, String.class, new Annotation[] {}, MediaType.TEXT_PLAIN_TYPE, null, gzipIS); assertEquals(getRepeatedString(), responseEntity); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals(HttpHeaders.ACCEPT_ENCODING, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } private static void verifyResponseDeflateContentEncodedForRepeatedStrings(ClientResponse response) throws IOException { assertEquals(200, response.getStatusCode()); InputStream is = response.getEntity(InputStream.class); InflaterInputStream inflaterIS = new InflaterInputStream(is); StringProvider sp = new StringProvider(); String responseEntity = sp.readFrom(String.class, String.class, new Annotation[] {}, MediaType.TEXT_PLAIN_TYPE, null, inflaterIS); assertEquals(getRepeatedString(), responseEntity); assertEquals("deflate", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals(HttpHeaders.ACCEPT_ENCODING, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } /** * Tests that a regular encoded input is acceptable to the server. */ public void testContentEncodedInboundRequestRegularOutboundPost() { ClientConfig config = new ClientConfig(); config.handlers(); RestClient client = new RestClient(config); ClientResponse response = client.resource(getBaseURI() + "/regular/echo").post(getRepeatedString()); assertEquals(200, response.getStatusCode()); assertEquals(getRepeatedString(), response.getEntity(String.class)); assertNull(response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertNull(response.getHeaders().getFirst(HttpHeaders.VARY)); } /** * Tests that a GZIP inbound is ok and outbound is also ok. */ public void testGZIPContentEncodedInboundRequestContentEncodedOutboundPost() { ClientConfig config = new ClientConfig(); config.handlers(new DeflateHandler()); RestClient client = new RestClient(config); ClientResponse response = client.resource(getBaseURI() + "/contentencode/echo").post(getRepeatedString()); assertEquals(200, response.getStatusCode()); assertEquals(getRepeatedString(), response.getEntity(String.class)); assertEquals("deflate", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals(HttpHeaders.ACCEPT_ENCODING, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } /** * Tests that a deflate inbound is ok and outbound is also ok. */ public void testDeflatedContentEncodedInboundRequestContentEncodedOutboundPost() { ClientConfig config = new ClientConfig(); config.handlers(new DeflateHandler()); RestClient client = new RestClient(config); ClientResponse response = client.resource(getBaseURI() + "/contentencode/echo").post(getRepeatedString()); assertEquals(200, response.getStatusCode()); assertEquals(getRepeatedString(), response.getEntity(String.class)); assertEquals("deflate", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals(HttpHeaders.ACCEPT_ENCODING, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } /** * Tests that a regular get repeated strings resource is possible. This is * not content encoded. */ public void testRegularGetRepeatedStringsResource() { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/regular/repeatedstring").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/regular/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "gzip").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/regular/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "*").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); /* * test even with the GZIP Handler on the path */ ClientConfig clientConfig = new ClientConfig(); clientConfig.handlers(new GzipHandler()); client = new RestClient(clientConfig); response = client.resource(getBaseURI() + "/regular/repeatedstring").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); } /** * Tests that a content encoded get repeated strings resource is possible. * This is GZIP content encoded. This uses the client handler * {@link GzipHandler}. */ public void testGZIPContentEncodedGetRepeatedStringsResource() throws IOException { ClientConfig clientConfig = new ClientConfig(); clientConfig.handlers(new GzipHandler()); RestClient client = new RestClient(clientConfig); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring").get(); assertEquals(200, response.getStatusCode()); assertEquals(getRepeatedString(), response.getEntity(String.class)); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals(HttpHeaders.ACCEPT_ENCODING, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } /** * Tests that a content encoded get repeated strings resource is possible. * This is GZIP content encoded. Tests a manual GZIP decode (so to make sure * that the content was GZIP encoded). */ public void testManualGZIPContentDecodedGetRepeatedStringsResource() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "gzip").get(); verifyResponseGZIPContentEncodedForRepeatedStrings(response); } /** * Tests that a content encoded get repeated strings resource is possible. * This is Deflate content encoded. */ public void testManualDeflateContentEncodedGetRepeatedStringsResource() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "deflate").get(); verifyResponseDeflateContentEncodedForRepeatedStrings(response); } /** * Tests that the possible Content Encoded resource respects the * Accept-Encoding header and will not Content Encode if the Accept-Encoding * header is missing or not available. This is not content encoded. */ public void testContentEncodeRespectAcceptEncodingHeaderForGetRepeatedStringsResource() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, " ").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "myencoding").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "mycustomencoding;q=0.0").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "mycustomencoding,myothercustomencoding") .get(); verifyResponseNotContentEncodedForRepeatedStrings(response); } /** * Tests that the possible Content Encoded resource respects the * Accept-Encoding header for GZIP with wildcards. */ public void testGZIPContentEncodeRespectWildcardAcceptEncodingHeaderForGetRepeatedStringsResource() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "*").get(); verifyResponseGZIPContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "*,deflate=0.8").get(); verifyResponseGZIPContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "gzip,deflate").get(); verifyResponseGZIPContentEncodedForRepeatedStrings(response); /* * tests that gzip encoding is banned which is the default. */ response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "*,gzip;q=0.0").get(); verifyResponseNotContentEncodedForRepeatedStrings(response); } /** * Tests that the possible Content Encoded resource respects the * Accept-Encoding header for Deflate with wildcards. */ public void testDeflateContentEncodeRespectAcceptEncodingQualityValuesHeaderForGetRepeatedStringsResource() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "*;q=0.6,deflate").get(); verifyResponseDeflateContentEncodedForRepeatedStrings(response); response = client.resource(getBaseURI() + "/contentencode/repeatedstring") .header(HttpHeaders.ACCEPT_ENCODING, "gzip;q=0.6,deflate;q=0.8").get(); verifyResponseDeflateContentEncodedForRepeatedStrings(response); } /** * Tests that when a JAX-RS application adds a Vary header, that the Vary * header comes out okay. */ public void testRegularVaryHeaderCorrectlyOutput() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/regular/varyheaderwithaccept") .header(HttpHeaders.ACCEPT_ENCODING, "gzip").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals("Variant[mediaType=text/plain, language=null, encoding=null]", response .getEntity(String.class)); assertEquals(HttpHeaders.ACCEPT, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); } /** * Tests that when a JAX-RS application adds a Vary header, that the Vary * header is correctly appended to for the first Vary value. */ public void testContentEncodeVaryHeaderCorrectlyAppended() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/varyheaderwithaccept") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT + ", " + HttpHeaders.ACCEPT_ENCODING, response.getHeaders() .getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); InputStream is = response.getEntity(InputStream.class); GZIPInputStream gzipIS = new GZIPInputStream(is); StringProvider sp = new StringProvider(); String responseEntity = sp.readFrom(String.class, String.class, new Annotation[] {}, MediaType.TEXT_PLAIN_TYPE, null, gzipIS); assertEquals("Variant[mediaType=text/plain, language=null, encoding=null]", responseEntity); } /** * Tests that when a JAX-RS application adds a Vary header, that the Vary * header is set when a {@link Request#selectVariant(java.util.List)} call * is made. */ public void testRegularVaryHeaderCorrectlyReturnedByItself() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/regular/varyheaderwithacceptencoding") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT + ", " + HttpHeaders.ACCEPT_ENCODING, response.getHeaders() .getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertNull(response.getHeaders().get(HttpHeaders.CONTENT_ENCODING)); assertEquals("Variant[mediaType=text/plain, language=null, encoding=gzip]", response .getEntity(String.class)); response = client.resource(getBaseURI() + "/regular/varyheaderwithacceptencoding") .accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT + ", " + HttpHeaders.ACCEPT_ENCODING, response.getHeaders() .getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertNull(response.getHeaders().get(HttpHeaders.CONTENT_ENCODING)); assertEquals("Variant[mediaType=text/plain, language=null, encoding=identity]", response .getEntity(String.class)); } /** * Tests that when a JAX-RS application adds a Vary header, that the * Accept-Encoding value is correctly appended to the first Vary value (in * this case, no append takes place since the Vary header already has * Accept-Encoding in it). */ public void testContentEncodeVaryHeaderCorrectlyReturnedByItself() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/varyheaderwithacceptencoding") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT + ", " + HttpHeaders.ACCEPT_ENCODING, response.getHeaders() .getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); InputStream is = response.getEntity(InputStream.class); GZIPInputStream gzipIS = new GZIPInputStream(is); StringProvider sp = new StringProvider(); String responseEntity = sp.readFrom(String.class, String.class, new Annotation[] {}, MediaType.TEXT_PLAIN_TYPE, null, gzipIS); assertEquals("Variant[mediaType=text/plain, language=null, encoding=gzip]", responseEntity); } /** * Tests that when a user uses a JAX-RS application to add a Vary header * that the header is correctly set. */ public void testRegularVaryHeaderCorrectlyReturnedByUserUnmodified() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/regular/varyheaderwithacceptencodingbyuser") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT_CHARSET + "," + HttpHeaders.ACCEPT_ENCODING.toLowerCase() + " , " + HttpHeaders.ACCEPT, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertNull(response.getHeaders().get(HttpHeaders.CONTENT_ENCODING)); assertEquals("text/plain content", response.getEntity(String.class)); response = client.resource(getBaseURI() + "/regular/varyheaderwithacceptencodingbyuser") .accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT_CHARSET + "," + HttpHeaders.ACCEPT_ENCODING.toLowerCase() + " , " + HttpHeaders.ACCEPT, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertNull(response.getHeaders().get(HttpHeaders.CONTENT_ENCODING)); assertEquals("text/plain content", response.getEntity(String.class)); } /** * Tests that when a JAX-RS application adds a Vary header, that the * Accept-Encoding value is correctly appended to the first Vary value (in * this case, no append takes place since the Vary header already has * Accept-Encoding in it). */ public void testGZIPContentEncodeVaryHeaderCorrectlyReturnedByUserUnmodified() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/contentencode/varyheaderwithacceptencodingbyuser") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN).get(); assertEquals(200, response.getStatusCode()); assertEquals(HttpHeaders.ACCEPT_CHARSET + "," + HttpHeaders.ACCEPT_ENCODING.toLowerCase() + " , " + HttpHeaders.ACCEPT, response.getHeaders().getFirst(HttpHeaders.VARY)); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); InputStream is = response.getEntity(InputStream.class); GZIPInputStream gzipIS = new GZIPInputStream(is); StringProvider sp = new StringProvider(); String responseEntity = sp.readFrom(String.class, String.class, new Annotation[] {}, MediaType.TEXT_PLAIN_TYPE, null, gzipIS); assertEquals("text/plain content", responseEntity); } /** * Tests that the server side request headers have the Content-Encoding * in them normally (without filter). */ public void testHttpHeaderRequestWithoutFilter() throws IOException { RestClient client = new RestClient(); ClientResponse response = client.resource(getBaseURI() + "/regular/httpheadercontentencoding") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN) .contentType(MediaType.TEXT_PLAIN).header(HttpHeaders.CONTENT_ENCODING, "gzip") .post("HI"); assertEquals(200, response.getStatusCode()); assertEquals("[gzip]:gzip:true:true", response.getEntity(String.class)); } /** * Tests that the server side request headers have the Content-Encoding * stripped since the filter is decoding it. */ public void testHttpHeaderRequest() throws IOException { RestClient client = new RestClient(new ClientConfig().handlers(new GzipHandler())); ClientResponse response = client.resource(getBaseURI() + "/contentencode/httpheadercontentencoding") .header(HttpHeaders.ACCEPT_ENCODING, "*").accept(MediaType.TEXT_PLAIN) .contentType(MediaType.TEXT_PLAIN).post("HI"); assertEquals(200, response.getStatusCode()); assertEquals(1, response.getHeaders().get(HttpHeaders.VARY).size()); assertEquals("gzip", response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, response.getHeaders().get(HttpHeaders.CONTENT_ENCODING).size()); assertEquals("null:null:false:false", response.getEntity(String.class)); } }