Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8287134

HttpURLConnection chunked streaming mode doesn't enforce specified size

XMLWordPrintable

    • b08
    • generic
    • generic
    • Verified

      ADDITIONAL SYSTEM INFORMATION :
      java 17
      windows 10

      A DESCRIPTION OF THE PROBLEM :
      [chunkedStreamingMode](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/HttpURLConnection.html#setChunkedStreamingMode(int)) simply enables chunk streaming but it doesn't enforce the specified size on the chunks transmitted. It allows chunks of any size to be transmitted regardless of this value and it doesn't divide the data into multiple chunks if it exceeds this value. We have to do it manually

      This method should divide the data in an write() call into chunks automatically without the user manually calculating the size of each chunk but it doesn't.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Create an simple server to print the chunks received from the client

      2) Create an HttpURLConnection to transfer chunks of size greater than the specified value

      3)Observe output on server end. chunk sizes can be of any length irrespective of the length specified in the client method



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Upon transmitting 15 bytes of data and with setChunkedStreamingMode(5) the URL connection should transmit 3 chunks each of size 5 bytes and the last 0 chunk as follows. Output is viewed on the server side

      POST /Test.txt HTTP/1.1
      User-Agent: Java/17.0.2
      Host: localhost:3000
      Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
      Connection: keep-alive
      Content-type: application/x-www-form-urlencoded
      Transfer-Encoding: chunked



      =========
      5
      01234

      =========
      5
      56789

      =========
      5
      ABCDE

      =========
      0




      ACTUAL -
      Full 20 bytes is transmitted as one chunk

      POST /Test.txt HTTP/1.1
      User-Agent: Java/17.0.2
      Host: localhost:3000
      Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
      Connection: keep-alive
      Content-type: application/x-www-form-urlencoded
      Transfer-Encoding: chunked


      =========
      f
      0123456789ABCDE

      ==========
      0

      ---------- BEGIN SOURCE ----------
      Run server in an seperate JVM

      class Server
      {
       public static void main(String[] args)throws Exception
       {
        try(ServerSocket server=new ServerSocket(3000))
        {
         try(Socket client=server.accept())
         {
          try(InputStream input=client.getInputStream())
          {
           int length;
           byte[] data=new byte[6000];
           
           while((length=input.read(data))>0)
           {
            System.out.println(new String(data,0,length));
            System.out.println("=========");
           }
          }
         }
        }
       }
      }

      Run client in an seperate JVM

      public class Chunked
      {
       public static void main(String[] args) throws Exception
       {
        HttpURLConnection con=(HttpURLConnection)new URL("http://localhost:3000/Test.txt")
                              .openConnection();
        
        con.setChunkedStreamingMode(5);
        
        con.setDoOutput(true);
        try(OutputStream output=con.getOutputStream())
        {
         output.write("0123456789ABCDE".getBytes());
         output.flush();
        }
       }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      in the client we need to manually divide the data our self into equal sized chunks.

      FREQUENCY : always


        1. Chunked.java
          0.5 kB
        2. Server.java
          0.7 kB

            ccleary Conor Cleary (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: