This is a low-level, efficient representation of a server request. Most
fields are GC-free, expensive operations are delayed until the user code
needs the information.
Processing is delegated to modules, using a hook mechanism.
This class is not intended for user code - it is used internally by tomcat
for processing the request in the most efficient way. Users ( servlets ) can
access the information using a facade, which provides the high-level view
of the request.
For lazy evaluation, the request uses the getInfo() hook. The following ids
are defined:
Method from org.apache.coyote.Request Detail: |
public void action(ActionCode actionCode,
Object param) {
if( hook==null && response!=null )
hook=response.getHook();
if (hook != null) {
if( param==null )
hook.action(actionCode, this);
else
hook.action(actionCode, param);
}
}
|
public MessageBytes contentType() {
if (contentTypeMB == null)
contentTypeMB = headers.getValue("content-type");
return contentTypeMB;
}
|
public MessageBytes decodedURI() {
return decodedUriMB;
}
|
public int doRead(ByteChunk chunk) throws IOException {
int n = inputBuffer.doRead(chunk, this);
if (n > 0) {
bytesRead+=n;
}
return n;
}
Read data from the input buffer and put it into a byte chunk.
The buffer is owned by the protocol implementation - it will be reused on the next read.
The Adapter must either process the data in place or copy it to a separate buffer if it needs
to hold it. In most cases this is done during byte->char conversions or via InputStream. Unlike
InputStream, this interface allows the app to process data in place, without copy. |
public Object getAttribute(String name) {
return attributes.get(name);
}
|
public HashMap getAttributes() {
return attributes;
}
|
public MessageBytes getAuthType() {
return authType;
}
|
public int getAvailable() {
return available;
}
|
public int getBytesRead() {
return bytesRead;
}
|
public String getCharacterEncoding() {
if (charEncoding != null)
return charEncoding;
charEncoding = ContentType.getCharsetFromContentType(getContentType());
return charEncoding;
}
Get the character encoding used for this request. |
public int getContentLength() {
long length = getContentLengthLong();
if (length < Integer.MAX_VALUE) {
return (int) length;
}
return -1;
}
|
public long getContentLengthLong() {
if( contentLength > -1 ) return contentLength;
MessageBytes clB = headers.getUniqueValue("content-length");
contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong();
return contentLength;
}
|
public String getContentType() {
contentType();
if ((contentTypeMB == null) || contentTypeMB.isNull())
return null;
return contentTypeMB.toString();
}
|
public Cookies getCookies() {
return cookies;
}
|
public String getHeader(String name) {
return headers.getHeader(name);
}
|
public InputBuffer getInputBuffer() {
return inputBuffer;
}
|
public int getLocalPort() {
return localPort;
}
|
public MimeHeaders getMimeHeaders() {
return headers;
}
|
public final Object getNote(int pos) {
return notes[pos];
}
|
public Parameters getParameters() {
return parameters;
}
|
public int getRemotePort() {
return remotePort;
}
|
public MessageBytes getRemoteUser() {
return remoteUser;
}
|
public RequestInfo getRequestProcessor() {
return reqProcessorMX;
}
|
public Response getResponse() {
return response;
}
|
public int getServerPort() {
return serverPort;
}
|
public long getStartTime() {
return startTime;
}
|
public UDecoder getURLDecoder() {
return urlDecoder;
}
|
public MessageBytes instanceId() {
return instanceId;
}
Get the instance id (or JVM route). Curently Ajp is sending it with each
request. In future this should be fixed, and sent only once ( or
'negociated' at config time so both tomcat and apache share the same name. |
public MessageBytes localAddr() {
return localAddrMB;
}
|
public MessageBytes localName() {
return localNameMB;
}
|
public MessageBytes method() {
return methodMB;
}
|
public MessageBytes protocol() {
return protoMB;
}
|
public MessageBytes query() {
return queryMB;
}
|
public MessageBytes queryString() {
return queryMB;
}
|
public void recycle() {
bytesRead=0;
contentLength = -1;
contentTypeMB = null;
charEncoding = null;
headers.recycle();
serverNameMB.recycle();
serverPort=-1;
localPort = -1;
remotePort = -1;
available = 0;
cookies.recycle();
parameters.recycle();
unparsedURIMB.recycle();
uriMB.recycle();
decodedUriMB.recycle();
queryMB.recycle();
methodMB.recycle();
protoMB.recycle();
schemeMB.recycle();
instanceId.recycle();
remoteUser.recycle();
authType.recycle();
attributes.clear();
}
|
public MessageBytes remoteAddr() {
return remoteAddrMB;
}
|
public MessageBytes remoteHost() {
return remoteHostMB;
}
|
public MessageBytes requestURI() {
return uriMB;
}
|
public MessageBytes scheme() {
return schemeMB;
}
|
public MessageBytes serverName() {
return serverNameMB;
}
Return the buffer holding the server name, if
any. Use isNull() to check if there is no value
set.
This is the "virtual host", derived from the
Host: header. |
public void setAttribute(String name,
Object o) {
attributes.put( name, o );
}
|
public void setAvailable(int available) {
this.available = available;
}
|
public void setBytesRead(int bytesRead) {
this.bytesRead = bytesRead;
}
|
public void setCharacterEncoding(String enc) {
this.charEncoding = enc;
}
|
public void setContentLength(int len) {
this.contentLength = len;
}
|
public void setContentType(String type) {
contentTypeMB.setString(type);
}
|
public void setContentType(MessageBytes mb) {
contentTypeMB=mb;
}
|
public void setInputBuffer(InputBuffer inputBuffer) {
this.inputBuffer = inputBuffer;
}
|
public void setLocalPort(int port) {
this.localPort = port;
}
|
public final void setNote(int pos,
Object value) {
notes[pos] = value;
}
Used to store private data. Thread data could be used instead - but
if you have the req, getting/setting a note is just a array access, may
be faster than ThreadLocal for very frequent operations.
Example use:
Jk:
HandlerRequest.HOSTBUFFER = 10 CharChunk, buffer for Host decoding
WorkerEnv: SSL_CERT_NOTE=16 - MessageBytes containing the cert
Catalina CoyoteAdapter:
ADAPTER_NOTES = 1 - stores the HttpServletRequest object ( req/res)
To avoid conflicts, note in the range 0 - 8 are reserved for the
servlet container ( catalina connector, etc ), and values in 9 - 16
for connector use.
17-31 range is not allocated or used. |
public void setRemotePort(int port) {
this.remotePort = port;
}
|
public void setResponse(Response response) {
this.response=response;
response.setRequest( this );
}
|
public void setServerPort(int serverPort) {
this.serverPort=serverPort;
}
|
public void setStartTime(long startTime) {
this.startTime = startTime;
}
|
public String toString() {
return "R( " + requestURI().toString() + ")";
}
|
public MessageBytes unparsedURI() {
return unparsedURIMB;
}
|
public void updateCounters() {
reqProcessorMX.updateCounters();
}
|