Search in sources :

Example 11 with CookieImpl

use of io.undertow.server.handlers.CookieImpl in project undertow by undertow-io.

the class Cookies method parseCookie.

private static void parseCookie(final String cookie, final Set<Cookie> parsedCookies, int maxCookies, boolean allowEqualInValue, boolean commaIsSeperator, boolean allowHttpSepartorsV0) {
    int state = 0;
    String name = null;
    int start = 0;
    boolean containsEscapedQuotes = false;
    int cookieCount = parsedCookies.size();
    final Map<String, String> cookies = new HashMap<>();
    final Map<String, String> additional = new HashMap<>();
    for (int i = 0; i < cookie.length(); ++i) {
        char c = cookie.charAt(i);
        switch(state) {
            case 0:
                {
                    // eat leading whitespace
                    if (c == ' ' || c == '\t' || c == ';') {
                        start = i + 1;
                        break;
                    }
                    state = 1;
                // fall through
                }
            case 1:
                {
                    // extract key
                    if (c == '=') {
                        name = cookie.substring(start, i);
                        start = i + 1;
                        state = 2;
                    } else if (c == ';' || (commaIsSeperator && c == ',')) {
                        if (name != null) {
                            cookieCount = createCookie(name, cookie.substring(start, i), maxCookies, cookieCount, cookies, additional);
                        } else if (UndertowLogger.REQUEST_LOGGER.isTraceEnabled()) {
                            UndertowLogger.REQUEST_LOGGER.trace("Ignoring invalid cookies in header " + cookie);
                        }
                        state = 0;
                        start = i + 1;
                    }
                    break;
                }
            case 2:
                {
                    // extract value
                    if (c == ';' || (commaIsSeperator && c == ',')) {
                        cookieCount = createCookie(name, cookie.substring(start, i), maxCookies, cookieCount, cookies, additional);
                        state = 0;
                        start = i + 1;
                    } else if (c == '"' && start == i) {
                        // only process the " if it is the first character
                        containsEscapedQuotes = false;
                        state = 3;
                        start = i + 1;
                    } else if (c == '=') {
                        if (!allowEqualInValue && !allowHttpSepartorsV0) {
                            cookieCount = createCookie(name, cookie.substring(start, i), maxCookies, cookieCount, cookies, additional);
                            state = 4;
                            start = i + 1;
                        }
                    } else if (c != ':' && !allowHttpSepartorsV0 && LegacyCookieSupport.isHttpSeparator(c)) {
                        // http separators are not allowed in V0 cookie value unless io.undertow.legacy.cookie.ALLOW_HTTP_SEPARATORS_IN_V0 is set to true.
                        // However, "<hostcontroller-name>:<server-name>" (e.g. master:node1) is added as jvmRoute (instance-id) by default in WildFly domain mode.
                        // Though ":" is http separator, we allow it by default. Because, when Undertow runs as a proxy server (mod_cluster),
                        // we need to handle jvmRoute containing ":" in the request cookie value correctly to maintain the sticky session.
                        cookieCount = createCookie(name, cookie.substring(start, i), maxCookies, cookieCount, cookies, additional);
                        state = 4;
                        start = i + 1;
                    }
                    break;
                }
            case 3:
                {
                    // extract quoted value
                    if (c == '"') {
                        cookieCount = createCookie(name, containsEscapedQuotes ? unescapeDoubleQuotes(cookie.substring(start, i)) : cookie.substring(start, i), maxCookies, cookieCount, cookies, additional);
                        state = 0;
                        start = i + 1;
                    }
                    // Skip the next double quote char '"' when it is escaped by backslash '\' (i.e. \") inside the quoted value
                    if (c == '\\' && (i + 1 < cookie.length()) && cookie.charAt(i + 1) == '"') {
                        // But..., do not skip at the following conditions
                        if (i + 2 == cookie.length()) {
                            // Cookie: key="\" or Cookie: key="...\"
                            break;
                        }
                        if (i + 2 < cookie.length() && (// Cookie: key="\"; key2=...
                        cookie.charAt(i + 2) == ';' || (commaIsSeperator && cookie.charAt(i + 2) == ','))) {
                            // Cookie: key="\", key2=...
                            break;
                        }
                        // Skip the next double quote char ('"' behind '\') in the cookie value
                        i++;
                        containsEscapedQuotes = true;
                    }
                    break;
                }
            case 4:
                {
                    // skip value portion behind '='
                    if (c == ';' || (commaIsSeperator && c == ',')) {
                        state = 0;
                    }
                    start = i + 1;
                    break;
                }
        }
    }
    if (state == 2) {
        createCookie(name, cookie.substring(start), maxCookies, cookieCount, cookies, additional);
    }
    for (final Map.Entry<String, String> entry : cookies.entrySet()) {
        Cookie c = new CookieImpl(entry.getKey(), entry.getValue());
        String domain = additional.get(DOMAIN);
        if (domain != null) {
            c.setDomain(domain);
        }
        String version = additional.get(VERSION);
        if (version != null) {
            c.setVersion(Integer.parseInt(version));
        }
        String path = additional.get(PATH);
        if (path != null) {
            c.setPath(path);
        }
        parsedCookies.add(c);
    }
}
Also used : Cookie(io.undertow.server.handlers.Cookie) CookieImpl(io.undertow.server.handlers.CookieImpl) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Map(java.util.Map) HashMap(java.util.HashMap)

Example 12 with CookieImpl

use of io.undertow.server.handlers.CookieImpl in project core-ng-project by neowu.

the class ResponseHandler method cookie.

CookieImpl cookie(CookieSpec spec, String value) {
    CookieImpl cookie = new CookieImpl(spec.name);
    if (value == null) {
        cookie.setMaxAge(0);
        cookie.setValue("");
    } else {
        if (spec.maxAge != null)
            cookie.setMaxAge((int) spec.maxAge.getSeconds());
        // recommended to use URI encoding for cookie value, https://curl.haxx.se/rfc/cookie_spec.html
        cookie.setValue(Encodings.uriComponent(value));
    }
    cookie.setDomain(spec.domain);
    cookie.setPath(spec.path);
    cookie.setSecure(spec.secure);
    cookie.setHttpOnly(spec.httpOnly);
    return cookie;
}
Also used : CookieImpl(io.undertow.server.handlers.CookieImpl)

Aggregations

CookieImpl (io.undertow.server.handlers.CookieImpl)12 Cookie (io.undertow.server.handlers.Cookie)7 HashMap (java.util.HashMap)3 Map (java.util.Map)3 SecureRandomSessionIdGenerator (io.undertow.server.session.SecureRandomSessionIdGenerator)2 List (java.util.List)2 TreeMap (java.util.TreeMap)2 SecurityIdentity (org.wildfly.security.auth.server.SecurityIdentity)2 FieldParam (core.framework.impl.log.filter.FieldParam)1 CookieSpec (core.framework.web.CookieSpec)1 AuthenticationCallHandler (io.undertow.security.handlers.AuthenticationCallHandler)1 AuthenticationConstraintHandler (io.undertow.security.handlers.AuthenticationConstraintHandler)1 HttpHandler (io.undertow.server.HttpHandler)1 HttpServerExchange (io.undertow.server.HttpServerExchange)1 PathHandler (io.undertow.server.handlers.PathHandler)1 ServletRequestContext (io.undertow.servlet.handlers.ServletRequestContext)1 StatusCodes (io.undertow.util.StatusCodes)1 BufferedInputStream (java.io.BufferedInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1