package org.springframework.cloud.netflix.zuul.filters.pre;

import com.google.common.base.Throwables;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;

/**
 * @author Spencer Gibb
 */
public class Servlet30WrapperFilter extends ZuulFilter {
    protected Field requestField = null;

    public Servlet30WrapperFilter() {
        try {
            requestField = HttpServletRequestWrapper.class.getDeclaredField("req");
            requestField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            Throwables.propagate(e);
        }
    }

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true; //TODO: only if in servlet 3.0 env
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request instanceof HttpServletRequestWrapper) {
            try {
                request = (HttpServletRequest) requestField.get(request);
            } catch (IllegalAccessException e) {
                Throwables.propagate(e);
            }
        }
        ctx.setRequest(new Servlet30RequestWrapper(request));
        //ctx.setResponse(new HttpServletResponseWrapper(ctx.getResponse()));
        return null;
    }

    class Servlet30RequestWrapper extends HttpServletRequestWrapper {
        private HttpServletRequest request;

        Servlet30RequestWrapper(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        @Override
        public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
            return request.authenticate(response);
        }

        @Override
        public void login(String username, String password) throws ServletException {
            request.login(username, password);
        }

        @Override
        public void logout() throws ServletException {
            request.logout();
        }

        @Override
        public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
            return request.getParts();
        }

        @Override
        public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
            return request.getPart(name);
        }

        @Override
        public ServletContext getServletContext() {
            return request.getServletContext();
        }

        @Override
        public AsyncContext startAsync() {
            return request.startAsync();
        }

        @Override
        public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
            return request.startAsync(servletRequest, servletResponse);
        }

        @Override
        public boolean isAsyncStarted() {
            return request.isAsyncStarted();
        }

        @Override
        public boolean isAsyncSupported() {
            return request.isAsyncSupported();
        }

        @Override
        public AsyncContext getAsyncContext() {
            return request.getAsyncContext();
        }

        @Override
        public DispatcherType getDispatcherType() {
            return request.getDispatcherType();
        }
    }
}

@@ -235,16 +235,105 @@
 Wrapper;
+%0Aimport org.springframework.util.Assert;%0Aimport org.springframework.util.ReflectionUtils;
 %0A%0Aimport
@@ -746,41 +746,49 @@
     
-try %7B%0A            requestField = 
+requestField = ReflectionUtils.findField(
 Http
@@ -818,34 +818,18 @@
 lass
-.getDeclaredField(
+, 
 %22req%22
-);%0A
+,%0A 
     
@@ -840,131 +840,166 @@
     
-requestField.setAccessible(true);%0A        %7D catch (NoSuchFieldException e) %7B%0A            Throwables.propagate(e);%0A        %7D
+   HttpServletRequest.class);%0A        Assert.notNull(requestField, %22HttpServletRequestWrapper.req field not found%22);%0A        requestField.setAccessible(true);
 %0A   

Use spring ReflectionUtils to find zuul HttpServletRequestWrapper field