/* ------------------------------------------------------------ */ @Override public void push() { if (HttpMethod.POST.is(_method) || HttpMethod.PUT.is(_method)) throw new IllegalStateException("Bad Method " + _method); if (_path == null || _path.length() == 0) throw new IllegalStateException("Bad Path " + _path); String path = _path; String query = _queryString; int q = path.indexOf('?'); if (q >= 0) { query = (query != null && query.length() > 0) ? (_path.substring(q + 1) + '&' + query) : _path.substring(q + 1); path = _path.substring(0, q); } if (!path.startsWith("/")) path = URIUtil.addPaths(_request.getContextPath(), path); String param = null; if (_sessionId != null) { if (_request.isRequestedSessionIdFromURL()) param = "jsessionid=" + _sessionId; // TODO else // _fields.add("Cookie","JSESSIONID="+_sessionId); } if (_conditional) { if (_etag != null) _fields.add(HttpHeader.IF_NONE_MATCH, _etag); else if (_lastModified != null) _fields.add(HttpHeader.IF_MODIFIED_SINCE, _lastModified); } HttpURI uri = HttpURI.createHttpURI( _request.getScheme(), _request.getServerName(), _request.getServerPort(), _path, param, query, null); MetaData.Request push = new MetaData.Request(_method, uri, _request.getHttpVersion(), _fields); if (LOG.isDebugEnabled()) LOG.debug( "Push {} {} inm={} ims={}", _method, uri, _fields.get(HttpHeader.IF_NONE_MATCH), _fields.get(HttpHeader.IF_MODIFIED_SINCE)); _request.getHttpChannel().getHttpTransport().push(push); _path = null; _etag = null; _lastModified = null; }
private boolean doIsEncodeable(Request hreq, Session session, String location) { // Is this a valid absolute URL? URL url = null; try { url = new URL(location); } catch (MalformedURLException e) { return (false); } // Does this URL match down to (and including) the context path? if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol())) { return (false); } if (!hreq.getServerName().equalsIgnoreCase(url.getHost())) { return (false); } int serverPort = hreq.getServerPort(); if (serverPort == -1) { if ("https".equals(hreq.getScheme())) { serverPort = 443; } else { serverPort = 80; } } int urlPort = url.getPort(); if (urlPort == -1) { if ("https".equals(url.getProtocol())) { urlPort = 443; } else { urlPort = 80; } } if (serverPort != urlPort) { return (false); } String contextPath = getContext().getPath(); if (contextPath != null) { String file = url.getFile(); if ((file == null) || !file.startsWith(contextPath)) { return (false); } String tok = ";" + SessionConfig.getSessionUriParamName(request.getContext()) + "=" + session.getIdInternal(); if (file.indexOf(tok, contextPath.length()) >= 0) { return (false); } } // This URL belongs to our web application, so it is encodeable return (true); }
/* ------------------------------------------------------------ */ protected void checkForwardedHeaders(EndPoint endpoint, Request request) throws IOException { HttpFields httpFields = request.getConnection().getRequestFields(); // Retrieving headers from the request String forwardedHost = getLeftMostValue(httpFields.getStringField(getForwardedHostHeader())); String forwardedServer = getLeftMostValue(httpFields.getStringField(getForwardedServerHeader())); String forwardedFor = getLeftMostValue(httpFields.getStringField(getForwardedForHeader())); if (_hostHeader != null) { // Update host header httpFields.put(HttpHeaders.HOST_BUFFER, _hostHeader); request.setServerName(null); request.setServerPort(-1); request.getServerName(); } else if (forwardedHost != null) { // Update host header httpFields.put(HttpHeaders.HOST_BUFFER, forwardedHost); request.setServerName(null); request.setServerPort(-1); request.getServerName(); } else if (forwardedServer != null) { // Use provided server name request.setServerName(forwardedServer); } if (forwardedFor != null) { request.setRemoteAddr(forwardedFor); InetAddress inetAddress = null; if (_useDNS) { try { inetAddress = InetAddress.getByName(forwardedFor); } catch (UnknownHostException e) { Log.ignore(e); } } request.setRemoteHost(inetAddress == null ? forwardedFor : inetAddress.getHostName()); } }
/** * Customizes the request attributes to be set for SSL requests. * * <p>The requirements of the Servlet specs are: * * <ul> * <li>an attribute named "javax.servlet.request.ssl_session_id" of type String (since Servlet * Spec 3.0). * <li>an attribute named "javax.servlet.request.cipher_suite" of type String. * <li>an attribute named "javax.servlet.request.key_size" of type Integer. * <li>an attribute named "javax.servlet.request.X509Certificate" of type * java.security.cert.X509Certificate[]. This is an array of objects of type * X509Certificate, the order of this array is defined as being in ascending order of trust. * The first certificate in the chain is the one set by the client, the next is the one used * to authenticate the first, and so on. * </ul> * * @param sslEngine the sslEngine to be customized. * @param request HttpRequest to be customized. */ protected void customize(SSLEngine sslEngine, Request request) { SSLSession sslSession = sslEngine.getSession(); if (_sniHostCheck) { String name = request.getServerName(); X509 x509 = (X509) sslSession.getValue(SniX509ExtendedKeyManager.SNI_X509); if (x509 != null && !x509.matches(name)) { LOG.warn("Host {} does not match SNI {}", name, x509); throw new BadMessageException(400, "Host does not match SNI"); } if (LOG.isDebugEnabled()) LOG.debug("Host {} matched SNI {}", name, x509); } try { String cipherSuite = sslSession.getCipherSuite(); Integer keySize; X509Certificate[] certs; String idStr; CachedInfo cachedInfo = (CachedInfo) sslSession.getValue(CACHED_INFO_ATTR); if (cachedInfo != null) { keySize = cachedInfo.getKeySize(); certs = cachedInfo.getCerts(); idStr = cachedInfo.getIdStr(); } else { keySize = SslContextFactory.deduceKeyLength(cipherSuite); certs = SslContextFactory.getCertChain(sslSession); byte[] bytes = sslSession.getId(); idStr = TypeUtil.toHexString(bytes); cachedInfo = new CachedInfo(keySize, certs, idStr); sslSession.putValue(CACHED_INFO_ATTR, cachedInfo); } if (certs != null) request.setAttribute("javax.servlet.request.X509Certificate", certs); request.setAttribute("javax.servlet.request.cipher_suite", cipherSuite); request.setAttribute("javax.servlet.request.key_size", keySize); request.setAttribute("javax.servlet.request.ssl_session_id", idStr); } catch (Exception e) { LOG.warn(Log.EXCEPTION, e); } }
/** * Convert (if necessary) and return the absolute URL that represents the resource referenced by * this possibly relative URL. If this URL is already absolute, return it unchanged. * * @param location URL to be (possibly) converted and then returned * @exception IllegalArgumentException if a MalformedURLException is thrown when converting the * relative URL to an absolute one */ protected String toAbsolute(String location) { if (location == null) { return (location); } boolean leadingSlash = location.startsWith("/"); if (location.startsWith("//")) { // Scheme relative redirectURLCC.recycle(); // Add the scheme String scheme = request.getScheme(); try { redirectURLCC.append(scheme, 0, scheme.length()); redirectURLCC.append(':'); redirectURLCC.append(location, 0, location.length()); return redirectURLCC.toString(); } catch (IOException e) { IllegalArgumentException iae = new IllegalArgumentException(location); iae.initCause(e); throw iae; } } else if (leadingSlash || !hasScheme(location)) { redirectURLCC.recycle(); String scheme = request.getScheme(); String name = request.getServerName(); int port = request.getServerPort(); try { redirectURLCC.append(scheme, 0, scheme.length()); redirectURLCC.append("://", 0, 3); redirectURLCC.append(name, 0, name.length()); if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) { redirectURLCC.append(':'); String portS = port + ""; redirectURLCC.append(portS, 0, portS.length()); } if (!leadingSlash) { String relativePath = request.getDecodedRequestURI(); int pos = relativePath.lastIndexOf('/'); CharChunk encodedURI = null; final String frelativePath = relativePath; final int fend = pos; if (SecurityUtil.isPackageProtectionEnabled()) { try { encodedURI = AccessController.doPrivileged( new PrivilegedExceptionAction<CharChunk>() { @Override public CharChunk run() throws IOException { return urlEncoder.encodeURL(frelativePath, 0, fend); } }); } catch (PrivilegedActionException pae) { IllegalArgumentException iae = new IllegalArgumentException(location); iae.initCause(pae.getException()); throw iae; } } else { encodedURI = urlEncoder.encodeURL(relativePath, 0, pos); } redirectURLCC.append(encodedURI); encodedURI.recycle(); redirectURLCC.append('/'); } redirectURLCC.append(location, 0, location.length()); normalize(redirectURLCC); } catch (IOException e) { IllegalArgumentException iae = new IllegalArgumentException(location); iae.initCause(e); throw iae; } return redirectURLCC.toString(); } else { return (location); } }
@Override public String encodeURL(String url) { final Request request = _channel.getRequest(); SessionManager sessionManager = request.getSessionManager(); if (sessionManager == null) return url; HttpURI uri = null; if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) { uri = new HttpURI(url); String path = uri.getPath(); path = (path == null ? "" : path); int port = uri.getPort(); if (port < 0) port = HttpScheme.HTTPS.asString().equalsIgnoreCase(uri.getScheme()) ? 443 : 80; if (!request.getServerName().equalsIgnoreCase(uri.getHost()) || request.getServerPort() != port || !path.startsWith( request .getContextPath())) // TODO the root context path is "", with which every non null // string starts return url; } String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix(); if (sessionURLPrefix == null) return url; if (url == null) return null; // should not encode if cookies in evidence if (request.isRequestedSessionIdFromCookie()) { int prefix = url.indexOf(sessionURLPrefix); if (prefix != -1) { int suffix = url.indexOf("?", prefix); if (suffix < 0) suffix = url.indexOf("#", prefix); if (suffix <= prefix) return url.substring(0, prefix); return url.substring(0, prefix) + url.substring(suffix); } return url; } // get session; HttpSession session = request.getSession(false); // no session if (session == null) return url; // invalid session if (!sessionManager.isValid(session)) return url; String id = sessionManager.getNodeId(session); if (uri == null) uri = new HttpURI(url); // Already encoded int prefix = url.indexOf(sessionURLPrefix); if (prefix != -1) { int suffix = url.indexOf("?", prefix); if (suffix < 0) suffix = url.indexOf("#", prefix); if (suffix <= prefix) return url.substring(0, prefix + sessionURLPrefix.length()) + id; return url.substring(0, prefix + sessionURLPrefix.length()) + id + url.substring(suffix); } // edit the session int suffix = url.indexOf('?'); if (suffix < 0) suffix = url.indexOf('#'); if (suffix < 0) { return url + ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + // if no path, insert the root path sessionURLPrefix + id; } return url.substring(0, suffix) + ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + // if no path so insert the root path sessionURLPrefix + id + url.substring(suffix); }