sunlabs.brazil.server
public class Request extends Object
Provides a set of accessor functions to fetch the individual fields of the HTTP request.
Utility methods that are generically useful for manipulating HTTP requests are included here as well. An instance of this class is passed to handlers. There will be exactly one request object per thead at any time.
The fields {@link #headers}, {@link #query}, and {@link #url}, and the method {@link #getQueryData()} are most often used to examine the content of the request. The field {@link #props} contains information about the server, or up-stream handlers.
The methods {@link #sendResponse(String, String, int)} and {@link Request#sendError(int, String)} are commonly used to return content to the client. The methods {@link #addHeader(String)} and {@link #setStatus(int)} can be used to modify the response headers and return code respectively before the response is sent.
Many of the other methods are used internally, but can be useful to
handlers that need finer control over the output that the above methods
provide. Note that the order of the methods is important. For instance,
the user cannot change the HTTP response headers (by calling the
addHeader
method or by modifying the
responseHeaders
field) after having already sent an HTTP
response.
A number of the fields in the Request
object are public,
by design. Many of the methods are convenience methods; the underlying
data fields are meant to be accessed for more complicated operations,
such as changing the URL or deleting HTTP response headers.
Version: 2.11
See Also: Handler
Nested Class Summary | |
---|---|
static class | Request.HttpOutputStream
The HttpOutputStream provides the convenience method
writeBytes for writing the byte representation of a
string, without bringing in the overhead and the deprecated warnings
associated with a java.io.DataOutputStream .
|
Field Summary | |
---|---|
String | connectionHeader
The header "Connection" usually controls whether the client
connection will be of type "Keep-Alive" or "close". |
MimeHeaders | headers
The HTTP request headers. |
protected boolean | headersSent |
protected HttpInputStream | in |
boolean | keepAlivetrue if the client requested a persistent connection,
false otherwise. |
String | method
The HTTP request method, such as "GET", "POST", or "PUT". |
static int | MAX_BLANKS
Maximum number of blank lines allowed between requests before
aborting the connecion. |
Request.HttpOutputStream | out
The HTTP response to the client is written to this stream. |
byte[] | postData
The uploaded content of this request, usually from a POST. |
PropertiesList | props
A set of properties local to this request. |
String | protocol
The HTTP protocol specified in the request, either "HTTP/1.0" or
"HTTP/1.1".
|
String | query
The query string specified after the URL, or "" if no
query string was specified. |
protected int | requestsLeft |
MimeHeaders | responseHeaders
The HTTP response headers. |
Server | server
The server that initiated this request. |
PropertiesList | serverProps
A PropertiesList object that wraps
server.props . |
String | serverProtocol
This is the server's protocol. |
Socket | sock
Our connection to the client. |
long | startMillis
Time stamp for start of this request - set, but not used. |
protected int | statusCode |
protected String | statusPhrase |
String | url
The URL specified in the request, not including any "? |
int | version
Derived from {@link #protocol}, the version of the HTTP protocol
used for this request. |
Constructor Summary | |
---|---|
protected | Request(Server server, Socket sock)
Create a new http request. |
protected | Request()
Needed by VelocityFilter.Vrequest. |
Method Summary | |
---|---|
void | addHeader(String key, String value)
Adds a response header to the HTTP response. |
void | addHeader(String line)
Adds a response header to the HTTP response. |
boolean | addSharedProps(Dictionary d)
Adds the given Dictionary to the set of properties that
are searched by request.props.getProperty() . |
Hashtable | getQueryData(Hashtable table)
Retrieves the query data as a hashtable.
|
Hashtable | getQueryData()
Retrieves the query data as a hashtable.
|
boolean | getRequest()
Reads an HTTP request from the socket.
|
String | getRequestHeader(String key)
Returns the value that the given case-insensitive key maps to
in the HTTP request headers. |
int | getReuseCount()
Return uses of this socket |
Socket | getSocket()
The socket from which the HTTP request was received, and to where the
HTTP response will be written. |
int | getStatus()
Return the status code. |
void | log(int level, String message)
Logs a message by calling Server.log . |
void | log(int level, Object obj, String message)
Logs a message by calling Server.log . |
void | redirect(String url, String body)
Responds to an HTTP request with a redirection reply, telling the
client that the requested url has moved. |
boolean | removeSharedProps(Dictionary d)
Removes a Dictionary added by
addSharedProps . |
void | sendError(int code, String clientMessage)
Sends a HTTP error response to the client.
|
void | sendError(int code, String clientMessage, String logMessage)
Sends a HTTP error response to the client.
|
void | sendHeaders(int code, String type, int length)
Sends the HTTP status line and response headers to the client. |
void | sendResponse(byte[] body, String type)
Sends an HTTP response to the client.
|
void | sendResponse(String body, String type, int code)
Sends an HTTP response to the client.
|
void | sendResponse(String body)
Convenience method that sends an HTTP response to the client
with a "Content-Type" of "text/html" and the default HTTP status
code.
|
void | sendResponse(String body, String type)
Convenience method that sends an HTTP response to the client
with the default HTTP status code.
|
void | sendResponse(InputStream in, int length, String type, int code)
Sends the contents of the given input stream as the HTTP response.
|
String | serverUrl()
Returns the server's fully-qualified base URL. |
void | setStatus(int code)
Sets the status code of the HTTP response. |
protected void | setStatus(int code, String message)
Set the HTTP status code and status phrase of this request. |
String | toString()
Returns a string representation of this Request .
|
The field {@link #keepAlive} is set based on the value of the
"Connection" header. However, not all clients use "Connection"
to request that the connection be kept alive. For instance (although
it does not appear in the HTTP/1.0 or HTTP/1.1 documentation) both
Netscape and IE use the "Proxy-Connection" header when issuing
requests via an HTTP proxy. If a Handler
is written to
respond to HTTP proxy requests, it should set keepAlive
depending on the value of the "Proxy-Connection" header, and set
connectionHeader
to "Proxy-Connection", since the
convenience methods like setResponse()
use these fields
when constructing the response. The server does not handle the
"Proxy-Connection" header by default, since trying to pre-anticipate
all the exceptions to the specification is a "slippery slope".
true
if the client requested a persistent connection,
false
otherwise. Derived from the {@link #protocol} and
the {@link #headers},
When "Keep-Alive" is requested, the client can issue multiple, consecutive requests via a single socket connection. By default:
true
to
false
to forcefully close the connection to the client
after sending the response. The user can change this value from
false
to true
if the client is using a
different header to request a persistent connection. See
{@link #connectionHeader}.
Regardless of this value, if an error is detected while receiving or responding to an HTTP request, the connection will be closed.
sendResponse
, are used
to send the response, but this field is available if a handler
needs to generate the response specially.
If the user chooses to write the response directly to this stream, the
user is still encouraged to use the convenience methods, such as
sendHeaders
, to first send the HTTP response headers.
The {@link sunlabs.brazil.filter.FilterHandler}
examines the HTTP response headers
set by the convenience methods to determine whether to filter the
output.
Note that the HTTP response headers will not automatically be
sent as a side effect if the user writes to this stream. The user
would either need to call the convenience method
sendHeaders
or need to generate the HTTP response headers
themselves.
This variable is declared as a Request.HttpOutputStream
,
which provides the convenience method writeBytes
to write
the byte representation of a string back to the client. If the user
does not need this functionality, this variable may be accessed
simply as a normal OutputStream
.
null
if the request has no content.PropertiesList
object and initially is the head
of a linked list of properties that are searched in order.
This is useful for handlers that wish to communicate via properties
to down-stream handlers, such as modifying a server property for a
particular request. Some handlers may even add entire new sets of
properties onto the front of request.props
to temporarily
modify the properties seen by downstream handlers.See Also: version
""
if no
query string was specified.See Also: Request
PropertiesList
object that wraps
server.props
. When this request
is
created, a new PropertiesList
wrapping
server.props
is created and added to a list consisting
only of props
and serverProps
.NOTE: Traditionally handlers modify this as needed. The request property "url.orig" is set to match the url at creation time, and should be considered "Read only", for those cases where the original url is required.
10
for "HTTP/1.0" or
11
for "HTTP/1.1".Parameters: server The server that owns this request. sock The socket of the incoming HTTP request.
Request
object.responseHeaders
field.
If this method is called, it must be called before
sendHeaders
is either directly or indirectly called.
Otherwise, it will have no effect.
Parameters: key The header name. value The value for the request header.
See Also: Request responseHeaders
responseHeaders
field.
If this method is called, it must be called before
sendHeaders
is either directly or indirectly called.
Otherwise, it will have no effect.
Parameters: line
The HTTP response header, of the form
"key
: value
".
See Also: Request responseHeaders
Dictionary
to the set of properties that
are searched by request.props.getProperty()
. This method
is used to optimize the case when the caller has an existing
Dictionary
object that should be added to the search
chain.
Assume the caller is constructing a new Properties
object and wants to chain it onto the front of
request.props
. The following code is appropriate:
However,
/* Push a temporary Dictionary onto request.props. */
PropertiesList old = request.props;
(new PropertiesList()).addBefore(request.props);
request.props = request.props.getPrior();
request.props.put("foo", "bar");
request.props.put("baz", "garply");
/* Do something that accesses new properties. */
.
.
.
/* Restore old Dictionary when done. */
request.props.remove();
request.props = old;
addSharedProps
may be called when the caller
has an existing set of Properties
and is faced with
copying its contents into request.props
and/or trying
to share the existing Properties
object among multiple
threads concurrently.
is more efficient and esthetically pleasing than:
/* Some properties created at startup. */
static Properties P = new Properties();
.
.
.
/* Share properties at runtime. */
request.addSharedProps(P);
The given
foreach key in P.keys() {
request.props.put(key, P.get(key));
}
Dictionary
object is added to the
Properties.getProperty()
search chain before serverProps;
it will be searched after the
request.props
and before serverProps
.
Multiple Dictionary
objects can be added and they will
be searched in the order given. The same Dictionary
object can be added multiple times safely. However, the search
chain for the given Dictionary
must not refer back to
request.props
itself or a circular chain will be
created causing an infinite loop:
Subsequent calls to
request.addSharedProps(request.props); // Bad
request.addSharedProps(request.props.getWrapped()); // Good
Properties d1 = new Properties(request.props);
request.addSharedProps(d1); // Bad
Hashtable d2 = new Hashtable();
Properties d3 = new Properties();
request.addSharedProps(d2); // Good
request.addSharedProps(d3); // Good
request.props.getProperty()
may
fetch properties from an added Dictionary
, but
request.put()
will not modify those dictionaries.
Parameters: d
A Dictionary
of String
key/value
pairs that will be added to the chain searched
when request.props.getProperty()
is called. The
dictionary d
is "live", meaning that external
changes to the contents of d
will be seen on
subsequent calls to request.props.getProperty()
.
Returns: false
if the dictionary had already been added
by a previous call to this method, true
otherwise.
Parameters: table
An existing hashtable in which to put the query data as
name/value pairs. May be null
, in which case
a new hashtable is allocated.
Returns: The hashtable in which the query data was stored.
Returns: The hashtable in which the query data was stored.
Returns: true
if the request was successfully read and
parsed, false
if the request was malformed.
Throws: IOException if there was an IOException reading from the socket. See the socket documentation for a description of socket exceptions.
headers
field.
Parameters: key
The key to look for in the HTTP request headers. May not
be null
.
Returns: The value to which the given key is mapped, or
null
if the key is not in the headers.
See Also: headers
Returns: The client socket that issued this HTTP request.
Server.log
. Typically a
message is generated on the console or in a log file, if the
level
is less than the current server log setting.
Parameters: level The severity of the message. message The message that will be logged.
See Also: Server
Server.log
. Typically a
message is generated on the console or in a log file, if the
level
is less than the current server log setting.
Parameters: level The severity of the message. obj The object that the message relates to. message The message that will be logged.
See Also: Server
Parameters: url
The URL the client should have requested. This URL may be
fully-qualified (in the form "http://....") or host-relative
(in the form "/...").
body
The body of the redirect response, or null
to
send a hardcoded message.
Dictionary
added by
addSharedProps
. Dictionary
objects may
be removed in any order. Dictionary
objects do not need
to be removed; they will automatically get cleaned up at the end of
the request.
Parameters: d
The Dictionary
object to remove from the
request.props.getProperty()
search chain.
Returns: true
if the Dictionary
was found
and removed, false
if the Dictionary
was not found (it had already been removed or had never been
added).
Parameters: code The HTTP status code. clientMessage A short message to be included in the error response and logged to the server.
Parameters: code The HTTP status code. clientMessage A short message to be included in the error response. logMessage A short message to be logged to the server. This message is not sent to the client.
sendResponse
, but
can be manually invoked if the user needs direct access to the
client's output stream. If this method is not called, then the
HTTP status and response headers will not automatically be sent to
the client; the user would be responsible for forming the entire
HTTP response.
The user may call the addHeader
method or modify the
responseHeaders
field before calling this method.
This method then adds a number of HTTP headers, as follows:
server.name
), if
this header is not already present.
keepAlive
field.
length
.
type
.
The string used for "Connection" header actually comes from the
connectionHeader
field.
Parameters: code
The HTTP status code for the response, such as
200
. May be < 0 to preserve the existing
status code.
type
The MIME type of the response, such as "text/html". May be
null
to preserve the existing "Content-Type"
response header (if any).
length
The length of the response body. May be < 0 if the length
is unknown and/or to preserve the existing "Content-Length"
response header (if any).
Throws: IOException if there was an I/O error while sending the headers to the client.
See Also: Request Request Request connectionHeader
This method first calls sendHeaders
to send the HTTP
response headers, then sends the given byte array as the HTTP
response body. If the request method is HEAD, or the result
code is "204", the body is not sent.
The "Content-Length" will be set to the length of the given byte array. The "Content-Type" will be set to the given MIME type.
Parameters: body
The array of bytes to send as the HTTP response body. May
not be null
.
type
The MIME type of the response, such as "text/html". May be
null
to use the existing "Content-Type"
response header (if any).
Throws: IOException if there was an I/O error while sending the response to the client.
See Also: Request
This method first calls sendHeaders
to send the HTTP
response headers. It then writes out the given string to the client
as a sequence of bytes. Each character in the string is written out
by discarding its high eight bits.
The "Content-Length" will be set to the length of the string. The "Content-Type" will be set to the given MIME type.
Note: to use a different character encoding, use
sendResponse(body.getBytes(encoding)...)
instead.
Parameters: body
The string to send as the HTTP response body. May
not be null
. If the request method is HEAD,
the body is not sent.
type
The MIME type of the response, such as "text/html". May be
null
to preserve the existing "Content-Type"
response header (if any).
code
The HTTP status code for the response, such as
200
. May be < 0 to preserve the existing
status code.
Throws: IOException if there was an I/O error while sending the response to the client.
See Also: Request
Parameters: body The string to send as the HTTP response body.
See Also: Request
Parameters: body The string to send as the HTTP response body. If the request method is HEAD, only the headers are sent to the client. type The MIME type of the response.
See Also: Request
This method first calls sendHeaders
to send the HTTP
response headers. It then transfers a total of length
bytes of data from the given input stream to the client as the
HTTP response body.
This method takes care of setting the "Content-Length" header if the actual content length is known, or the "Transfer-Encoding" header if the content length is not known (for HTTP/1.1 clients only).
This method may set the keepAlive
to false
before returning, if fewer than length
bytes could be
read. If the request method is HEAD, only the headers are sent.
Parameters: in
The input stream to read from.
length
The content length. The number of bytes to send to the
client. May be < 0, in which case this method will read
until reaching the end of the input stream.
type
The MIME type of the response, such as "text/html". May be
null
to preserve the existing "Content-Type"
response header (if any).
code
The HTTP status code for the response, such as
200
. May be < 0 to preserve the existing
status code.
Throws: IOException if there was an I/O error while sending the response to the client.
If the HTTP request header "Host" is present, it specifies the
hostname and port that will be used instead of the server's internal
name for itself. Due bugs in certain browsers, when using the server's
internal name, the port number will be elided if it is 80
.
Returns: The string representation of the server's URL.
200
if this method is not
called.
An HTTP status phrase will be chosen based on the given
status code. For example, the status code 404
will get
the status phrase "Not Found".
If this method is called, it must be called before
sendHeaders
is either directly or indirectly called.
Otherwise, it will have no effect.
Parameters: code
The HTTP status code, such as 200
or
404
. If < 0, the HTTP status code will
not be changed.
See Also: Request
sendHeaders
. The given status phrase
replaces the default HTTP status phrase normally associated with the
given status code.
Parameters: code
The HTTP status code, such as 200
or
404
.
message
The HTTP status phrase, such as "Okey dokey"
or
"I don't see it"
.
See Also: Request
Request
.
The string representation is the first line (the method line) of the
HTTP request that this Request
is handling. Useful for
debugging.
Returns: The string representation of this Request
.