## HTTPClient
Class HttpOutputStream

    java.lang.Object
      java.io.OutputStream
          HTTPClient.HttpOutputStream

public class HttpOutputStream
extends OutputStream

This class provides an output stream for requests. The stream must first be associated with a request before it may be used; this is done by passing it to one of the request methods in HTTPConnection. Example:

        OutputStream out = new HttpOutputStream(12345);
        rsp = con.Post("/cgi-bin/my_cgi", out);
        out.write(...);
        out.close();
        if (rsp.getStatusCode() >= 300)
            ...

There are two constructors for this class, one taking a length parameter, and one without any parameters. If the stream is created with a length then the request will be sent with the corresponding Content-length header and anything written to the stream will be written on the socket immediately. This is the preferred way. If the stream is created without a length then one of two things will happen: if, at the time of the request, the server is known to understand HTTP/1.1 then each write() will send the data immediately using the chunked encoding. If, however, either the server version is unknown (because this is first request to that server) or the server only understands HTTP/1.0 then all data will be written to a buffer first, and only when the stream is closed will the request be sent.

Another reason that using the HttpOutputStream(length) constructor is recommended over the HttpOutputStream() one is that some HTTP/1.1 servers do not allow the chunked transfer encoding to be used when POSTing to a cgi script. This is because the way the cgi API is defined the cgi script expects a Content-length environment variable. If the data is sent using the chunked transfer encoding however, then the server would have to buffer all the data before invoking the cgi so that this variable could be set correctly. Not all servers are willing to do this.

If you cannot use the HttpOutputStream(length) constructor and are having problems sending requests (usually a 411 response) then you can try setting the system property HTTPClient.dontChunkRequests to true (this needs to be done either on the command line or somewhere in the code before the HTTPConnection is first accessed). This will prevent the client from using the chunked encoding in this case and will cause the HttpOutputStream to buffer all the data instead, sending it only when close() is invoked.

The behaviour of a request sent with an output stream may differ from that of a request sent with a data parameter. The reason for this is that the various modules cannot resend a request which used an output stream. Therefore such things as authorization and retrying of requests won't be done by the HTTPClient for such requests. But see `HTTPResponse.retryRequest` for a partial solution.

Since:
  V0.3

Constructor Summary
`HttpOutputStream()` Creates an output stream of unspecified length.
`HttpOutputStream(int length)` This creates an output stream which will take length bytes of data.

Method Summary
`void` `close()` Closes the stream and causes the data to be sent if it has not already been done so.
`int` `getLength()` Returns the number of bytes this stream is willing to accept, or -1 if it is unbounded.
`(package private) Response` `getResponse()` Return the response we got from sendRequest().
`NVPair[]` `getTrailers()` Gets the trailers which were set with `setTrailers()`.
`(package private) void` `goAhead(Request req, OutputStream os, int con_to)` Associates this stream with a request and the actual output stream.
`(package private) void` `ignoreData(Request req)` Setup this stream to dump the data to the great bit-bucket in the sky.
`void` `reset()` Reset this output stream, so it may be reused in a retried request.
`void` `setTrailers(NVPair[] trailers)` Sets the trailers to be sent if the output is sent with the chunked transfer encoding.
`String` `toString()` produces a string describing this stream.
`void` `write(byte[] buf, int off, int len)` Writes an array of bytes on the stream.
`void` `write(int b)` Writes a single byte on the stream.

Methods inherited from class java.io.OutputStream
`flush, write`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

Constructor Detail

### HttpOutputStream

    public HttpOutputStream()

  Creates an output stream of unspecified length. Note that it is highly recommended that this constructor be avoided where possible and `HttpOutputStream(int)` used instead.

See Also:
  `HttpOutputStream(int)`

### HttpOutputStream

    public HttpOutputStream(int length)

  This creates an output stream which will take length bytes of data.

Parameters:
  `length` - the number of bytes which will be sent over this stream

Method Detail

### goAhead

    void goAhead(Request req,
                 OutputStream os,
                 int con_to)

  Associates this stream with a request and the actual output stream. No other methods in this class may be invoked until this method has been invoked by the HTTPConnection.

  Parameters:
    `req` - the request this stream is to be associated with
    `os` - the underlying output stream to write our data to, or null if we should write to a ByteArrayOutputStream instead.
    `con_to` - connection timeout to use in sendRequest()

### ignoreData

    void ignoreData(Request req)

  Setup this stream to dump the data to the great bit-bucket in the sky. This is needed for when a module handles the request directly.

  Parameters:
    `req` - the request this stream is to be associated with

### getResponse

    Response getResponse()

  Return the response we got from sendRequest(). This waits until the request has actually been sent.

  Returns:
    the response returned by sendRequest()

### getLength

    public int getLength()

  Returns the number of bytes this stream is willing to accept, or -1 if it is unbounded.

  Returns:
    the number of bytes

### getTrailers

    public NVPair[] getTrailers()

  Gets the trailers which were set with `setTrailers()`.

  Returns:
    an array of header fields
  See Also:
    `setTrailers(HTTPClient.NVPair[])`

### setTrailers

    public void setTrailers(NVPair[] trailers)

  Sets the trailers to be sent if the output is sent with the chunked transfer encoding. These must be set before the output stream is closed for them to be sent.

  Any trailers set here should be mentioned in a Trailer header in the request (see section 14.40 of draft-ietf-http-v11-spec-rev-06.txt).

  This method (and its related `getTrailers()`)) are in this class and not in Request because setting trailers is something an application may want to do, not only modules.

  Parameters:
    `trailers` - an array of header fields

### reset

    public void reset()

  Reset this output stream, so it may be reused in a retried request. This method may only be invoked by modules, and must never be invoked by an application.

### write

    public void write(int b)
               throws IOException,
                      IllegalAccessError

  Writes a single byte on the stream. It is subject to the same rules as `write(byte[], int, int)`.

  Parameters:
    `b` - the byte to write
  Throws:
    `IOException` - if any exception is thrown by the socket
    `IllegalAccessError`
  See Also:
    `write(byte[], int, int)`

### write

    public void write(byte[] buf,
                      int off,
                      int len)
               throws IOException,
                      IllegalAccessError

  Writes an array of bytes on the stream. This method may not be used until this stream has been passed to one of the methods in HTTPConnection (i.e. until it has been associated with a request).

  Parameters:
    `buf` - an array containing the data to write
    `off` - the offset of the data whithin the buffer
    `len` - the number bytes (starting at off) to write
  Throws:
    `IOException` - if any exception is thrown by the socket, or if writing len bytes would cause more bytes to be written than this stream is willing to accept.
    `IllegalAccessError` - if this stream has not been associated with a request yet

### close

    public void close()
               throws IOException,
                      IllegalAccessError

  Closes the stream and causes the data to be sent if it has not already been done so. This method must be invoked when all data has been written.

  Throws:
    `IOException` - if any exception is thrown by the underlying socket, or if too few bytes were written.
    `IllegalAccessError` - if this stream has not been associated with a request yet.

### toString

    public String toString()

  produces a string describing this stream.

  Returns:
    a string containing the name and the length