package io.vertx.ext.web.impl;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import io.vertx.ext.web.ParsedHeaderValue;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
public class {
private static final Logger = LoggerFactory.getLogger(HeaderParser.class);
private static final Comparator<ParsedHeaderValue> =
(ParsedHeaderValue left, ParsedHeaderValue right) -> right.weightedOrder() - left.weightedOrder();
public static <T extends ParsedHeaderValue> List<T> (String unparsedHeaderValue, Function<String, T> objectCreator) {
return split(unparsedHeaderValue, ',', objectCreator);
}
public static <T extends ParsedHeaderValue> List<T> (List<T> headers) {
headers.sort(HEADER_SORTER);
return headers;
}
public static void (String headerContent, Consumer<String> valueCallback, Consumer<Float> weightCallback, BiConsumer<String, String> parameterCallback) {
int paramIndex = headerContent.indexOf(';');
if (paramIndex < 0) {
valueCallback.accept(headerContent);
} else {
valueCallback.accept(headerContent.substring(0, paramIndex));
if (paramIndex < headerContent.length()) {
split(headerContent.substring(paramIndex + 1), ';', part -> {
int idx = part.indexOf('=');
if (idx != -1) {
final String key = part.substring(0, idx);
final String val = part.substring(idx + 1);
if ("q".equalsIgnoreCase(key)) {
try {
weightCallback.accept(Float.parseFloat(val));
} catch (NumberFormatException e) {
log.info("Found a \"q\" parameter with value \"{}\" which was unparsable", val);
}
} else {
parameterCallback.accept(key, unquote(val));
}
} else {
parameterCallback.accept(part, null);
}
return null;
});
}
}
}
public static void (
String headerContent,
Consumer<String> componentCallback,
Consumer<String> subcomponentCallback
) {
int slashIndex = headerContent.indexOf('/');
int paramIndex = headerContent.indexOf(';', slashIndex + 1);
if (slashIndex < 0) {
componentCallback.accept("*");
} else {
componentCallback.accept(headerContent.substring(0, slashIndex).toLowerCase());
}
if (paramIndex < 0) {
subcomponentCallback.accept(headerContent.substring(slashIndex + 1));
} else {
subcomponentCallback.accept(headerContent.substring(slashIndex + 1, paramIndex).toLowerCase());
}
}
public static List<String> (String value) {
if (value == null || value.length() == 0) {
return Collections.emptyList();
}
final List<String> parts = new LinkedList<>();
int start = 0;
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (start == i && ch == ' ') {
start++;
continue;
}
if (ch == '-' || ch == '_') {
int end = i;
for (int j = i - 1; j >= start; j--) {
if (value.charAt(j) == ' ') {
end--;
continue;
}
break;
}
if (end - start > 0) {
parts.add(value.substring(start, end));
if (parts.size() == 3) {
return parts;
}
}
start = i + 1;
}
}
if (start < value.length()) {
int end = value.length();
for (int j = value.length() - 1; j >= start; j--) {
if (value.charAt(j) == ' ') {
end--;
continue;
}
break;
}
if (end - start > 0) {
parts.add(value.substring(start, end));
}
}
return parts;
}
private static <T> List<T> (String header, char split, Function<String, T> factory) {
if (header == null || header.length() == 0) {
return Collections.emptyList();
}
final List<T> parts = new LinkedList<>();
boolean quote = false;
int start = 0;
char last = 0;
for (int i = 0; i < header.length(); i++) {
char ch = header.charAt(i);
if (start == i && ch == ' ') {
start++;
continue;
}
if (ch == '\"' && last != '\\') {
quote = !quote;
}
last = ch;
if (!quote && ch == split) {
int end = i;
for (int j = i - 1; j >= start; j--) {
if (header.charAt(j) == ' ') {
end--;
continue;
}
break;
}
if (end - start > 0) {
parts.add(factory.apply(header.substring(start, end)));
}
start = i + 1;
}
}
if (start < header.length()) {
int end = header.length();
for (int j = header.length() - 1; j >= start; j--) {
if (header.charAt(j) == ' ') {
end--;
continue;
}
break;
}
if (end - start > 0) {
parts.add(factory.apply(header.substring(start, end)));
}
}
return parts;
}
private static String (String value) {
if (value == null || value.length() == 0) {
return value;
}
StringBuilder sb = null;
int start = 0;
int end = value.length();
if (value.charAt(start) == '\"') {
start++;
}
if (value.charAt(end - 1) == '\"') {
end--;
}
for (int i = start ; i < end; i++) {
if (value.charAt(i) == '\\') {
if (sb == null) {
sb = new StringBuilder(value.substring(start, i));
}
continue;
}
if (sb != null) {
sb.append(value.charAt(i));
}
}
if (sb != null) {
return sb.toString();
} else {
if (end - start != value.length()) {
return value.substring(start, end);
}
return value;
}
}
}