Estoy usando Zuul para proxy de un cliente extraño que envía un cuerpo como parte de una solicitud GET. Desafortunadamente, no hay forma de que pueda cambiar el cliente.

Con curl, dicha solicitud se puede enviar como:

curl -XGET 'localhost:8765/kibana/index.html' -d' {"key": "value"}'

Y los datos realmente se envían en el cuerpo. En el lado de zuul, sin embargo, cuando trato de leer el cuerpo, está vacío. Aquí está mi prototipo de código zuul:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@Controller
@EnableZuulProxy
public class ZuulServerApplication {

    @Bean
    public ZuulFilter myFilter() {
    return new ZuulFilter(){

        @Override
        public Object run() {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request=(HttpServletRequest)ctx.getRequest();
            try {
                InputStream is=request.getInputStream();
                String content=IOUtils.toString(is);
                System.out.println("Request content:"+content);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public boolean shouldFilter() {
            return true;
        }

        @Override
        public int filterOrder() {
            return 10;
        }
        @Override
        public String filterType() {
            return "pre";
        }};
    }
         public static void main(String[] args) {
            new SpringApplicationBuilder(ZuulServerApplication.class).web(true).run(args);
        }

    }

Si envío una solicitud POST, este código imprime el cuerpo de la solicitud sin problema. Sin embargo, si envío la solicitud GET anterior, el cuerpo no se imprime. ¿Hay algo que pueda hacer para que el cuerpo se envíe como parte de una solicitud GET?

1
Klaus 3 dic. 2016 a las 07:31
Parece que alguna maquinaria subyacente no hace un proxy de flujo de entrada cuando es un método GET con cuerpo. Dado que cuando filterOder es 10, HttpServletRequestWrapper se devolverá desde ctx.getRequest() que normalmente puede manejar la adquisición múltiple de flujo de entrada. Si filterOrder se cambia a p. Ej. -10 entonces funciona para este filtro ya que se usa más HttpServletRequest sin procesar (ningún otro filtro podría reemplazar HttpServletRequest con HttpServletRequestWrapper). Pero podría agotar el flujo de entrada para otra cosa.
 – 
Martin Krauskopf
5 dic. 2016 a las 17:55
Eso es bueno para mí. Probé y funciona. ¿Te importaría publicar como respuesta?
 – 
Klaus
7 dic. 2016 a las 19:01
Eso es bueno. Lo hice con un poco de elaboración.
 – 
Martin Krauskopf
8 dic. 2016 a las 10:46

1 respuesta

La mejor respuesta

Parece que alguna maquinaria subyacente [0], p. Ej. algún filtro Zuul incorporado con un orden de filtro menor, reemplaza el "crudo" predeterminado HttpServletRequest con HttpServletRequestWrapper que, en circunstancias estándar (es decir, no el método GET con cuerpo), es capaz de manejar múltiples adquisición de flujo de entrada. Pero en el caso del método GET con cuerpo, HttpServletRequestWrapper parece no flujo de entrada de proxy en absoluto.

Por lo tanto, la solución podría ser cambiar filterOrder p. ej. a -10.

Entonces funciona para el filtro ya que se usa HttpServletRequest - la maquinaria mencionada no llegó a su turno y por lo tanto no reemplazó HttpServletRequest con HttpServletRequestWrapper todavía. Pero el problema potencial con esta solución es que el filtro podría agotar el flujo de entrada para otra cosa, p. Ej. filtro con orden de filtro superior. Pero dado que GET con body no es una buena práctica de todos modos, podría ser una solución suficientemente buena después de todo :)

[0] He depurado esto hace más tiempo, pero no llegué al punto exacto, por lo tanto, una definición vaga de "la maquinaria".

1
Martin Krauskopf 8 dic. 2016 a las 10:45