📄 httpadapter.java
字号:
if( request.getContext() != null) {
headAppend( "Servlet-Engine: ");
headAppend( request.getContext().getEngineHeader());
}
int count=headers.size();
for( int i=0; i<count; i++ ) {
MimeHeaderField field=headers.getField( i );
// response headers are set by the servlet, so probably we have only
// Strings.
// XXX date, cookies, etc shoud be extracted from response
headAppend( field.getName() );
headAppend(": ");
headAppend( field.getValue() );
headAppend("\r\n");
}
headAppend( "\r\n" );
sout.write( headBuffer, 0, bufferCount );
sout.flush();
}
// From BufferedServletOutputStream
// XXX will be moved in a new in/out system, temp. code
// Right now it's not worse than BOS
protected void headAppend( String s ) {
if (s==null) s="null";
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt (i);
//
// XXX NOTE: This is clearly incorrect for many strings,
// but is the only consistent approach within the current
// servlet framework. It must suffice until servlet output
// streams properly encode their output.
//
if ((c & 0xff00) != 0) { // high order byte must be zero
// XXX will go away after we change the I/O system
System.out.println("Header character is not iso8859_1, not supported yet: " + c ) ;
}
if( bufferCount >= headBuffer.length ) {
byte bufferNew[]=new byte[ headBuffer.length * 2 ];
System.arraycopy( headBuffer,0, bufferNew, 0, headBuffer.length );
headBuffer=bufferNew;
}
headBuffer[bufferCount] = (byte)c;
bufferCount++;
}
}
// -------------------- Request Methods --------------------
private void readNextRequest(Request req, Response response) throws IOException {
// Read the full buffer - this should mean the full request
// and maybe part of the body or next request
count = BuffTool.readLine(in, buf, 0, buf.length);
if (count < 0 ) {
// System.out.println("No request");
// System.out.println("Request too long ");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
int status=processRequestLine(req);
if( status != 0 ) {
response.setStatus( status );
return;
}
// for 0.9, we don't have headers!
if (req.getProtocol() !=null) { // all HTTP versions with protocol also have headers ( 0.9 has no HTTP/0.9 !)
status=readHeaders( req );
if( status!= 0 ) {
response.setStatus( status );
return;
}
}
//req.setServerPort( socket.getLocalPort() );
//req.setLocalHost( socket.getLocalAddress().getHostName() );
// req.setRemoteAddr( socket.getInetAddress().getHostAddress());
// req.setRemoteHost( socket.getInetAddress().getHostName());
}
/**
* Reads header fields from the specified servlet input stream until
* a blank line is encountered.
* @param in the servlet input stream
* @exception IllegalArgumentException if the header format was invalid
* @exception IOException if an I/O error has occurred
*/
public int readHeaders( Request req ) throws IOException {
MimeHeaders headers = req.getMimeHeaders();
// use pre-allocated buffer if possible
off = count; // where the request line ended
while (true) {
int start = off;
while (true) {
int len = buf.length - off;
if (len > 0) {
len = BuffTool.readLine(in, buf, off, len);
if (len == -1) {
return HttpServletResponse.SC_BAD_REQUEST;
}
}
off += len;
if (len == 0 || buf[off-1] == '\n') {
break;
}
// overflowed buffer, so temporarily expand and continue
byte[] tmp = new byte[buf.length * 2];
System.arraycopy(buf, 0, tmp, 0, buf.length);
buf = tmp;
}
// strip off trailing "\r\n"
if (--off > start && buf[off-1] == '\r') {
--off;
}
if (off == start) {
break;
}
// XXX this does not currently handle headers which
// are folded to take more than one line.
MimeHeaderField mhf=headers.putHeader();
int status= parseHeaderFiled(mhf, buf, start, off - start);
if( status != 0 ) {
// error parsing header
return status;
}
}
return 0;
}
/**
* Parses a header field from a subarray of bytes.
* @param b the bytes to parse
* @param off the start offset of the bytes
* @param len the length of the bytes
* @exception IllegalArgumentException if the header format was invalid
*/
public int parseHeaderFiled(MimeHeaderField mhf, byte[] b, int off, int len)
{
int start = off;
byte c;
int end=off+len;
int nameEnd= BuffTool.findChars( b, start, end, NAME_DELIMS );
if( nameEnd < 0 || b[nameEnd]=='\r' || b[nameEnd]=='\n' ) {
System.out.println("Parse error, empty line: " + new String( b, off, len ));
return HttpServletResponse.SC_BAD_REQUEST;
}
mhf.setName(b, start, nameEnd - start);
// skip spaces. We should find ":" after the spaces
int sepIdx= BuffTool.findNotChars( b, nameEnd, end, SPACE_DELIMS );
if (b[sepIdx] != ':') {
System.out.println("Parse error, missing : in " + new String( b, off, len ));
System.out.println("Full " + new String( b, 0, b.length ));
return HttpServletResponse.SC_BAD_REQUEST;
}
// skip spaces
int valueStart= BuffTool.findNotChars( b, sepIdx + 1, end, SPACE_DELIMS);
if( valueStart < 0 ) {
System.out.println("Parse error, no value after : " + new String( b, off, len ));
System.out.println("Full " + new String( b, 0, b.length ));
return HttpServletResponse.SC_BAD_REQUEST;
}
mhf.setValue(b, valueStart, end - valueStart );
return 0;
}
static final byte NAME_DELIMS[]={ (byte)':', (byte)' ', (byte)'\t', (byte)'\r', (byte)'\n' };
static final byte SPACE_DELIMS[]={ (byte)' ', (byte)'\t'};
/** Parse the request line and set the fields of req
*/
private int processRequestLine(Request req)
throws IOException
{
off=0;
// if end of line is reached before we scan all 3 components -
// we're fine, off=count and remain unchanged
if( buf[count-1]!= '\r' && buf[count-1]!= '\n' ) {
return HttpServletResponse.SC_REQUEST_URI_TOO_LONG;
}
int startMethod = BuffTool.findNotChars( buf, 0, count, SPACE_DELIMS);
if( startMethod == -1 ) return HttpServletResponse.SC_BAD_REQUEST;
int endMethod = BuffTool.findChars( buf, startMethod, count, SPACE_DELIMS );
if( endMethod == -1 ) return HttpServletResponse.SC_BAD_REQUEST;
req.setMethod( new String( buf, startMethod, endMethod - startMethod ));
int startReq= BuffTool.findNotChars( buf, endMethod, count, SPACE_DELIMS);
if( startReq == -1 ) return HttpServletResponse.SC_BAD_REQUEST;
int endReq= BuffTool.findChars( buf, startReq, count, SPACE_DELIMS);
if( endReq != -1 ) {
// we have a space after query string, we might have protocol
int startProto= BuffTool.findNotChars(buf, endReq, count, SPACE_DELIMS);
if( startProto != -1 ) {
// yes, we do have protocol
int endProto=BuffTool.findChars( buf, startProto, count, SPACE_DELIMS);
// no ' ' found after end, that's ok
if( endProto == -1 ) endProto = count;
req.setProtocol( new String( buf, startProto, endProto-startProto ));
} else {
req.setProtocol(null);
}
} else {
// no protocol
req.setProtocol(null);
endReq=count;
}
int qryIdx= BuffTool.findChar( buf, startReq, endReq, '?' );
if( qryIdx <0 ) {
req.setRequestURI( new String( buf, startReq, endReq - startReq ));
} else {
req.setRequestURI( new String( buf, startReq, qryIdx - startReq ));
req.setQueryString( new String( buf, qryIdx+1, endReq - qryIdx -1 ));
}
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -