add multi map convenience method to obtain all parameters from a http request
This commit is contained in:
parent
2b413def7a
commit
ba332dd10b
6 changed files with 102 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = net-http
|
name = net-http
|
||||||
version = 4.0.2
|
version = 4.0.3
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -3,5 +3,6 @@ dependencies {
|
||||||
api libs.config
|
api libs.config
|
||||||
implementation libs.settings.datastructures.json
|
implementation libs.settings.datastructures.json
|
||||||
implementation libs.settings.datastructures.yaml
|
implementation libs.settings.datastructures.yaml
|
||||||
|
implementation libs.datastructures.tiny
|
||||||
implementation libs.datastructures.json.tiny
|
implementation libs.datastructures.json.tiny
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ module org.xbib.net.http.server {
|
||||||
requires org.xbib.net.mime;
|
requires org.xbib.net.mime;
|
||||||
requires org.xbib.net.http;
|
requires org.xbib.net.http;
|
||||||
requires org.xbib.datastructures.common;
|
requires org.xbib.datastructures.common;
|
||||||
|
requires org.xbib.datastructures.tiny;
|
||||||
requires org.xbib.datastructures.json.tiny;
|
requires org.xbib.datastructures.json.tiny;
|
||||||
requires org.xbib.config;
|
requires org.xbib.config;
|
||||||
requires java.logging;
|
requires java.logging;
|
||||||
|
|
|
@ -2,27 +2,41 @@ package org.xbib.net.http.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.charset.MalformedInputException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.nio.charset.UnmappableCharacterException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.xbib.datastructures.common.MultiMap;
|
||||||
import org.xbib.datastructures.common.Pair;
|
import org.xbib.datastructures.common.Pair;
|
||||||
|
import org.xbib.datastructures.json.tiny.Json;
|
||||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||||
|
import org.xbib.datastructures.tiny.TinyList;
|
||||||
|
import org.xbib.datastructures.tiny.TinyMultiMap;
|
||||||
import org.xbib.net.Attributes;
|
import org.xbib.net.Attributes;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
import org.xbib.net.ParameterException;
|
import org.xbib.net.ParameterException;
|
||||||
|
import org.xbib.net.PercentDecoder;
|
||||||
import org.xbib.net.URL;
|
import org.xbib.net.URL;
|
||||||
|
import org.xbib.net.http.HttpHeaderNames;
|
||||||
|
import org.xbib.net.http.HttpHeaderValues;
|
||||||
import org.xbib.net.http.HttpHeaders;
|
import org.xbib.net.http.HttpHeaders;
|
||||||
import org.xbib.net.http.HttpMethod;
|
import org.xbib.net.http.HttpMethod;
|
||||||
import org.xbib.net.http.HttpVersion;
|
import org.xbib.net.http.HttpVersion;
|
||||||
import org.xbib.net.http.server.auth.BaseAttributes;
|
import org.xbib.net.http.server.auth.BaseAttributes;
|
||||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||||
|
import org.xbib.net.util.ExceptionFormatter;
|
||||||
|
|
||||||
public abstract class BaseHttpRequest implements HttpRequest {
|
public abstract class BaseHttpRequest implements HttpRequest {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(BaseHttpRequest.class.getName());
|
||||||
|
|
||||||
protected final BaseHttpRequestBuilder builder;
|
protected final BaseHttpRequestBuilder builder;
|
||||||
|
|
||||||
private final Attributes attributes;
|
private final Attributes attributes;
|
||||||
|
@ -157,7 +171,7 @@ public abstract class BaseHttpRequest implements HttpRequest {
|
||||||
jsonBuilder.buildKey("sequenceid").buildValue(builder.sequenceId);
|
jsonBuilder.buildKey("sequenceid").buildValue(builder.sequenceId);
|
||||||
jsonBuilder.buildKey("streamid").buildValue(builder.streamId);
|
jsonBuilder.buildKey("streamid").buildValue(builder.streamId);
|
||||||
jsonBuilder.buildKey("requestid").buildValue(builder.requestId);
|
jsonBuilder.buildKey("requestid").buildValue(builder.requestId);
|
||||||
// body may be large
|
// body may be large, skip it
|
||||||
//jsonBuilder.buildKey("encoding").buildValue("ISO-8859-1");
|
//jsonBuilder.buildKey("encoding").buildValue("ISO-8859-1");
|
||||||
//jsonBuilder.buildKey("body").buildValue(StandardCharsets.ISO_8859_1.decode(builder.getBody()).toString());
|
//jsonBuilder.buildKey("body").buildValue(StandardCharsets.ISO_8859_1.decode(builder.getBody()).toString());
|
||||||
jsonBuilder.endMap();
|
jsonBuilder.endMap();
|
||||||
|
@ -166,4 +180,83 @@ public abstract class BaseHttpRequest implements HttpRequest {
|
||||||
}
|
}
|
||||||
return jsonBuilder.build();
|
return jsonBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public MultiMap<String, Object> asMultiMap() {
|
||||||
|
PercentDecoder percentDecoder = new PercentDecoder();
|
||||||
|
MultiMap<String, Object> multiMap = new ParameterMap();
|
||||||
|
String contentType = getHeaders().get(HttpHeaderNames.CONTENT_TYPE);
|
||||||
|
if (getMethod() == HttpMethod.POST &&
|
||||||
|
contentType != null && contentType.contains(HttpHeaderValues.APPLICATION_JSON)) {
|
||||||
|
String bodyAsChars = getBodyAsChars(StandardCharsets.UTF_8).toString();
|
||||||
|
Map<String, Object> map = Json.toMap(bodyAsChars);
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() instanceof Iterable) {
|
||||||
|
multiMap.putAll(entry.getKey(), (Iterable<Object>) entry.getValue());
|
||||||
|
} else {
|
||||||
|
multiMap.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
toMultiMapEntry(getParameter().get(Parameter.Domain.PATH),
|
||||||
|
percentDecoder,
|
||||||
|
false,
|
||||||
|
multiMap);
|
||||||
|
toMultiMapEntry(getParameter().get(Parameter.Domain.FORM),
|
||||||
|
percentDecoder,
|
||||||
|
HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED.equals(contentType),
|
||||||
|
multiMap);
|
||||||
|
toMultiMapEntry(getParameter().get(Parameter.Domain.QUERY),
|
||||||
|
percentDecoder,
|
||||||
|
HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED.equals(contentType),
|
||||||
|
multiMap);
|
||||||
|
} catch (ParameterException e) {
|
||||||
|
logger.log(Level.WARNING, e.getMessage(), ExceptionFormatter.format(e));
|
||||||
|
}
|
||||||
|
return multiMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void toMultiMapEntry(Parameter parameter,
|
||||||
|
PercentDecoder percentDecoder,
|
||||||
|
boolean isFormEncoded,
|
||||||
|
MultiMap<String, Object> multiMap) {
|
||||||
|
for (Pair<String, Object> entry : parameter) {
|
||||||
|
try {
|
||||||
|
List<Object> list;
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (value instanceof List) {
|
||||||
|
list = (List<Object>) value;
|
||||||
|
} else if (value != null) {
|
||||||
|
list = List.of(value);
|
||||||
|
} else {
|
||||||
|
list = List.of();
|
||||||
|
}
|
||||||
|
for (Object object : list) {
|
||||||
|
String string = object.toString();
|
||||||
|
if (isFormEncoded) {
|
||||||
|
string = string.replace('+', ' ');
|
||||||
|
}
|
||||||
|
multiMap.put(entry.getKey(), percentDecoder.decode(string));
|
||||||
|
}
|
||||||
|
} catch (MalformedInputException | UnmappableCharacterException e) {
|
||||||
|
logger.log(Level.WARNING, "unable to percent decode parameter: " +
|
||||||
|
entry.getKey() + "=" + entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ParameterMap extends TinyMultiMap<String, Object> {
|
||||||
|
|
||||||
|
public ParameterMap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<Object> newValues() {
|
||||||
|
// keep values with multiple occurences
|
||||||
|
return TinyList.builder();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.net.http.server;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.xbib.datastructures.common.MultiMap;
|
||||||
import org.xbib.net.Attributes;
|
import org.xbib.net.Attributes;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
import org.xbib.net.Request;
|
import org.xbib.net.Request;
|
||||||
|
@ -45,4 +46,6 @@ public interface HttpRequest extends Request {
|
||||||
Attributes getAttributes();
|
Attributes getAttributes();
|
||||||
|
|
||||||
String asJson();
|
String asJson();
|
||||||
|
|
||||||
|
MultiMap<String, Object> asMultiMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ dependencyResolutionManagement {
|
||||||
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
||||||
library('net-bouncycastle', 'org.xbib', 'net-bouncycastle').versionRef('net')
|
library('net-bouncycastle', 'org.xbib', 'net-bouncycastle').versionRef('net')
|
||||||
library('datastructures-common', 'org.xbib', 'datastructures-common').versionRef('datastructures')
|
library('datastructures-common', 'org.xbib', 'datastructures-common').versionRef('datastructures')
|
||||||
|
library('datastructures-tiny', 'org.xbib', 'datastructures-tiny').versionRef('datastructures')
|
||||||
library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
|
library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
|
||||||
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
||||||
library('config', 'org.xbib', 'config').versionRef('datastructures')
|
library('config', 'org.xbib', 'config').versionRef('datastructures')
|
||||||
|
|
Loading…
Reference in a new issue