📄 requesthandler.java
字号:
case SC_A_SSL_KEY_SIZE: // Ajp13 ! isSSL = true; req.setAttribute("javax.servlet.request.key_size", Integer.toString(msg.getInt())); break; default: // Ignore. Assume a single-string value - we shouldn't // allow anything else. msg.getString(); break; } } if(isSSL) { req.setScheme(req.SCHEME_HTTPS); req.setSecure(true); } // set cookies on request now that we have all headers req.cookies().setHeaders(req.headers()); // Check to see if there should be a body packet coming along // immediately after if(req.getContentLength() > 0) { /* Read present data */ int err = ch.receive(ch.inBuf); if(err < 0) { return 500; } ch.blen = ch.inBuf.peekInt(); ch.pos = 0; ch.inBuf.getBytes(ch.bodyBuff); } if (debug > 5) { log(req.toString()); } return 200; // Success } // -------------------- Messages from container to server ------------------ /** * Send the HTTP headers back to the web server and on to the browser. * * @param status The HTTP status code to send. * @param statusMessage the HTTP status message to send. * @param headers The set of all headers. */ public void sendHeaders(Ajp13 ch, Ajp13Packet outBuf, int status, String statusMessage, MimeHeaders headers) throws IOException { // XXX if more headers that MAX_SIZE, send 2 packets! if( statusMessage==null ) statusMessage=HttpMessages.getMessage(status); outBuf.reset(); outBuf.appendByte(JK_AJP13_SEND_HEADERS); outBuf.appendInt(status); outBuf.appendString(statusMessage); int numHeaders = headers.size(); outBuf.appendInt(numHeaders); for( int i=0 ; i < numHeaders ; i++ ) { String headerName = headers.getName(i).toString(); int sc = headerNameToSc(headerName); if(-1 != sc) { outBuf.appendInt(sc); } else { outBuf.appendString(headerName); } outBuf.appendString(headers.getValue(i).toString() ); } outBuf.end(); ch.send(outBuf); } /** * Signal the web server that the servlet has finished handling this * request, and that the connection can be reused. */ public void finish(Ajp13 ch, Ajp13Packet outBuf) throws IOException { if (debug > 0) log("finish()"); outBuf.reset(); outBuf.appendByte(JK_AJP13_END_RESPONSE); outBuf.appendBool(true); // Reuse this connection outBuf.end(); ch.send(outBuf); } /** * Send a chunk of response body data to the web server and on to the * browser. * * @param b A huffer of bytes to send. * @param off The offset into the buffer from which to start sending. * @param len The number of bytes to send. */ public void doWrite(Ajp13 ch, Ajp13Packet outBuf, byte b[], int off, int len) throws IOException { if (debug > 0) log("doWrite(byte[], " + off + ", " + len + ")"); int sent = 0; while(sent < len) { int to_send = len - sent; to_send = to_send > Ajp13.MAX_SEND_SIZE ? Ajp13.MAX_SEND_SIZE : to_send; outBuf.reset(); outBuf.appendByte(JK_AJP13_SEND_BODY_CHUNK); outBuf.appendBytes(b, off + sent, to_send); ch.send(outBuf); sent += to_send; } } // -------------------- Utils -------------------- /** * Translate an HTTP response header name to an integer code if * possible. Case is ignored. * * @param name The name of the response header to translate. * * @return The code for that header name, or -1 if no code exists. */ protected int headerNameToSc(String name) { switch(name.charAt(0)) { case 'c': case 'C': if(name.equalsIgnoreCase("Content-Type")) { return SC_RESP_CONTENT_TYPE; } else if(name.equalsIgnoreCase("Content-Language")) { return SC_RESP_CONTENT_LANGUAGE; } else if(name.equalsIgnoreCase("Content-Length")) { return SC_RESP_CONTENT_LENGTH; } break; case 'd': case 'D': if(name.equalsIgnoreCase("Date")) { return SC_RESP_DATE; } break; case 'l': case 'L': if(name.equalsIgnoreCase("Last-Modified")) { return SC_RESP_LAST_MODIFIED; } else if(name.equalsIgnoreCase("Location")) { return SC_RESP_LOCATION; } break; case 's': case 'S': if(name.equalsIgnoreCase("Set-Cookie")) { return SC_RESP_SET_COOKIE; } else if(name.equalsIgnoreCase("Set-Cookie2")) { return SC_RESP_SET_COOKIE2; } break; case 'w': case 'W': if(name.equalsIgnoreCase("WWW-Authenticate")) { return SC_RESP_WWW_AUTHENTICATE; } break; } return -1; } private int debug=0; private Logger logger = new Logger(); public void setDebug(int debug) { this.debug = debug; } public void setLogger(Logger l) { this.logger = l; } void log(String s) { logger.log("[RequestHandler] " + s ); } // ==================== Servlet Input Support ================= // XXX DEPRECATED public int available(Ajp13 ch) throws IOException { if (debug > 0) { log("available()"); } if (ch.pos >= ch.blen) { if( ! refillReadBuffer(ch)) { return 0; } } return ch.blen - ch.pos; } /** * Return the next byte of request body data (to a servlet). * * @see Request#doRead */ public int doRead(Ajp13 ch) throws IOException { if (debug > 0) { log("doRead()"); } if(ch.pos >= ch.blen) { if( ! refillReadBuffer(ch)) { return -1; } } return ch.bodyBuff[ch.pos++] & 0xFF; } /** * Store a chunk of request data into the passed-in byte buffer. * * @param b A buffer to fill with data from the request. * @param off The offset in the buffer at which to start filling. * @param len The number of bytes to copy into the buffer. * * @return The number of bytes actually copied into the buffer, or -1 * if the end of the stream has been reached. * * @see Request#doRead */ public int doRead(Ajp13 ch, byte[] b, int off, int len) throws IOException { if (debug > 0) { log("doRead(byte[], int, int)"); } if(ch.pos >= ch.blen) { if( ! refillReadBuffer(ch)) { return -1; } } if(ch.pos + len <= ch.blen) { // Fear the off by one error // Sanity check b.length > off + len? System.arraycopy(ch.bodyBuff, ch.pos, b, off, len); ch.pos += len; return len; } // Not enough data (blen < pos + len) int toCopy = len; while(toCopy > 0) { int bytesRemaining = ch.blen - ch.pos; if(bytesRemaining < 0) bytesRemaining = 0; int c = bytesRemaining < toCopy ? bytesRemaining : toCopy; System.arraycopy(ch.bodyBuff, ch.pos, b, off, c); toCopy -= c; off += c; ch.pos += c; // In case we exactly consume the buffer if(toCopy > 0) if( ! refillReadBuffer(ch)) { // Resets blen and pos break; } } return len - toCopy; } /** * Get more request body data from the web server and store it in the * internal buffer. * * @return true if there is more data, false if not. */ public boolean refillReadBuffer(Ajp13 ch) throws IOException { if (debug > 0) { log("refillReadBuffer()"); } // If the server returns an empty packet, assume that that end of // the stream has been reached (yuck -- fix protocol??). // Why not use outBuf?? ch.inBuf.reset(); ch.inBuf.appendByte(JK_AJP13_GET_BODY_CHUNK); ch.inBuf.appendInt(Ajp13.MAX_READ_SIZE); ch.send(ch.inBuf); int err = ch.receive(ch.inBuf); if(err < 0) { throw new IOException(); } // check for empty packet, which means end of stream if (ch.inBuf.getLen() == 0) { if (debug > 0) { log("refillReadBuffer(): " + "received empty packet -> end of stream"); } ch.blen = 0; ch.pos = 0; return false; } ch.blen = ch.inBuf.peekInt(); ch.pos = 0; ch.inBuf.getBytes(ch.bodyBuff); return (ch.blen > 0); } // ==================== Servlet Output Support ================= /** */ public void beginSendHeaders(Ajp13 ch, Ajp13Packet outBuf, int status, String statusMessage, int numHeaders) throws IOException { if (debug > 0) { log("sendHeaders()"); } // XXX if more headers that MAX_SIZE, send 2 packets! outBuf.reset(); outBuf.appendByte(JK_AJP13_SEND_HEADERS); if (debug > 0) { log("status is: " + status + "(" + statusMessage + ")"); } // set status code and message outBuf.appendInt(status); outBuf.appendString(statusMessage); // write the number of headers... outBuf.appendInt(numHeaders); } public void sendHeader(Ajp13Packet outBuf, String name, String value) throws IOException { int sc = headerNameToSc(name); if(-1 != sc) { outBuf.appendInt(sc); } else { outBuf.appendString(name); } outBuf.appendString(value); } public void endSendHeaders(Ajp13 ch, Ajp13Packet outBuf) throws IOException { outBuf.end(); ch.send(outBuf); } /** * Send the HTTP headers back to the web server and on to the browser. * * @param status The HTTP status code to send. * @param headers The set of all headers. */ public void sendHeaders(Ajp13 ch, Ajp13Packet outBuf, int status, MimeHeaders headers) throws IOException { sendHeaders(ch, outBuf, status, HttpMessages.getMessage(status), headers); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -