How to proxy HTTP requests in Spring MVC?

此生再无相见时 提交于 2019-12-21 03:33:30

问题


I have an application built on top of Spring MVC.

I want to write simple proxy that processes requests as follows:

  1. send the same HTTP request to some specific server
  2. capture HTTP response from this specific server
  3. return the same answer to requesting client

Here is what I've got so far:

public void proxyRequest(HttpServletRequest request, HttpServletResponse response) {
    try {
        HttpUriRequest proxiedRequest = createHttpUriRequest(request);
        HttpResponse proxiedResponse = httpClient.execute(proxiedRequest);
        writeToResponse(proxiedResponse, response);
    } catch (URISyntaxException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void writeToResponse(HttpResponse proxiedResponse, HttpServletResponse response){
    for(Header header : proxiedResponse.getAllHeaders()){
        response.addHeader(header.getName(), header.getValue());
    }
    OutputStream os = null;
    InputStream is = null;
    try {
        is = proxiedResponse.getEntity().getContent();
        os = response.getOutputStream();
        IOUtils.copy(is, os);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

private HttpUriRequest createHttpUriRequest(HttpServletRequest request) throws URISyntaxException{
    URI uri = new URI(geoserverConfig.getUrl()+"/wms?"+request.getQueryString());

    RequestBuilder rb = RequestBuilder.create(request.getMethod());
    rb.setUri(uri);

    Enumeration<String> headerNames = request.getHeaderNames();
    while(headerNames.hasMoreElements()){
        String headerName = headerNames.nextElement();
        String headerValue = request.getHeader(headerName);
        rb.addHeader(headerName, headerValue);
    }

    HttpUriRequest proxiedRequest = rb.build();
    return proxiedRequest;
}

It works ok but not in all cases. I've checked in Chrome's network monitor and some of the requests that are using this proxy failed.

Here are headers of sample failed request response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: inline; filename=JEDN_EWID.png
Transfer-Encoding: chunked
Date: Thu, 16 Jul 2015 10:31:49 GMT
Content-Type: image/png;charset=UTF-8
Content-Length: 6727

Here are headers of sample successfull request response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: inline; filename=JEDN_EWID.png
Transfer-Encoding: chunked
Date: Thu, 16 Jul 2015 10:31:49 GMT
Content-Type: image/png;charset=UTF-8
Transfer-Encoding: chunked

What's more Chrome throws an error in the console:

GET http://localhost:8080/<rest of url> net::ERR_INVALID_CHUNKED_ENCODING

The requests that I'm proxying are WMS GetMap requests and my proxy is forwarding them to hidden Geoserver. I've noticed that failed requests should return transparent 512x512 .png images which are all empty. The successfull ones return 512x512 .png images that are not only transparent but also contain some colors.


回答1:


It looks like remote server responds with chunked responses when size become too big, Apache HttpClient library gathers all chunked elements in one big HttpResponse, but leaves the Transfer-Encoding: chunked header.

I could not test, but you should filter out the Transfer-Encoding: chunked to get rid of this problem :

private void writeToResponse(HttpResponse proxiedResponse, HttpServletResponse response){
    for(Header header : proxiedResponse.getAllHeaders()){
        if ((! header.getName().equals("Transfer-Encoding")) || (! header.getValue().equals("chunked"))) {
            response.addHeader(header.getName(), header.getValue());
        }
    }
    ...


来源:https://stackoverflow.com/questions/31452074/how-to-proxy-http-requests-in-spring-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!