Re: ( MAJOR BUG ) The POST body is corrupted after the first 16K

I've found a serious bug in the HTBufferWriter_write method. It seems that
if the amount of information that you're trying to write out is greater in
size than the space in the buffer....

1) the contents of the buffer is filled with as much information as possible
and then flushed
2) the remainder of the inforamtion is placed into a reallocated buffer and
never written out

by changing the the HTBufferWriter_write method to the following, I've been
able to successfully POST bodies of information as small as 333 bytes to
over 1 MB in size and validate the transfered file via a binary comparison.
Prior to the changes, the 1 MB file would only match to about (funny enough)
the size of the allocated buffer.

Here are my changes:

PRIVATE int HTBufferWriter_write (HTOutputStream * me, const char * buf, int
len)
{
  int status;
  while (1)
  {
    int available = me->data + me->allocated - me->read;
    /* If we have enough buffer space */
    if (len <= available)
    {
      int size = 0;
      memcpy(me->read, buf, len);
      me->read += len;
      
      /* If we have accumulated enough data then flush */
      if ((size = me->read - me->data) > me->growby)
      {
        me->lastFlushTime = HTGetTimeInMillis();
        status = PUTBLOCK(me->data, size);
        if (status == HT_OK) 
        {
          me->read = me->data;
        } 
        else
        {
          return (status == HT_WOULD_BLOCK) ? HT_OK : HT_ERROR;
        }
      }
      return HT_OK;
    } 
    else
    {
      if (len > me->allocated )
      {
        /* moved whis code from the HT_WOULD_BLOCK section */
        HTBufferWriter_addBuffer(me, len-me->allocated);
        memcpy(me->read, buf, len);
        me->read += len;
      }
      else
      {
        /* Fill the existing buffer (if not already) and flush */
        if (available) 
        {
          memcpy(me->read, buf, available);
          buf += available;
          len -= available;
          me->read += available;
        }
      }
      me->lastFlushTime = HTGetTimeInMillis();
      status = PUTBLOCK(me->data, me->allocated);
      if (status == HT_OK) 
      {
        me->read = me->data;
      } 
      else if (status == HT_WOULD_BLOCK) 
      {
        /* this code was moved above */
        return HT_OK;
      }
    }
  }
}

At this time, my only major concern is the fact that there is another buffer
being allocated to copy the buffer I wish to send. I understand the need for
this if ASYNC operations need to be handled however, what about the "return
HT_OK" in the HT_WOULD_BLOCK section of the code which precludes sending the
rest of the information.

Received on Monday, 19 February 2001 18:05:56 UTC