Class HttpClientConnection
HttpClientConnection provides a simple HTTP/1.1
compliant connection from a client to an HTTP server. This class does not
provide a full-blown HTTP connection, but it is rather optimized for what
ONC/RPC clients need in order to tunnel ONC remote procedure calls through
ordinary HTTP connections, thus penetrating firewalls.
A HttpClientConnection is not that clever as you would
first expect. Rather you have to do some things for yourself, like
reconnecting dropped connections, and so on. While this sometimes result
in more labour on the caller's shoulders, this keeps resource wasting at
a minimum, and gives you full control over redirections and other mess --
you do want full control, right?.
For this reason, for instance, an HttpClientConnection
does not buffer the whole request before sending it to the server but
rather relies on the caller to supply the right content-length information.
This avoids unnecessary double buffering but instead creates the bas64
encoded content on-the-fly.
Of course, this client connection object does not touch the content, it just suplies the pipe to swallow the data.
- Version:
- $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:45 $ $State: Exp $ $Locker: $
- Author:
- Harald Albrecht
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) class -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate byte[]Buffer receiving ASCII characters from Unicode strings when sending (header) strings to the HTTP server.private StringAddress of proxy host to contact instead of real HTTP server.private intPort number of proxy HTTP server.private booleanIndicates whether the HTTP server send its reply using the chunked transfer encoding.private StringType of content sent by HTTP server.static final byte[]private booleanIndicates whether the end-of-chunks chunk has been read (whow, another one for the Purlitzer price).private char[]Dynamically growing buffer used during header parsing.private StringHost name of HTTP server to contact in the form ofwww.acplt.org.private static final intstatic final intDefault port where HTTP servers listen for incomming requests.private static final intprivate static final intprivate static final intprivate InputStreamprivate booleanprivate intIndicates sending/receiving mode of the HTTP connection.private OutputStreamBuffered output stream used for sending the HTTP headers.private intPort number where to contact the HTTP server.private intContains the amount of data still to be read for the current chunk.private intIndicates the amount of content data which still has to be sent or received.private intContains the HTTP response code from the last request sent to the HTTP server.private SocketTCP/IP socket for communication with the HTTP server.private intTimeout (in milliseconds) for communication with an HTTP server.private booleanIndicates whether a proxy HTTP server needs to be contacted in order to reach the real HTTP server.private String -
Constructor Summary
ConstructorsConstructorDescriptionHttpClientConnection(String hostname) Constructs a newHttpClientConnection.HttpClientConnection(String hostname, int port) Constructs a newHttpClientConnection. -
Method Summary
Modifier and TypeMethodDescriptionintBegin receiving the content sent by the HTTP server.voidbeginPostRequest(String path, String mimeType, int contentLength) Starts a new HTTP "POST" request and sends all necessary HTTP header fields.voidclose()Closes the connection to the HTTP server and frees up some resources.private voidconnect()Connects to the HTTP server.voidThis method silently discards any unread content, if the caller has yet not read all content.voidEnds the HTTP "POST" request.Returns the content type (MIME type, charset, etc.).booleanprivate StringRetrieves the host name where the HTTP proxy server resided from the system properties.private intRetrieves the port number where the HTTP proxy server resides from the system properties.intReturns amount of content still available (to be read).intintRetrieve the current timeout set for remote procedure calls.protected voidhandleOption(String option, String value) Handle options sent by the HTTP server.intreadContentBytes(byte[] buffer, int offset, int length) Read content sent by the HTTP server.private booleanreadHeaderLine(String[] keyvalue) Read in a header line coming over the HTTP connection from the server.private intRead the HTTP headers sent by the servers and also parse them at the same time.private StringreadLine()Read exactly one line, termined by CRLF or either CR or LF, and return it.voidsetTimeout(int milliseconds) Set the timout for sending or receiving information to/from the HTTP server.private voidWrites an ASCII string to the HTTP server (this is buffered first).voidwriteContentBytes(byte[] bytes, int offset, int length) Send (part) of the content to the HTTP server.private voidWrites an ASCII string and appends a line termination in the form of CR followed by LF.
-
Field Details
-
HTTP_DEFAULTPORT
public static final int HTTP_DEFAULTPORTDefault port where HTTP servers listen for incomming requests. This is just a convenience definition to make the code more readable.- See Also:
-
hostname
Host name of HTTP server to contact in the form ofwww.acplt.org. -
port
private int portPort number where to contact the HTTP server. This defaults to the standard port where HTTP servers are expected: port 80. -
socket
TCP/IP socket for communication with the HTTP server. -
timeout
private int timeoutTimeout (in milliseconds) for communication with an HTTP server. -
keepAlive
private boolean keepAlive -
chunkedTransfer
private boolean chunkedTransferIndicates whether the HTTP server send its reply using the chunked transfer encoding. -
remainingChunkLength
private int remainingChunkLengthContains the amount of data still to be read for the current chunk. -
finalChunkSeen
private boolean finalChunkSeenIndicates whether the end-of-chunks chunk has been read (whow, another one for the Purlitzer price). -
contentType
Type of content sent by HTTP server. -
out
Buffered output stream used for sending the HTTP headers. This stream is not used to send content in an HTTP request. -
in
-
responseCode
private int responseCodeContains the HTTP response code from the last request sent to the HTTP server. -
asciiBuffer
private byte[] asciiBufferBuffer receiving ASCII characters from Unicode strings when sending (header) strings to the HTTP server. -
headerLine
private char[] headerLineDynamically growing buffer used during header parsing. -
userAgentId
-
HTTP_DEAD
private static final int HTTP_DEAD- See Also:
-
HTTP_IDLE
private static final int HTTP_IDLE- See Also:
-
HTTP_SENDING
private static final int HTTP_SENDING- See Also:
-
HTTP_RECEIVING
private static final int HTTP_RECEIVING- See Also:
-
mode
private int modeIndicates sending/receiving mode of the HTTP connection. -
remainingContentLength
private int remainingContentLengthIndicates the amount of content data which still has to be sent or received. -
CRLF
public static final byte[] CRLF -
useProxy
private boolean useProxyIndicates whether a proxy HTTP server needs to be contacted in order to reach the real HTTP server. -
cachedProxyHost
Address of proxy host to contact instead of real HTTP server. -
cachedProxyPort
private int cachedProxyPortPort number of proxy HTTP server.
-
-
Constructor Details
-
HttpClientConnection
Constructs a newHttpClientConnection. The port used on the HTTP server side is the default HTTP port, 80.- Parameters:
hostname- name (DNS name or IP dotted address) of host running a HTTP server to which we want to connect to.
-
HttpClientConnection
Constructs a newHttpClientConnection.- Parameters:
hostname- name (DNS name or IP dotted address) of host running a HTTP server to which we should connect to.port- Port number where the HTTP server can be contacted.
-
-
Method Details
-
close
public void close()Closes the connection to the HTTP server and frees up some resources. After callingcloseit is still possible to open a new connection to the HTTP server once again. -
beginPostRequest
Starts a new HTTP "POST" request and sends all necessary HTTP header fields. Next, the caller can send lots of content using thewriteContentBytes(byte[], int, int)method. Finally, to finish the request he has to call theendPostRequest()method.- Parameters:
path- Path to server object which handles the POST request. For instance, this can be a CGI script (although it better should not be one, except in the case of FAST CGI).mimeType- MIME-classified type of content to be sent.contentLength- Length of content to be sent. If negative, the length is not known in advance. In this case, keeping the connection alive is not possible, so callers should avoid this situation, if possible.- Throws:
IOException- if an I/O exception occurs when sending the HTTP headers. In this case the connection is closed automatically and the caller must not send any content. However, the caller is free to give the request another try by callingbeginEncodingagain, thus opening a new HTTP connection.
-
writeContentBytes
Send (part) of the content to the HTTP server. Note that the output is done unbuffered, so callers should write their content in large chunks to avoid the calling overhead for sending data.- Parameters:
bytes- The data.offset- Start offset in the data.length- Number of bytes to write.- Throws:
RuntimeException- if too much content was sent.IOException- if an I/O error occurs.NullPointerException- ifbytesisnull.IndexOutOfBoundsException- ifoffsetis negative, orlengthis negative, oroffset + lengthis greater than the length of the arraybytes.
-
endPostRequest
Ends the HTTP "POST" request. The next logical step for a caller is then to call ... #FIXME- Throws:
IOException
-
handleOption
Handle options sent by the HTTP server.Currently the following options are handled by this class:
- Content-Length -- length of content following the header section
- Content-Type -- type of content sent
- Proxy-Connection -- handle keep-alive request
- Connection -- handle keep-alive request
- Transfer-Encoding -- transfer encoding choosen by HTTP server
- Parameters:
option- Name of option sent by HTTP server.value- Value of option.
-
readHeaders
Read the HTTP headers sent by the servers and also parse them at the same time.- Returns:
- HTTP status code.
- Throws:
IOException
-
readHeaderLine
Read in a header line coming over the HTTP connection from the server.- Parameters:
keyvalue- An array with room for either exactly one or two strings, receiving the header option and optionally its value. If only room for a single return string is supplied, thenreadHeaderLinewill only read in the header line (like the first HTTP header) without separating the options's value from its name. If a header option has no option, thennullis returned as the value string.- Returns:
falseif the end of the headers has been reached.- Throws:
IOException
-
readLine
Read exactly one line, termined by CRLF or either CR or LF, and return it.- Returns:
- Line without the terminating CR, LF or CRLF.
- Throws:
IOException
-
beginDecoding
Begin receiving the content sent by the HTTP server. This method blocks until at least the HTTP header section has been received or until the connection times out.- Returns:
- HTTP server response code (status code).
- Throws:
IOException
-
getContentType
Returns the content type (MIME type, charset, etc.).- Returns:
- content type
-
readContentBytes
Read content sent by the HTTP server. This method also handles the HTTP/1.1 chunked transfer encoding if the HTTP server insisted on using it. If only chunked transfer encoding has been introduced with the first official 0.9 protocol version of HTTP, it would have made sending ONC/RPC requests much easier, because we would not need to buffer the while request before sending it just to know its exact length. Unfortunately, chunking has only been introduced lately so we can not expect servers and especially proxies to handle it. Sigh.- Parameters:
buffer- Buffer to receive the content sent by the HTTP server.offset- Start offset in the buffer.length- Number of bytes to receive.- Throws:
ProtocolException- if not enough content was available (the caller attempted to read more data than available) or if we received junk information violating the HTTP protocol specification.IOException- if an I/O error occurs.NullPointerException- ifbytesisnull.IndexOutOfBoundsException- ifoffsetis negative, orlengthis negative, oroffset + lengthis greater than the length of the arraybytes.
-
getRemainingContentLength
public int getRemainingContentLength()Returns amount of content still available (to be read). This always shows the remaining amount and is updated whenever content is read usingreadContentBytes(byte[], int, int).- Returns:
- Amount of content available.
-
endDecoding
This method silently discards any unread content, if the caller has yet not read all content.
- Throws:
IOException
-
setTimeout
public void setTimeout(int milliseconds) Set the timout for sending or receiving information to/from the HTTP server.- Parameters:
milliseconds- Timeout in milliseconds.
-
getTimeout
public int getTimeout()Retrieve the current timeout set for remote procedure calls. A timeout of zero indicates batching calls (no reply message is expected).- Returns:
- Current timeout.
-
getResponseCode
public int getResponseCode() -
getKeepAlive
public boolean getKeepAlive() -
connect
Connects to the HTTP server. In case an HTTP proxy has been configured, this connects to the proxy instead.If the connection is in keep-alive mode and already open, then the connection is reused.
- Throws:
SecurityException- if a security manager exists and itscheckConnectmethod does not allow the connect operation.IOException
-
write
Writes an ASCII string to the HTTP server (this is buffered first).- Parameters:
s- String to write.- Throws:
IOException
-
writeln
Writes an ASCII string and appends a line termination in the form of CR followed by LF.- Parameters:
s- String to write.- Throws:
IOException
-
getProxyHost
Retrieves the host name where the HTTP proxy server resided from the system properties.- Returns:
- Name of proxy host or
nullif no proxy has been configured.
-
getProxyPort
private int getProxyPort()Retrieves the port number where the HTTP proxy server resides from the system properties. If no port number has been configured for the HTTP proxy, then the default http port number of 80 is returned.- Returns:
- Port number of HTTP proxy server.
-