public boolean handleNext()
{
AJP13RequestPacket packet=null;
HttpRequest request=getRequest();
HttpResponse response=getResponse();
HttpContext context=null;
boolean gotRequest=false;
_persistent=true;
_keepAlive=true;
try
{
try
{
packet=null;
packet=_ajpIn.nextPacket();
if (packet==null)
return false;
if (packet.getDataSize()==0)
return true;
}
catch (IOException e)
{
LogSupport.ignore(log,e);
return false;
}
int type=packet.getByte();
if (log.isDebugEnabled())
log.debug("AJP13 type="+type+" size="+packet.unconsumedData());
switch (type)
{
case AJP13Packet.__FORWARD_REQUEST:
request.setTimeStamp(System.currentTimeMillis());
request.setState(HttpMessage.__MSG_EDITABLE);
request.setMethod(packet.getMethod());
request.setVersion(packet.getString());
String version=packet.getString();
try
{
request.setVersion(version);
}
catch(Exception e)
{
log.warn("Bad version"+version,e);
log.warn(packet.toString());
}
String path=packet.getString();
int sc=path.lastIndexOf(";");
if (sc<0)
request.setPath(URI.encodePath(path));
else
request.setPath(URI.encodePath(path.substring(0,sc))+path.substring(sc));
_remoteAddr=packet.getString();
_remoteHost=packet.getString();
_serverName=packet.getString();
_serverPort=packet.getInt();
_isSSL=packet.getBoolean();
// Check keep alive
_keepAlive=request.getDotVersion()>=1;
// Headers
int h=packet.getInt();
for (int i=0; i<h; i++)
{
String hdr=packet.getHeader();
String val=packet.getString();
request.addField(hdr,val);
if (!_keepAlive&&hdr.equalsIgnoreCase(HttpFields.__Connection)&&val.equalsIgnoreCase(HttpFields.__KeepAlive))
_keepAlive=true;
}
// Handler other attributes
byte attr=packet.getByte();
while ((0xFF&attr)!=0xFF)
{
String value=(attr==11)?null:packet.getString();
switch (attr)
{
case 11: // key size
request.setAttribute("javax.servlet.request.key_size",new Integer(packet.getInt()));
break;
case 10: // request attribute
request.setAttribute(value,packet.getString());
break;
case 9: // SSL session
request.setAttribute("javax.servlet.request.ssl_session",value);
break;
case 8: // SSL cipher
request.setAttribute("javax.servlet.request.cipher_suite",value);
break;
case 7: // SSL cert
// request.setAttribute("javax.servlet.request.X509Certificate",value);
CertificateFactory cf=CertificateFactory.getInstance("X.509");
InputStream certstream=new ByteArrayInputStream(value.getBytes());
X509Certificate cert=(X509Certificate)cf.generateCertificate(certstream);
X509Certificate certs[]=
{ cert };
request.setAttribute("javax.servlet.request.X509Certificate",certs);
break;
case 6: // JVM Route
request.setAttribute("org.openqa.jetty.http.ajp.JVMRoute",value);
break;
case 5: // Query String
request.setQuery(value);
break;
case 4: // AuthType
request.setAuthType(value);
break;
case 3: // Remote User
request.setAuthUser(value);
break;
case 2: // servlet path not implemented
case 1: // _context not implemented
default:
log.warn("Unknown attr: "+attr+"="+value);
}
attr=packet.getByte();
}
_listener.customizeRequest(this,request);
gotRequest=true;
statsRequestStart();
request.setState(HttpMessage.__MSG_RECEIVED);
// Complete response
if (request.getContentLength()==0&&request.getField(HttpFields.__TransferEncoding)==null)
_ajpIn.close();
// Prepare response
response.setState(HttpMessage.__MSG_EDITABLE);
response.setVersion(HttpMessage.__HTTP_1_1);
response.setDateField(HttpFields.__Date,_request.getTimeStamp());
if (!Version.isParanoid())
response.setField(HttpFields.__Server,Version.getDetail());
// Service request
if (log.isDebugEnabled())
log.debug("REQUEST:\n"+request);
context=service(request,response);
if (log.isDebugEnabled())
log.debug("RESPONSE:\n"+response);
break;
default:
if (log.isDebugEnabled())
log.debug("Ignored: "+packet);
_persistent=false;
}
}
catch (SocketException e)
{
LogSupport.ignore(log,e);
_persistent=false;
}
catch (Exception e)
{
log.warn(LogSupport.EXCEPTION,e);
_persistent=false;
try
{
if (gotRequest)
_ajpOut.close();
}
catch (IOException e2)
{
LogSupport.ignore(log,e2);
}
}
finally
{
// abort if nothing received.
if (packet==null||!gotRequest)
return false;
// flush and end the output
try
{
// Consume unread input.
// while(_ajpIn.skip(4096)>0 || _ajpIn.read()>=0);
// end response
getOutputStream().close();
if (!_persistent)
_ajpOut.end();
// Close the outout
_ajpOut.close();
// reset streams
getOutputStream().resetStream();
getOutputStream().addObserver(this);
getInputStream().resetStream();
_ajpIn.resetStream();
_ajpOut.resetStream();
}
catch (Exception e)
{
log.debug(LogSupport.EXCEPTION,e);
_persistent=false;
}
finally
{
statsRequestEnd();
if (context!=null)
context.log(request,response,-1);
}
}
return _persistent;
}