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
|
||||
name = net-http
|
||||
version = 4.0.2
|
||||
version = 4.0.3
|
||||
|
||||
org.gradle.warning.mode = ALL
|
||||
|
|
|
@ -3,5 +3,6 @@ dependencies {
|
|||
api libs.config
|
||||
implementation libs.settings.datastructures.json
|
||||
implementation libs.settings.datastructures.yaml
|
||||
implementation libs.datastructures.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.http;
|
||||
requires org.xbib.datastructures.common;
|
||||
requires org.xbib.datastructures.tiny;
|
||||
requires org.xbib.datastructures.json.tiny;
|
||||
requires org.xbib.config;
|
||||
requires java.logging;
|
||||
|
|
|
@ -2,27 +2,41 @@ package org.xbib.net.http.server;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.MalformedInputException;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.xbib.datastructures.common.MultiMap;
|
||||
import org.xbib.datastructures.common.Pair;
|
||||
import org.xbib.datastructures.json.tiny.Json;
|
||||
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.Parameter;
|
||||
import org.xbib.net.ParameterException;
|
||||
import org.xbib.net.PercentDecoder;
|
||||
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.HttpMethod;
|
||||
import org.xbib.net.http.HttpVersion;
|
||||
import org.xbib.net.http.server.auth.BaseAttributes;
|
||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||
import org.xbib.net.util.ExceptionFormatter;
|
||||
|
||||
public abstract class BaseHttpRequest implements HttpRequest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(BaseHttpRequest.class.getName());
|
||||
|
||||
protected final BaseHttpRequestBuilder builder;
|
||||
|
||||
private final Attributes attributes;
|
||||
|
@ -157,7 +171,7 @@ public abstract class BaseHttpRequest implements HttpRequest {
|
|||
jsonBuilder.buildKey("sequenceid").buildValue(builder.sequenceId);
|
||||
jsonBuilder.buildKey("streamid").buildValue(builder.streamId);
|
||||
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("body").buildValue(StandardCharsets.ISO_8859_1.decode(builder.getBody()).toString());
|
||||
jsonBuilder.endMap();
|
||||
|
@ -166,4 +180,83 @@ public abstract class BaseHttpRequest implements HttpRequest {
|
|||
}
|
||||
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.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import org.xbib.datastructures.common.MultiMap;
|
||||
import org.xbib.net.Attributes;
|
||||
import org.xbib.net.Parameter;
|
||||
import org.xbib.net.Request;
|
||||
|
@ -45,4 +46,6 @@ public interface HttpRequest extends Request {
|
|||
Attributes getAttributes();
|
||||
|
||||
String asJson();
|
||||
|
||||
MultiMap<String, Object> asMultiMap();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ dependencyResolutionManagement {
|
|||
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
||||
library('net-bouncycastle', 'org.xbib', 'net-bouncycastle').versionRef('net')
|
||||
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-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
||||
library('config', 'org.xbib', 'config').versionRef('datastructures')
|
||||
|
|
Loading…
Reference in a new issue