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

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

    Details

      Description

      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

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                bill.burke Bill Burke
                Reporter:
                akiraly Attila Király
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: