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

io.muserver.ParameterizedHeader Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package io.muserver;

import java.util.*;

import static io.muserver.Mutils.notNull;
import static io.muserver.ParseUtils.isOWS;
import static io.muserver.ParseUtils.isTChar;
import static java.util.Collections.emptyMap;

/**
 * 

A utility class to parse headers that are of the format param1, param2=value, param3="quoted string" * such as Cache-Control etc.

* @see ParameterizedHeaderWithValue */ public class ParameterizedHeader { private final Map parameters; /** * Creates a value with parameters * * @param parameters A map of parameters, such as charset: UTF-8 */ private ParameterizedHeader(Map parameters) { notNull("parameters", parameters); this.parameters = parameters; } /** * @return Gets all the parameters */ public Map parameters() { return parameters; } /** * @param name The name of the parameter to get * @return Gets a single parameter, or null if there is no value */ public String parameter(String name) { return parameters.get(name); } /** * @param name The name of the parameter to get * @param defaultValue The value to return if no parameter was set * @return Gets a single parameter, or null if there is no value */ public String parameter(String name, String defaultValue) { return parameters.getOrDefault(name, defaultValue); } /** * @param name The name of the parameter to look up * @return True if the parameter exists (with or without a value); otherwise false */ public boolean hasParameter(String name) { return parameters.containsKey(name); } /** * @return Gets the parameters in the order declared (without the parameter values) */ public List parameterNames() { return new ArrayList<>(parameters.keySet()); } private enum State {PARAM_NAME, PARAM_VALUE} /** *

Converts a comma-separated list of param names (with optional values) into a Parameterized Header

*

Null or blank strings return value with an empty parameter map.

* @param input The value to parse * @return An object containing a map of name/value pairs (where values may be null) * @throws IllegalArgumentException The value cannot be parsed */ public static ParameterizedHeader fromString(String input) { if (input == null || input.trim().isEmpty()) { return new ParameterizedHeader(emptyMap()); } StringBuilder buffer = new StringBuilder(); Map parameters = new LinkedHashMap<>(); // keeps insertion order State state = State.PARAM_NAME; String paramName = null; boolean isQuotedString = false; for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (state == State.PARAM_NAME) { if (c == ',') { if (buffer.length() > 0) { parameters.put(buffer.toString(), null); buffer.setLength(0); paramName = null; } } else if (c == '=') { paramName = buffer.toString(); if (paramName.isEmpty()) { throw new IllegalArgumentException("Nameless values not allowed"); } buffer.setLength(0); state = State.PARAM_VALUE; } else if (isTChar(c)) { buffer.append(c); } else if (isOWS(c)) { // ignore it } else { throw new IllegalArgumentException("Got ascii " + ((int) c) + " while in " + state); } } else { boolean isFirst = !isQuotedString && buffer.length() == 0; if (isFirst && isOWS(c)) { // ignore it } else if (isFirst && c == '"') { isQuotedString = true; } else { if (isQuotedString) { char lastChar = input.charAt(i - 1); if (c == '\\') { // don't append } else if (lastChar == '\\') { buffer.append(c); } else if (c == '"') { // this is the end, but we'll update on the next go isQuotedString = false; } else { buffer.append(c); } } else { if (c == ',') { parameters.put(paramName, buffer.toString()); buffer.setLength(0); paramName = null; state = State.PARAM_NAME; } else if (isTChar(c)) { buffer.append(c); } else if (isOWS(c)) { // ignore it } else { throw new IllegalArgumentException("Got character code " + ((int) c) + " (" + c + ") while parsing parameter value"); } } } } } if (state == State.PARAM_VALUE) { parameters.put(paramName, buffer.toString()); buffer.setLength(0); } else { if (buffer.length() > 0) { parameters.put(buffer.toString(), null); } } return new ParameterizedHeader(parameters); } /** * Converts the HeaderValue into a string, suitable for printing in an HTTP header. * * @return A String, such as "some-value" or "content-type:text/html;charset=UTF-8" */ public String toString() { StringBuilder sb = new StringBuilder(); Map parameters = this.parameters(); for (Map.Entry entry : parameters.entrySet()) { if (sb.length() > 0) { sb.append(", "); } sb.append(entry.getKey()); String value = entry.getValue(); if (value != null) { sb.append('=').append(ParseUtils.quoteIfNeeded(value)); } } return sb.toString(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ParameterizedHeader that = (ParameterizedHeader) o; return Objects.equals(parameters, that.parameters); } @Override public int hashCode() { return Objects.hash(parameters); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy