@ -17,36 +17,68 @@
@@ -17,36 +17,68 @@
package org.springframework.cloud.netflix.zuul.filters.route ;
import java.io.ByteArrayInputStream ;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
import java.nio.charset.Charset ;
import java.util.Arrays ;
import java.util.zip.GZIPOutputStream ;
import javax.servlet.http.HttpServletResponse ;
import org.apache.http.HttpEntityEnclosingRequest ;
import org.apache.http.HttpHost ;
import org.apache.http.HttpRequest ;
import org.apache.http.client.methods.CloseableHttpResponse ;
import org.apache.http.entity.InputStreamEntity ;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager ;
import org.junit.After ;
import org.junit.Test ;
import org.junit.runner.RunWith ;
import org.springframework.boot.SpringApplication ;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration ;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration ;
import org.springframework.boot.context.embedded.LocalServerPort ;
import org.springframework.boot.context.properties.EnableConfigurationProperties ;
import org.springframework.boot.test.context.SpringBootTest ;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper ;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties ;
import org.springframework.context.annotation.AnnotationConfigApplicationContext ;
import org.springframework.context.annotation.Bean ;
import org.springframework.context.annotation.Configuration ;
import org.springframework.mock.web.MockHttpServletRequest ;
import org.springframework.test.annotation.DirtiesContext ;
import org.springframework.test.context.junit4.SpringRunner ;
import org.springframework.util.LinkedMultiValueMap ;
import org.springframework.util.StreamUtils ;
import org.springframework.web.bind.annotation.PathVariable ;
import org.springframework.web.bind.annotation.RequestMapping ;
import org.springframework.web.bind.annotation.RequestMethod ;
import org.springframework.web.bind.annotation.RestController ;
import static org.junit.Assert.assertEquals ;
import static org.junit.Assert.assertFalse ;
import static org.junit.Assert.assertTrue ;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT ;
import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment ;
import static org.springframework.util.StreamUtils.copyToByteArray ;
import static org.springframework.util.StreamUtils.copyToString ;
/ * *
* @author Andreas Kluth
* @author Spencer Gibb
* /
@RunWith ( SpringRunner . class )
@SpringBootTest ( classes = SampleApplication . class ,
webEnvironment = RANDOM_PORT ,
properties = "server.contextPath: /app" )
@DirtiesContext
public class SimpleHostRoutingFilterTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ( ) ;
@LocalServerPort
private int port ;
@After
public void clear ( ) {
if ( this . context ! = null ) {
@ -99,6 +131,32 @@ public class SimpleHostRoutingFilterTests {
@@ -99,6 +131,32 @@ public class SimpleHostRoutingFilterTests {
assertTrue ( httpEntityEnclosingRequest . getEntity ( ) ! = null ) ;
}
@Test
public void httpClientDoesNotDecompressEncodedData ( ) throws Exception {
setupContext ( ) ;
InputStreamEntity inputStreamEntity = new InputStreamEntity ( new ByteArrayInputStream ( new byte [ ] { 1 } ) ) ;
HttpRequest httpRequest = getFilter ( ) . buildHttpRequest ( "GET" , "/app/compressed/get/1" , inputStreamEntity ,
new LinkedMultiValueMap < String , String > ( ) , new LinkedMultiValueMap < String , String > ( ) , new MockHttpServletRequest ( ) ) ;
CloseableHttpResponse response = getFilter ( ) . newClient ( ) . execute ( new HttpHost ( "localhost" , this . port ) , httpRequest ) ;
assertEquals ( 200 , response . getStatusLine ( ) . getStatusCode ( ) ) ;
byte [ ] responseBytes = copyToByteArray ( response . getEntity ( ) . getContent ( ) ) ;
assertTrue ( Arrays . equals ( GZIPCompression . compress ( "Get 1" ) , responseBytes ) ) ;
}
@Test
public void httpClientPreservesUnencodedData ( ) throws Exception {
setupContext ( ) ;
InputStreamEntity inputStreamEntity = new InputStreamEntity ( new ByteArrayInputStream ( new byte [ ] { 1 } ) ) ;
HttpRequest httpRequest = getFilter ( ) . buildHttpRequest ( "GET" , "/app/get/1" , inputStreamEntity ,
new LinkedMultiValueMap < String , String > ( ) , new LinkedMultiValueMap < String , String > ( ) , new MockHttpServletRequest ( ) ) ;
CloseableHttpResponse response = getFilter ( ) . newClient ( ) . execute ( new HttpHost ( "localhost" , this . port ) , httpRequest ) ;
assertEquals ( 200 , response . getStatusLine ( ) . getStatusCode ( ) ) ;
String responseString = copyToString ( response . getEntity ( ) . getContent ( ) , Charset . forName ( "UTF-8" ) ) ;
assertTrue ( "Get 1" . equals ( responseString ) ) ;
}
private void setupContext ( ) {
this . context . register ( PropertyPlaceholderAutoConfiguration . class ,
TestConfiguration . class ) ;
@ -118,3 +176,38 @@ public class SimpleHostRoutingFilterTests {
@@ -118,3 +176,38 @@ public class SimpleHostRoutingFilterTests {
}
}
}
@Configuration
@EnableAutoConfiguration
@RestController
class SampleApplication {
public static void main ( String [ ] args ) {
SpringApplication . run ( SampleApplication . class , args ) ;
}
@RequestMapping ( value = "/compressed/get/{id}" , method = RequestMethod . GET )
public byte [ ] getCompressed ( @PathVariable String id , HttpServletResponse response ) throws IOException {
response . setHeader ( "content-encoding" , "gzip" ) ;
return GZIPCompression . compress ( "Get " + id ) ;
}
@RequestMapping ( value = "/get/{id}" , method = RequestMethod . GET )
public String getString ( @PathVariable String id , HttpServletResponse response ) throws IOException {
return "Get " + id ;
}
}
class GZIPCompression {
public static byte [ ] compress ( final String str ) throws IOException {
if ( ( str = = null ) | | ( str . length ( ) = = 0 ) ) {
return null ;
}
ByteArrayOutputStream obj = new ByteArrayOutputStream ( ) ;
GZIPOutputStream gzip = new GZIPOutputStream ( obj ) ;
gzip . write ( str . getBytes ( "UTF-8" ) ) ;
gzip . close ( ) ;
return obj . toByteArray ( ) ;
}
}