📄 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 + -