All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.netty.handler.codec.http.CookieDecoder Maven / Gradle / Ivy

/*
 * Copyright 2011 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.handler.codec.http;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Decodes an HTTP header value into {@link Cookie}s.  This decoder can decode
 * the HTTP cookie version 0, 1, and 2.
 *
 * 
 * {@link HttpRequest} req = ...;
 * String value = req.getHeader("Cookie");
 * Set<{@link Cookie}> cookies = new {@link CookieDecoder}().decode(value);
 * 
* * @see CookieEncoder * * @apiviz.stereotype utility * @apiviz.has io.netty.handler.codec.http.Cookie oneway - - decodes */ public class CookieDecoder { private static final Pattern PATTERN = Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))"); private static final String COMMA = ","; private final boolean lenient; /** * Creates a new decoder with strict parsing. */ public CookieDecoder() { this(false); } /** * Creates a new decoder. * * @param lenient ignores cookies with the name 'HTTPOnly' instead of throwing an exception */ public CookieDecoder(boolean lenient) { this.lenient = lenient; } /** * Decodes the specified HTTP header value into {@link Cookie}s. * * @return the decoded {@link Cookie}s */ public Set decode(String header) { List names = new ArrayList(8); List values = new ArrayList(8); extractKeyValuePairs(header, names, values); if (names.isEmpty()) { return Collections.emptySet(); } int i; int version = 0; // $Version is the only attribute that can appear before the actual // cookie name-value pair. if (names.get(0).equalsIgnoreCase(CookieHeaderNames.VERSION)) { try { version = Integer.parseInt(values.get(0)); } catch (NumberFormatException e) { // Ignore. } i = 1; } else { i = 0; } if (names.size() <= i) { // There's a version attribute, but nothing more. return Collections.emptySet(); } Set cookies = new TreeSet(); for (; i < names.size(); i ++) { String name = names.get(i); // Not all user agents understand the HttpOnly attribute if (lenient && CookieHeaderNames.HTTPONLY.equalsIgnoreCase(name)) { continue; } String value = values.get(i); if (value == null) { value = ""; } Cookie c = new DefaultCookie(name, value); cookies.add(c); boolean discard = false; boolean secure = false; boolean httpOnly = false; String comment = null; String commentURL = null; String domain = null; String path = null; int maxAge = -1; List ports = new ArrayList(2); for (int j = i + 1; j < names.size(); j++, i++) { name = names.get(j); value = values.get(j); if (CookieHeaderNames.DISCARD.equalsIgnoreCase(name)) { discard = true; } else if (CookieHeaderNames.SECURE.equalsIgnoreCase(name)) { secure = true; } else if (CookieHeaderNames.HTTPONLY.equalsIgnoreCase(name)) { httpOnly = true; } else if (CookieHeaderNames.COMMENT.equalsIgnoreCase(name)) { comment = value; } else if (CookieHeaderNames.COMMENTURL.equalsIgnoreCase(name)) { commentURL = value; } else if (CookieHeaderNames.DOMAIN.equalsIgnoreCase(name)) { domain = value; } else if (CookieHeaderNames.PATH.equalsIgnoreCase(name)) { path = value; } else if (CookieHeaderNames.EXPIRES.equalsIgnoreCase(name)) { try { long maxAgeMillis = new HttpHeaderDateFormat().parse(value).getTime() - System.currentTimeMillis(); if (maxAgeMillis <= 0) { maxAge = 0; } else { maxAge = (int) (maxAgeMillis / 1000) + (maxAgeMillis % 1000 != 0? 1 : 0); } } catch (ParseException e) { // Ignore. } } else if (CookieHeaderNames.MAX_AGE.equalsIgnoreCase(name)) { maxAge = Integer.parseInt(value); } else if (CookieHeaderNames.VERSION.equalsIgnoreCase(name)) { version = Integer.parseInt(value); } else if (CookieHeaderNames.PORT.equalsIgnoreCase(name)) { String[] portList = value.split(COMMA); for (String s1: portList) { try { ports.add(Integer.valueOf(s1)); } catch (NumberFormatException e) { // Ignore. } } } else { break; } } c.setVersion(version); c.setMaxAge(maxAge); c.setPath(path); c.setDomain(domain); c.setSecure(secure); c.setHttpOnly(httpOnly); if (version > 0) { c.setComment(comment); } if (version > 1) { c.setCommentUrl(commentURL); c.setPorts(ports); c.setDiscard(discard); } } return cookies; } private void extractKeyValuePairs( String header, List names, List values) { Matcher m = PATTERN.matcher(header); int pos = 0; String name = null; String value = null; String separator = null; while (m.find(pos)) { pos = m.end(); // Extract name and value pair from the match. String newName = m.group(1); String newValue = m.group(3); if (newValue == null) { newValue = decodeValue(m.group(2)); } String newSeparator = m.group(4); if (name == null) { name = newName; value = newValue == null? "" : newValue; separator = newSeparator; continue; } if (newValue == null && !CookieHeaderNames.DISCARD.equalsIgnoreCase(newName) && !CookieHeaderNames.SECURE.equalsIgnoreCase(newName) && !CookieHeaderNames.HTTPONLY.equalsIgnoreCase(newName)) { value = value + separator + newName; separator = newSeparator; continue; } names.add(name); values.add(value); name = newName; value = newValue; separator = newSeparator; } // The last entry if (name != null) { names.add(name); values.add(value); } } private String decodeValue(String value) { if (value == null) { return value; } return value.replace("\\\"", "\"").replace("\\\\", "\\"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy