Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-2275

Undertow read-timeout can close connection unexpectedly before returning response for POST request larger than the default buffer size

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 2.2.26.Final, 2.3.8.Final
    • 2.3.6.Final
    • AJP, Core
    • None
    • Hide

      1. Configure read-timeout="10000" (10 seconds) on undertow http-listener and ajp-listener

          <ajp-listener name="ajp" read-timeout="10000" socket-binding="ajp" record-request-start-time="true"/>
      
          <http-listener name="default" read-timeout="10000" socket-binding="http" record-request-start-time="true" redirect-socket="https" enable-http2="true"/>
      

      2. Configure httpd/mod_proxy_ajp for testing AJP part

      ProxyPass /example/ http://127.0.0.1:8009/example/
      

      3. Deploy attached example.war, then send a request to index.jsp with a large POST request data.

      • Send 16KB POST request data to HTTP port with Content-Length
        $ curl -v http://127.0.0.1:8080/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16384)" -H "Expect:"
        
      • Send 16KB POST request data to HTTP port with chunked encoding
        $ curl -v http://127.0.0.1:8080/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16384)" -H "Expect:" -H "Transfer-Encoding: chunked"
        
      • Send 8KB POST request data to AJP port through httpd/mod_proxy_ajp
        $ curl -v http://127.0.0.1/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 8192)" -H "Expect:"
        

      Expected result:
      The server returns a response for the application after some sleep (11 seconds by default), so curl should receive the response like the following:

      Hello
      Start: Fri May 19 19:17:34 JST 2023
      End:   Fri May 19 19:17:45 JST 2023
      

      Actual result:
      The server does not return any response, so curl will show the following instead:

      curl: (52) Empty reply from server
      

      Memo: the following command can generate a random ASCII text with the specified length. So, we utilize this to generate a large dummy POST request data for the curl command:

      $ cat /dev/urandom | tr -dc A-Za-z0-9 | head -c <bytesize>
      
      Show
      1. Configure read-timeout="10000" (10 seconds) on undertow http-listener and ajp-listener <ajp-listener name= "ajp" read-timeout= "10000" socket-binding= "ajp" record-request-start-time= " true " /> <http-listener name= " default " read-timeout= "10000" socket-binding= "http" record-request-start-time= " true " redirect-socket= "https" enable-http2= " true " /> 2. Configure httpd/mod_proxy_ajp for testing AJP part ProxyPass /example/ http: //127.0.0.1:8009/example/ 3. Deploy attached example.war, then send a request to index.jsp with a large POST request data. Send 16KB POST request data to HTTP port with Content-Length $ curl -v http: //127.0.0.1:8080/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16384)" -H "Expect:" Send 16KB POST request data to HTTP port with chunked encoding $ curl -v http: //127.0.0.1:8080/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16384)" -H "Expect:" -H "Transfer-Encoding: chunked" Send 8KB POST request data to AJP port through httpd/mod_proxy_ajp $ curl -v http: //127.0.0.1/example/index.jsp -d "test=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 8192)" -H "Expect:" Expected result: The server returns a response for the application after some sleep (11 seconds by default), so curl should receive the response like the following: Hello Start: Fri May 19 19:17:34 JST 2023 End: Fri May 19 19:17:45 JST 2023 Actual result: The server does not return any response, so curl will show the following instead: curl: (52) Empty reply from server — Memo: the following command can generate a random ASCII text with the specified length. So, we utilize this to generate a large dummy POST request data for the curl command: $ cat /dev/urandom | tr -dc A-Za-z0-9 | head -c <bytesize>

    Description

      Undertow read-timeout can close a connection unexpectedly before an application returns a response.

      This can happen with the following conditions:

      • Client sends larger POST request data than the buffer size (16KB for HTTP and 8KB for AJP by default). So, POST request is not fully read by HttpReadListner or AjpReadListener on the I/O thread.

      and

      • The application's processing takes longer than read-timeout after consuming POST request data.

      Note that this issue happens even if all POST request data can be read and consumed completely within the read-timeout. So, this unexpected connection closure is not caused by unreceived request data due to slow client or slow network.

      This is similar to the past issue JBEAP-20814/UNDERTOW-1856, but the reproduction conditions are different.

      Attachments

        Issue Links

          Activity

            People

              thofman Tomas Hofman
              thofman Tomas Hofman
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: