Uploaded image for project: 'HttpComponents HttpCore'
  1. HttpComponents HttpCore
  2. HTTPCORE-473

ElementalReverseProxy does not properly handle POST requests

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 4.4.6
    • 4.4.7
    • Examples
    • None
    • Windows 7, Java 8

    Description

      Dear Oleg et al.,

      I understand that ElementalReverseProxy is provided just as an example, but it will be great if this example works properly, as it shows how the underlying API must be used.

      Here's a simple setup that shows why ElementalReverseProxy fails to work with POST request (and in fact, any requests including Content-Length or Transfer-Content headers):

      1. Let http://127.0.0.1:80 denote the back-end server which we want to proxy against, and assume the server hosts the file /index.html.
      2. Run ElementalReverseProxy with default config against the back-end server.

      Test the back-end server using wget:

      wget http://127.0.0.1:80 --post-data="some data"
      --2017-06-24 11:52:30--  http://127.0.0.1/
      Connecting to 127.0.0.1:80... connected.
      HTTP request sent, awaiting response... 200 OK
      Length: 343 [text/html]
      Saving to: 'index.html'
      
      index.html                      100%[====================================================>]     343  --.-KB/s    in 0s
      
      2017-06-24 11:52:30 (9.78 MB/s) - 'index.html' saved [343/343]
      

      As you can see, it works just fine. Now try it with ElementalReverseProxy:

      wget http://127.0.0.1:8888 --post-data="some data"
      --2017-06-24 11:53:31--  http://127.0.0.1:8888/
      Connecting to 127.0.0.1:8888... connected.
      HTTP request sent, awaiting response... 400 Bad Request
      2017-06-24 11:53:31 ERROR 400: Bad Request.
      

      Resolution

      ProxyThread executes httpservice.handleRequest, which in turn calls processor.process(request, context). This causes RequestContent.process() to be executed, which throws an exception as it finds that the request already contains the Content-Length header.

      One way to rectify this is to initialize inhttpproc with RequestContent(true), which overwrites the Content-Length header even if it is present, without throwing an exception.

      Running wget again will now result in no error, but with one catch: Notice the response misses the Content-Length header (this is evident from Length: unspecified below):

      wget http://127.0.0.1:8888 --post-data="some data"
      --2017-06-24 12:09:25--  http://127.0.0.1:8888/
      Connecting to 127.0.0.1:8888... connected.
      HTTP request sent, awaiting response... 200 OK
      Length: unspecified [text/html]
      Saving to: 'index.html'
      
      index.html                          [ <=>                                                 ]     343  --.-KB/s    in 0s
      
      2017-06-24 12:09:25 (8.82 MB/s) - 'index.html' saved [343]
      

      This is due to the line targetResponse.removeHeaders(HTTP.CONTENT_LEN) in ProxyHandler#handle() method. Commenting this line will resolve the issue.

      In general, I don't get the ProxyHandler#handle() method: It is called by HttpService#doService(), which in turn gets called just after the following line:

      this.processor.process(request, context);
      

      So, it means that just after the above line applied mandatory HTTP headers, ProxyHandler#handle() removes them all! Next, it tries to re-apply them:

      this.httpexecutor.preProcess(request, this.httpproc, context);
      

      But here, this.httpproc refers to outhttpproc, for which the requestInterceptors instance is null effectively doing nothing.

      Attachments

        Activity

          People

            Unassigned Unassigned
            msdousti M.S. Dousti
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: