📄 coyoteadapter.java
字号:
req.decodedURI().duplicate(req.requestURI()); req.getURLDecoder().convert(req.decodedURI(), false); req.decodedURI().setEncoding("UTF-8"); // Normalize decoded URI if (!normalize(req.decodedURI())) { res.setStatus(400); res.setMessage("Invalid URI"); throw new IOException("Invalid URI"); } // Parse session Id parseSessionId(req, request); // Parse cookies parseCookies(req, request); // Set the SSL properties if( request.isSecure() ) { res.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE, request.getCoyoteRequest()); //Set up for getAttributeNames request.getAttribute(Globals.CERTIFICATES_ATTR); request.getAttribute(Globals.CIPHER_SUITE_ATTR); request.getAttribute(Globals.KEY_SIZE_ATTR); } // Set the remote principal String principal = req.getRemoteUser().toString(); if (principal != null) { request.setUserPrincipal(new CoyotePrincipal(principal)); } } /** * Parse session id in URL. * FIXME: Optimize this. */ protected void parseSessionId(Request req, CoyoteRequest request) { ByteChunk uriBC = req.decodedURI().getByteChunk(); int semicolon = uriBC.indexOf(match, 0, match.length(), 0); if (semicolon > 0) { // Parse session ID, and extract it from the decoded request URI String uri = uriBC.toString(); String rest = uri.substring(semicolon + match.length()); int semicolon2 = rest.indexOf(';'); if (semicolon2 >= 0) { request.setRequestedSessionId(rest.substring(0, semicolon2)); rest = rest.substring(semicolon2); } else { request.setRequestedSessionId(rest); rest = ""; } request.setRequestedSessionURL(true); req.decodedURI().setString(uri.substring(0, semicolon) + rest); // Extract session ID from request URI uri = req.requestURI().toString(); semicolon = uri.indexOf(match); if (semicolon > 0) { rest = uri.substring(semicolon + match.length()); semicolon2 = rest.indexOf(';'); if (semicolon2 >= 0) { rest = rest.substring(semicolon2); } else { rest = ""; } req.requestURI().setString(uri.substring(0, semicolon) + rest); } } else { request.setRequestedSessionId(null); request.setRequestedSessionURL(false); } } /** * Parse cookies. */ protected void parseCookies(Request req, CoyoteRequest request) { Cookies serverCookies = req.getCookies(); int count = serverCookies.getCookieCount(); if (count <= 0) return; Cookie[] cookies = new Cookie[count]; for (int i = 0; i < count; i++) { ServerCookie scookie = serverCookies.getCookie(i); if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) { // Override anything requested in the URL if (!request.isRequestedSessionIdFromCookie()) { // Accept only the first session id cookie request.setRequestedSessionId (scookie.getValue().toString()); request.setRequestedSessionCookie(true); request.setRequestedSessionURL(false); if (debug >= 1) log(" Requested cookie session id is " + ((HttpServletRequest) request.getRequest()) .getRequestedSessionId()); } } Cookie cookie = new Cookie(scookie.getName().toString(), scookie.getValue().toString()); cookies[i] = cookie; } request.setCookies(cookies); } /** * Normalize URI. * <p> * This method normalizes "\", "//", "/./" and "/../". This method will * return false when trying to go above the root, or if the URI contains * a null byte. * * @param uriMB URI to be normalized */ public static boolean normalize(MessageBytes uriMB) { ByteChunk uriBC = uriMB.getByteChunk(); byte[] b = uriBC.getBytes(); int start = uriBC.getStart(); int end = uriBC.getEnd(); int pos = 0; int index = 0; // Replace '\' with '/' // Check for null byte for (pos = start; pos < end; pos++) { if (b[pos] == (byte) '\\') b[pos] = (byte) '/'; if (b[pos] == (byte) 0) return false; } // The URL must start with '/' if (b[start] != (byte) '/') { return false; } // Replace "//" with "/" for (pos = start; pos < (end - 1); pos++) { if ((b[pos] == (byte) '/') && (b[pos + 1] == (byte) '/')) { copyBytes(b, pos, pos + 1, end - pos - 1); end--; } } // If the URI ends with "/." or "/..", then we append an extra "/" // Note: It is possible to extend the URI by 1 without any side effect // as the next character is a non-significant WS. if (((end - start) > 2) && (b[end - 1] == (byte) '.')) { if ((b[end - 2] == (byte) '/') || ((b[end - 2] == (byte) '.') && (b[end - 3] == (byte) '/'))) { b[end] = (byte) '/'; end++; } } uriBC.setEnd(end); index = 0; // Resolve occurrences of "/./" in the normalized path while (true) { index = uriBC.indexOf("/./", 0, 3, index); if (index < 0) break; copyBytes(b, start + index, start + index + 2, end - start - index - 2); end = end - 2; uriBC.setEnd(end); } index = 0; // Resolve occurrences of "/../" in the normalized path while (true) { index = uriBC.indexOf("/../", 0, 4, index); if (index < 0) break; // Prevent from going outside our context if (index == 0) return false; int index2 = -1; for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --) { if (b[pos] == (byte) '/') { index2 = pos; } } copyBytes(b, start + index2, start + index + 3, end - start - index - 3); end = end + index2 - index - 3; uriBC.setEnd(end); index = index2; } uriBC.setBytes(b, start, end); return true; } // ------------------------------------------------------ Protected Methods /** * Copy an array of bytes to a different position. Used during * normalization. */ protected static void copyBytes(byte[] b, int dest, int src, int len) { for (int pos = 0; pos < len; pos++) { b[pos + dest] = b[pos + src]; } } /** * Log a message on the Logger associated with our Container (if any) * * @param message Message to be logged */ protected void log(String message) { Logger logger = connector.getContainer().getLogger(); if (logger != null) logger.log("CoyoteAdapter " + message); } /** * Log a message on the Logger associated with our Container (if any) * * @param message Message to be logged * @param throwable Associated exception */ protected void log(String message, Throwable throwable) { Logger logger = connector.getContainer().getLogger(); if (logger != null) logger.log("CoyoteAdapter " + message, throwable); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -