package com.netflix.eureka.cluster;

import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.netflix.eureka.EurekaServerConfig;
import com.sun.jersey.api.client.AbstractClientRequestAdapter;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientRequestAdapter;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.filter.ClientFilter;

/**
 * This is a modified version of the standard jersey {@link com.sun.jersey.api.client.filter.GZIPContentEncodingFilter},
 * that supports dynamic configuration of request entity compression.
 */
public class DynamicGZIPContentEncodingFilter extends ClientFilter {

    private final EurekaServerConfig config;

    public DynamicGZIPContentEncodingFilter(EurekaServerConfig config) {
        this.config = config;
    }

    @Override
    public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
        if (!request.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) {
            request.getHeaders().add(HttpHeaders.ACCEPT_ENCODING, "gzip");
        }

        if (request.getEntity() != null) {
            Object o = request.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
            if (o != null && o.equals("gzip")) {
                request.setAdapter(new Adapter(request.getAdapter()));
            } else if (isCompressionEnabled()) {
                request.getHeaders().add(HttpHeaders.CONTENT_ENCODING, "gzip");
                request.setAdapter(new Adapter(request.getAdapter()));
            }
        }

        ClientResponse response = getNext().handle(request);

        if (response.hasEntity() &&
                response.getHeaders().containsKey(HttpHeaders.CONTENT_ENCODING)) {
            String encodings = response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);

            if (encodings.equals("gzip")) {
                response.getHeaders().remove(HttpHeaders.CONTENT_ENCODING);
                try {
                    response.setEntityInputStream(new GZIPInputStream(response.getEntityInputStream()));
                } catch (IOException ex) {
                    throw new ClientHandlerException(ex);
                }
            }
        }

        return response;
    }

    private boolean isCompressionEnabled() {
        return config.shouldEnableReplicatedRequestCompression();
    }

    private static final class Adapter extends AbstractClientRequestAdapter {
        Adapter(ClientRequestAdapter cra) {
            super(cra);
        }

        public OutputStream adapt(ClientRequest request, OutputStream out) throws IOException {
            return new GZIPOutputStream(getAdapter().adapt(request, out));
        }
    }
}
@@ -91,24 +91,52 @@
 OException;%0A
+import java.io.InputStream;%0A
 import java.
@@ -614,194 +614,51 @@
 %0A * 
-This is a modified version of the standard jersey %7B@link com.sun.jersey.api.client.filter.
+Eureka specific 
 GZIP
-C
+ c
 ontent
-EncodingFilter%7D,%0A * that supports dynamic configuration of request entity compression
+ filter handler
 .%0A *
@@ -729,16 +729,73 @@
 lter %7B%0A%0A
+    private static final String GZIP_ENCODING = %22gzip%22;%0A%0A
     priv
@@ -1016,39 +1016,78 @@
 st) 
-throws ClientHandlerException %7B
+%7B%0A        // If 'Accept-Encoding' is not set, assume gzip as a default
 %0A   
@@ -1219,38 +1219,45 @@
 CCEPT_ENCODING, 
-%22gzip%22
+GZIP_ENCODING
 );%0A        %7D%0A%0A  
@@ -1316,17 +1316,31 @@
  Object 
-o
+requestEncoding
  = reque
@@ -1415,36 +1415,44 @@
 if (
-o != null && o.equals(%22gzip%22
+GZIP_ENCODING.equals(requestEncoding
 )) %7B
@@ -1483,32 +1483,36 @@
 .setAdapter(new 
+Gzip
 Adapter(request.
@@ -1647,22 +1647,29 @@
 CODING, 
-%22gzip%22
+GZIP_ENCODING
 );%0A     
@@ -1702,16 +1702,20 @@
 ter(new 
+Gzip
 Adapter(
@@ -1837,20 +1837,23 @@
     
-if (
+String 
 response
 .has
@@ -1852,39 +1852,18 @@
 onse
-.hasEntity() &&%0A               
+Encoding =
  res
@@ -1877,35 +1877,32 @@
 etHeaders().
-containsKey
+getFirst
 (HttpHeaders
@@ -1911,35 +1911,33 @@
 ONTENT_ENCODING)
-) %7B
+;
 %0A            Str
@@ -1933,142 +1933,78 @@
     
-    String encodings = response.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);%0A%0A            if (encodings.equals(%22gzip%22
+if (response.hasEntity() && GZIP_ENCODING.equals(responseEncoding
 )) %7B%0A
-    
     
@@ -2087,255 +2087,37 @@
     
-    try %7B%0A                    response.setEntityInputStream(new GZIPInputStream(response.getEntityInputStream()));%0A                %7D catch (IOException ex) %7B%0A                    throw new ClientHandlerException(ex);%0A                %7D%0A            %7D
+decompressResponse(response);
 %0A   
@@ -2115,33 +2115,32 @@
 nse);%0A        %7D%0A
-%0A
         return r
@@ -2265,32 +2265,574 @@
 ssion();%0A    %7D%0A%0A
+    private static void decompressResponse(ClientResponse response) %7B%0A        InputStream entityInputStream = response.getEntityInputStream();%0A        GZIPInputStream uncompressedIS;%0A        try %7B%0A            uncompressedIS = new GZIPInputStream(entityInputStream);%0A        %7D catch (IOException ex) %7B%0A            try %7B%0A                entityInputStream.close();%0A            %7D catch (IOException ignored) %7B%0A            %7D%0A            throw new ClientHandlerException(ex);%0A        %7D%0A        response.setEntityInputStream(uncompressedIS);%0A    %7D%0A%0A
     private stat
@@ -2846,16 +2846,20 @@
 l class 
+Gzip
 Adapter 
@@ -2905,16 +2905,20 @@
         
+Gzip
 Adapter(
@@ -2972,32 +2972,50 @@
 ra);%0A        %7D%0A%0A
+        @Override%0A
         public O

Fix for issue https://github.com/Netflix/eureka/issues/711