HTTPClient
Class StreamDemultiplexor

java.lang.Object
  extended byHTTPClient.StreamDemultiplexor
All Implemented Interfaces:
GlobalConstants

class StreamDemultiplexor
extends Object
implements GlobalConstants

This class handles the demultiplexing of input stream. This is needed for things like keep-alive in HTTP/1.0, persist in HTTP/1.1 and in HTTP-NG.


Field Summary
static int CD_0
           
static int CD_CHUNKED
           
static int CD_CLOSE
           
static int CD_CONTLEN
           
static int CD_HDRS
           
static int CD_MP_BR
           
static int CD_NONE
          Content delimiters
static int HTTP
          possible http protocols we (might) handle
static int HTTP_1_0
          some known http versions
static int HTTP_1_1
           
static int HTTP_NG
           
static int HTTPS
           
static int SHTTP
           
 
Constructor Summary
(package private) StreamDemultiplexor(int protocol, Socket sock, HTTPConnection connection)
          a simple contructor.
 
Method Summary
(package private)  void abort()
          Emergency stop.
(package private)  int available(ResponseHandler resph)
          Determines the number of available bytes.
(package private)  void close(IOException exception, boolean was_reset)
          Closes the socket and all associated streams.
(package private)  void closeSocketIfAllStreamsClosed()
          Close the socket if all the streams have been closed.
protected  void finalize()
          A safety net to close the connection.
(package private)  Socket getSocket()
          returns the socket associated with this demux
(package private)  RespInputStream getStream(Response resp)
          creates an input stream for the response.
(package private)  void markForClose(Response resp)
          Mark this demux to not accept any more request and to close the stream after this response or all requests have been processed, or close immediately if no requests are registered.
(package private)  int read(byte[] b, int off, int len, ResponseHandler resph, int timeout)
          reads an array of bytes from the master stream.
(package private)  void register(Response resp_handler, Request req)
          Each Response must register with us.
(package private)  void restartTimer()
          Restarts the timer thread that will close an unused socket after 60 seconds.
(package private)  long skip(long num, ResponseHandler resph)
          skips a number of bytes in the master stream.
 String toString()
          produces a string.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

HTTP

public static final int HTTP
possible http protocols we (might) handle

See Also:
Constant Field Values

HTTPS

public static final int HTTPS
See Also:
Constant Field Values

SHTTP

public static final int SHTTP
See Also:
Constant Field Values

HTTP_NG

public static final int HTTP_NG
See Also:
Constant Field Values

HTTP_1_0

public static final int HTTP_1_0
some known http versions

See Also:
Constant Field Values

HTTP_1_1

public static final int HTTP_1_1
See Also:
Constant Field Values

CD_NONE

public static final int CD_NONE
Content delimiters

See Also:
Constant Field Values

CD_HDRS

public static final int CD_HDRS
See Also:
Constant Field Values

CD_0

public static final int CD_0
See Also:
Constant Field Values

CD_CLOSE

public static final int CD_CLOSE
See Also:
Constant Field Values

CD_CONTLEN

public static final int CD_CONTLEN
See Also:
Constant Field Values

CD_CHUNKED

public static final int CD_CHUNKED
See Also:
Constant Field Values

CD_MP_BR

public static final int CD_MP_BR
See Also:
Constant Field Values
Constructor Detail

StreamDemultiplexor

StreamDemultiplexor(int protocol,
                    Socket sock,
                    HTTPConnection connection)
              throws IOException
a simple contructor.

Parameters:
protocol - the protocol used on this stream.
sock - the socket which we're to demux.
connection - the http-connection this socket belongs to.
Method Detail

register

void register(Response resp_handler,
              Request req)
        throws RetryException
Each Response must register with us.

Throws:
RetryException

getStream

RespInputStream getStream(Response resp)
creates an input stream for the response.

Parameters:
resp - the response structure requesting the stream
Returns:
an InputStream

restartTimer

void restartTimer()
Restarts the timer thread that will close an unused socket after 60 seconds.


read

int read(byte[] b,
         int off,
         int len,
         ResponseHandler resph,
         int timeout)
   throws IOException
reads an array of bytes from the master stream.

Throws:
IOException

skip

long skip(long num,
          ResponseHandler resph)
    throws IOException
skips a number of bytes in the master stream. This is done via a dummy read, as the socket input stream doesn't like skip()'s.

Throws:
IOException

available

int available(ResponseHandler resph)
        throws IOException
Determines the number of available bytes. If resph is null, return available bytes on the socket stream itself (used by HTTPConnection).

Throws:
IOException

close

void close(IOException exception,
           boolean was_reset)
Closes the socket and all associated streams. If exception is not null then all active requests are retried.

There are five ways this method may be activated. 1) if an exception occurs during read or write. 2) if the stream is marked for close but no responses are outstanding (e.g. due to a timeout). 3) when the markedForClose response is closed. 4) if all response streams up until and including the markedForClose response have been closed. 5) if this demux is finalized.

Parameters:
exception - the IOException to be sent to the streams.
was_reset - if true then the exception is due to a connection reset; otherwise it means we generated the exception ourselves and this is a "normal" close.

closeSocketIfAllStreamsClosed

void closeSocketIfAllStreamsClosed()
Close the socket if all the streams have been closed.

When a stream reaches eof it is removed from the response handler list, but when somebody close()'s the response stream it is just marked as such. This means that all responses in the list have either not been read at all or only partially read, but they might have been close()'d meaning that nobody is interested in the data. So If all the response streams up till and including the one markedForClose have been close()'d then we can remove them from our list and close the socket.

Note: if the response list is emtpy or if no response is markedForClose then this method does nothing. Specifically it does not close the socket. We only want to close the socket if we've been told to do so.

Also note that there might still be responses in the list after the markedForClose one. These are due to us having pipelined more requests to the server than it's willing to serve on a single connection. These requests will be retried if possible.


getSocket

Socket getSocket()
returns the socket associated with this demux


markForClose

void markForClose(Response resp)
Mark this demux to not accept any more request and to close the stream after this response or all requests have been processed, or close immediately if no requests are registered.


abort

void abort()
Emergency stop. Closes the socket and notifies the responses that the requests are aborted.

Since:
V0.3

finalize

protected void finalize()
                 throws Throwable
A safety net to close the connection.

Throws:
Throwable

toString

public String toString()
produces a string.

Returns:
a string containing the class name and protocol number