/**
  * This method is used to flush the contents of the buffer to the client. This method will block
  * until such time as all of the data has been sent to the client. If at any point there is an
  * error sending the content an exception is thrown.
  */
 public void flush() throws IOException {
   try {
     if (!monitor.isClosed()) {
       sender.flush();
     }
   } catch (Exception cause) {
     if (sender != null) {
       monitor.close(sender);
     }
     throw new ProducerException("Error sending response", cause);
   }
 }
  /**
   * This method is used to encode the provided buffer of bytes in a HTTP/1.1 compliant format and
   * sent it to the client. Once the data has been encoded it is handed to the transport layer
   * within the server, which may choose to buffer the data if the content is too small to send
   * efficiently or if the socket is not write ready.
   *
   * @param buffer this is the buffer of bytes to send to the client
   * @param off this is the offset within the buffer to send from
   * @param len this is the number of bytes that are to be sent
   */
  public void produce(ByteBuffer buffer, int off, int len) throws IOException {
    int pos = 7;

    if (monitor.isClosed()) {
      throw new ProducerException("Stream has been closed");
    }
    if (len > 0) {
      for (int num = len; num > 0; num >>>= 4) {
        size[pos--] = index[num & 0xf];
      }
      try {
        sender.send(size, pos + 1, 9 - pos);
        sender.send(buffer, off, len);
        sender.send(size, 8, 2);
      } catch (Exception cause) {
        if (sender != null) {
          monitor.error(sender);
        }
        throw new ProducerException("Error sending response", cause);
      }
    }
  }
 /**
  * This is used to signal to the producer that all content has been written and the user no longer
  * needs to write. This will either close the underlying transport or it will notify the monitor
  * that the response has completed and the next request can begin. This ensures the content is
  * flushed to the client.
  */
 public void close() throws IOException {
   if (!monitor.isClosed()) {
     finish();
   }
 }