httpWrite2(http_t     *http,		/* I - HTTP connection */
           const char *buffer,		/* I - Buffer for data */
	   size_t     length)		/* I - Number of bytes to write */
{
  ssize_t	bytes;			/* Bytes written */


  DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffer, CUPS_LLCAST length));

 /*
  * Range check input...
  */

  if (!http || !buffer)
  {
    DEBUG_puts("1httpWrite2: Returning -1 due to bad input.");
    return (-1);
  }

 /*
  * Mark activity on the connection...
  */

  http->activity = time(NULL);

 /*
  * Buffer small writes for better performance...
  */

#ifdef HAVE_LIBZ
  if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE)
  {
    DEBUG_printf(("1httpWrite2: http->coding=%d", http->coding));

    if (length == 0)
    {
      http_content_coding_finish(http);
      bytes = 0;
    }
    else
    {
      size_t	slen;			/* Bytes to write */
      ssize_t	sret;			/* Bytes written */

      ((z_stream *)http->stream)->next_in   = (Bytef *)buffer;
      ((z_stream *)http->stream)->avail_in  = (uInt)length;

      while (deflate((z_stream *)http->stream, Z_NO_FLUSH) == Z_OK)
      {
        DEBUG_printf(("1httpWrite2: avail_out=%d", ((z_stream *)http->stream)->avail_out));

        if (((z_stream *)http->stream)->avail_out > 0)
	  continue;

	slen = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out;

        DEBUG_printf(("1httpWrite2: Writing intermediate chunk, len=%d", (int)slen));

	if (slen > 0 && http->data_encoding == HTTP_ENCODING_CHUNKED)
	  sret = http_write_chunk(http, (char *)http->sbuffer, slen);
	else if (slen > 0)
	  sret = http_write(http, (char *)http->sbuffer, slen);
	else
	  sret = 0;

        if (sret < 0)
	{
	  DEBUG_puts("1httpWrite2: Unable to write, returning -1.");
	  return (-1);
	}

	((z_stream *)http->stream)->next_out  = (Bytef *)http->sbuffer;
	((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER;
      }

      bytes = (ssize_t)length;
    }
  }
  else
#endif /* HAVE_LIBZ */
  if (length > 0)
  {
    if (http->wused && (length + (size_t)http->wused) > sizeof(http->wbuffer))
    {
      DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length="
                    CUPS_LLFMT ")", http->wused, CUPS_LLCAST length));

      httpFlushWrite(http);
    }

    if ((length + (size_t)http->wused) <= sizeof(http->wbuffer) && length < sizeof(http->wbuffer))
    {
     /*
      * Write to buffer...
      */

      DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...",
                    CUPS_LLCAST length));

      memcpy(http->wbuffer + http->wused, buffer, length);
      http->wused += (int)length;
      bytes = (ssize_t)length;
    }
    else
    {
     /*
      * Otherwise write the data directly...
      */

      DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...",
                    CUPS_LLCAST length));

      if (http->data_encoding == HTTP_ENCODING_CHUNKED)
	bytes = (ssize_t)http_write_chunk(http, buffer, length);
      else
	bytes = (ssize_t)http_write(http, buffer, length);

      DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...",
                    CUPS_LLCAST bytes));
    }

    if (http->data_encoding == HTTP_ENCODING_LENGTH)
      http->data_remaining -= bytes;
  }
  else
    bytes = 0;

 /*
  * Handle end-of-request processing...
  */

  if ((http->data_encoding == HTTP_ENCODING_CHUNKED && length == 0) ||
      (http->data_encoding == HTTP_ENCODING_LENGTH && http->data_remaining == 0))
  {
   /*
    * Finished with the transfer; unless we are sending POST or PUT
    * data, go idle...
    */

#ifdef HAVE_LIBZ
    if (http->coding == _HTTP_CODING_GZIP || http->coding == _HTTP_CODING_DEFLATE)
      http_content_coding_finish(http);
#endif /* HAVE_LIBZ */

    if (http->wused)
    {
      if (httpFlushWrite(http) < 0)
        return (-1);
    }

    if (http->data_encoding == HTTP_ENCODING_CHUNKED)
    {
     /*
      * Send a 0-length chunk at the end of the request...
      */

      http_write(http, "0\r\n\r\n", 5);

     /*
      * Reset the data state...
      */

      http->data_encoding  = HTTP_ENCODING_FIELDS;
      http->data_remaining = 0;
    }

    if (http->state == HTTP_STATE_POST_RECV)
      http->state ++;
    else if (http->state == HTTP_STATE_POST_SEND ||
             http->state == HTTP_STATE_GET_SEND)
      http->state = HTTP_STATE_WAITING;
    else
      http->state = HTTP_STATE_STATUS;

    DEBUG_printf(("2httpWrite2: Changed state to %s.",
		  httpStateString(http->state)));
  }

  DEBUG_printf(("1httpWrite2: Returning " CUPS_LLFMT ".", CUPS_LLCAST bytes));

  return (bytes);
}