📄 handlerrequest.java
字号:
return OK;
default:
if(log.isInfoEnabled())
log.info("Unknown message " + type);
}
return OK;
}
static int count = 0;
private Request checkRequest(MsgContext ep) {
Request req=ep.getRequest();
if( req==null ) {
req=new Request();
Response res=new Response();
req.setResponse(res);
ep.setRequest( req );
if( registerRequests ) {
synchronized(lock) {
ep.getSource().registerRequest(req, ep, count++);
}
}
}
return req;
}
private int decodeRequest( Msg msg, MsgContext ep, MessageBytes tmpMB )
throws IOException {
// FORWARD_REQUEST handler
Request req = checkRequest(ep);
RequestInfo rp = req.getRequestProcessor();
rp.setStage(Constants.STAGE_PARSE);
MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
if(tmpMB2 != null) {
tmpMB2.recycle();
}
req.setStartTime(System.currentTimeMillis());
// Translate the HTTP method code to a String.
byte methodCode = msg.getByte();
if (methodCode != AjpConstants.SC_M_JK_STORED) {
String mName=AjpConstants.methodTransArray[(int)methodCode - 1];
req.method().setString(mName);
}
msg.getBytes(req.protocol());
msg.getBytes(req.requestURI());
msg.getBytes(req.remoteAddr());
msg.getBytes(req.remoteHost());
msg.getBytes(req.localName());
req.setLocalPort(msg.getInt());
boolean isSSL = msg.getByte() != 0;
if( isSSL ) {
// XXX req.setSecure( true );
req.scheme().setString("https");
}
decodeHeaders( ep, msg, req, tmpMB );
decodeAttributes( ep, msg, req, tmpMB );
rp.setStage(Constants.STAGE_PREPARE);
MessageBytes valueMB = req.getMimeHeaders().getValue("host");
parseHost(valueMB, req);
// set cookies on request now that we have all headers
req.getCookies().setHeaders(req.getMimeHeaders());
// Check to see if there should be a body packet coming along
// immediately after
int cl=req.getContentLength();
if(cl > 0) {
JkInputStream jkIS = ep.getInputStream();
jkIS.setIsReadRequired(true);
if(!delayInitialRead) {
jkIS.receive();
}
}
if (log.isTraceEnabled()) {
log.trace(req.toString());
}
return OK;
}
private int decodeAttributes( MsgContext ep, Msg msg, Request req,
MessageBytes tmpMB) {
boolean moreAttr=true;
while( moreAttr ) {
byte attributeCode=msg.getByte();
if( attributeCode == AjpConstants.SC_A_ARE_DONE )
return 200;
/* Special case ( XXX in future API make it separate type !)
*/
if( attributeCode == AjpConstants.SC_A_SSL_KEY_SIZE ) {
// Bug 1326: it's an Integer.
req.setAttribute(SSLSupport.KEY_SIZE_KEY,
new Integer( msg.getInt()));
//Integer.toString(msg.getInt()));
}
if( attributeCode == AjpConstants.SC_A_REQ_ATTRIBUTE ) {
// 2 strings ???...
msg.getBytes( tmpMB );
String n=tmpMB.toString();
msg.getBytes( tmpMB );
String v=tmpMB.toString();
req.setAttribute(n, v );
if(log.isTraceEnabled())
log.trace("jk Attribute set " + n + "=" + v);
}
// 1 string attributes
switch(attributeCode) {
case AjpConstants.SC_A_CONTEXT :
msg.getBytes( tmpMB );
// nothing
break;
case AjpConstants.SC_A_SERVLET_PATH :
msg.getBytes( tmpMB );
// nothing
break;
case AjpConstants.SC_A_REMOTE_USER :
if( tomcatAuthentication ) {
// ignore server
msg.getBytes( tmpMB );
} else {
msg.getBytes(req.getRemoteUser());
}
break;
case AjpConstants.SC_A_AUTH_TYPE :
if( tomcatAuthentication ) {
// ignore server
msg.getBytes( tmpMB );
} else {
msg.getBytes(req.getAuthType());
}
break;
case AjpConstants.SC_A_QUERY_STRING :
msg.getBytes(req.queryString());
break;
case AjpConstants.SC_A_JVM_ROUTE :
msg.getBytes(req.instanceId());
break;
case AjpConstants.SC_A_SSL_CERT :
req.scheme().setString( "https" );
// Transform the string into certificate.
MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
if(tmpMB2 == null) {
tmpMB2 = MessageBytes.newInstance();
req.setNote(WorkerEnv.SSL_CERT_NOTE, tmpMB2);
}
// SSL certificate extraction is costy, moved to JkCoyoteHandler
msg.getBytes(tmpMB2);
break;
case AjpConstants.SC_A_SSL_CIPHER :
req.scheme().setString( "https" );
msg.getBytes(tmpMB);
req.setAttribute(SSLSupport.CIPHER_SUITE_KEY,
tmpMB.toString());
break;
case AjpConstants.SC_A_SSL_SESSION :
req.scheme().setString( "https" );
msg.getBytes(tmpMB);
req.setAttribute(SSLSupport.SESSION_ID_KEY,
tmpMB.toString());
break;
case AjpConstants.SC_A_SECRET :
msg.getBytes(tmpMB);
String secret=tmpMB.toString();
if(log.isTraceEnabled())
log.trace("Secret: " + secret );
// endpoint note
ep.setNote( secretNote, secret );
break;
case AjpConstants.SC_A_STORED_METHOD:
msg.getBytes(req.method());
break;
default:
break; // ignore, we don't know about it - backward compat
}
}
return 200;
}
private void decodeHeaders( MsgContext ep, Msg msg, Request req,
MessageBytes tmpMB ) {
// Decode headers
MimeHeaders headers = req.getMimeHeaders();
int hCount = msg.getInt();
for(int i = 0 ; i < hCount ; i++) {
String hName = null;
// Header names are encoded as either an integer code starting
// with 0xA0, or as a normal string (in which case the first
// two bytes are the length).
int isc = msg.peekInt();
int hId = isc & 0xFF;
MessageBytes vMB=null;
isc &= 0xFF00;
if(0xA000 == isc) {
msg.getInt(); // To advance the read position
hName = AjpConstants.headerTransArray[hId - 1];
vMB=headers.addValue( hName );
} else {
// reset hId -- if the header currently being read
// happens to be 7 or 8 bytes long, the code below
// will think it's the content-type header or the
// content-length header - SC_REQ_CONTENT_TYPE=7,
// SC_REQ_CONTENT_LENGTH=8 - leading to unexpected
// behaviour. see bug 5861 for more information.
hId = -1;
msg.getBytes( tmpMB );
ByteChunk bc=tmpMB.getByteChunk();
vMB=headers.addValue( bc.getBuffer(),
bc.getStart(), bc.getLength() );
}
msg.getBytes(vMB);
if (hId == AjpConstants.SC_REQ_CONTENT_LENGTH ||
(hId == -1 && tmpMB.equalsIgnoreCase("Content-Length"))) {
// just read the content-length header, so set it
req.setContentLength( vMB.getInt() );
} else if (hId == AjpConstants.SC_REQ_CONTENT_TYPE ||
(hId == -1 && tmpMB.equalsIgnoreCase("Content-Type"))) {
// just read the content-type header, so set it
ByteChunk bchunk = vMB.getByteChunk();
req.contentType().setBytes(bchunk.getBytes(),
bchunk.getOffset(),
bchunk.getLength());
}
}
}
/**
* Parse host.
*/
private void parseHost(MessageBytes valueMB, Request request)
throws IOException {
if (valueMB == null || valueMB.isNull()) {
// HTTP/1.0
// Default is what the socket tells us. Overriden if a host is
// found/parsed
request.setServerPort(request.getLocalPort());
request.serverName().duplicate(request.localName());
return;
}
ByteChunk valueBC = valueMB.getByteChunk();
byte[] valueB = valueBC.getBytes();
int valueL = valueBC.getLength();
int valueS = valueBC.getStart();
int colonPos = -1;
CharChunk hostNameC = (CharChunk)request.getNote(HOSTBUFFER);
if(hostNameC == null) {
hostNameC = new CharChunk(valueL);
request.setNote(HOSTBUFFER, hostNameC);
}
hostNameC.recycle();
boolean ipv6 = (valueB[valueS] == '[');
boolean bracketClosed = false;
for (int i = 0; i < valueL; i++) {
char b = (char) valueB[i + valueS];
hostNameC.append(b);
if (b == ']') {
bracketClosed = true;
} else if (b == ':') {
if (!ipv6 || bracketClosed) {
colonPos = i;
break;
}
}
}
if (colonPos < 0) {
if (request.scheme().equalsIgnoreCase("https")) {
// 80 - Default HTTTP port
request.setServerPort(443);
} else {
// 443 - Default HTTPS port
request.setServerPort(80);
}
request.serverName().setChars(hostNameC.getChars(),
hostNameC.getStart(),
hostNameC.getLength());
} else {
request.serverName().setChars(hostNameC.getChars(),
hostNameC.getStart(), colonPos);
int port = 0;
int mult = 1;
for (int i = valueL - 1; i > colonPos; i--) {
int charValue = HexUtils.DEC[(int) valueB[i + valueS]];
if (charValue == -1) {
// Invalid character
throw new CharConversionException("Invalid char in port: " + valueB[i + valueS]);
}
port = port + (charValue * mult);
mult = 10 * mult;
}
request.setServerPort(port);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -