Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-190

resteasy.plugins.providers.multipart.HeaderFlushedOutputStream should flush headers only once

XMLWordPrintable

      It seems HeaderFlushedOutputStream is writing headers to response every time. This is the reason why resteasy.plugins.providers.InputStreamProvider is writing headers before every single byte with multipart/form-data output media type. Imho HeaderFlushedOutputStream should write headers only once.

      Suggested fix: add a flag to HeaderFlushedOutputStream
      <pre>
      private MultivaluedMap<String, Object> headers;
      + private boolean headersFlushed;
      private OutputStream stream;

      /* ... */

      protected void flushHeaders() throws IOException
      {
      + if (headersFlushed)
      + return;
      RuntimeDelegate delegate = RuntimeDelegate.getInstance();

      for (String key : headers.keySet())
      {
      List<Object> objs = headers.get(key);
      for (Object obj : objs)
      {
      String value;
      RuntimeDelegate.HeaderDelegate headerDelegate = delegate.createHeaderDelegate(obj.getClass());
      if (headerDelegate != null)

      { value = headerDelegate.toString(obj); }

      else

      { value = obj.toString(); }

      stream.write(key.getBytes());
      stream.write(": ".getBytes());
      stream.write(value.getBytes());
      stream.write("\r\n".getBytes());
      }
      }
      stream.write("\r\n".getBytes());

      + headersFlushed = true;
      }
      </pre>

      The issue came up with the following example.

      POJO:
      <pre>
      public class MyBean {
      @FormParam("someBinary")
      @PartType(MediaType.APPLICATION_OCTET_STREAM)
      private InputStream someBinary;

      /* ... */
      }
      </pre>

      Service:
      <pre>
      @GET
      @Produces(MediaType.MULTIPART_FORM_DATA)
      public @MultipartForm
      MyBean createMyBean()

      { logger.debug("started"); MyBean myBean = new MyBean(); myBean.setSomeBinary(new ByteArrayInputStream("bla".getBytes())); /* ... */ return myBean; }

      </pre>

      part of output:
      --f231sldkxx11
      Content-Length: -1
      Content-Disposition: form-data; name="someBinary"
      Content-Type: application/octet-stream

      bContent-Length: -1
      Content-Disposition: form-data; name="someBinary"
      Content-Type: application/octet-stream

      lContent-Length: -1
      Content-Disposition: form-data; name="someBinary"
      Content-Type: application/octet-stream

      a

      As you can see "bla" is written in 3 parts with full headers of every byte. With the above mentioned fix the result get to normal:
      --f231sldkxx11
      Content-Length: -1
      Content-Disposition: form-data; name="someBinary"
      Content-Type: application/octet-stream

      bla

              patriot1burke@gmail.com Bill Burke (Inactive)
              akiraly Attila Király (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved: