org.zodiac.netty.http.request.HttpProtocolRequest Maven / Gradle / Ivy
The newest version!
package org.zodiac.netty.http.request;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.zodiac.netty.http.headers.HeaderValueType;
import org.zodiac.sdk.toolkit.constants.StringPool;
import org.zodiac.sdk.toolkit.util.lang.NumUtil;
import org.zodiac.sdk.toolkit.util.lang.StrUtil;
/**
* Provides access to http request headers and URL.
*
*/
public interface HttpProtocolRequest {
/**
* Get an HTTP header.
*
* @param A type
* @param header A header spec
* @return optional header
*/
default Optional httpHeader(HeaderValueType header) {
return httpHeader(Objects.requireNonNull(header, "header").name()).map(
val -> header.toValue(val));
}
/**
* Get the set of all header names in a request.
*
* @return A set of header names
*/
Set extends CharSequence> httpHeaderNames();
/**
* Get an HTTP header.
*
* @param name A name
* @return An optional
*/
Optional httpHeader(CharSequence name);
/**
* Get the anchor portion of the URI, if one was passed.
*
* @return An anchor if one is present
*/
Optional uriAnchor();
/**
* Get a path element of the URL path, if one exists.
*
* @param index The index of the /-delimited path element
* @return An optional
*/
Optional uriPathElement(int index);
/**
* Get a query parameter, if one is present.
*
* @param name A name
* @param decode If true, apply URL decoding to the result
* @return A string or empty
*/
Optional uriQueryParameter(CharSequence name, boolean decode);
/**
* Get a query parameter, applying URL decoding.
*
* @param name The parameter name
* @return A string if one is matched
*/
default Optional uriQueryParameter(CharSequence name) {
return uriQueryParameter(name, true);
}
/**
* Get a query parameter as a number, which may be one of Byte, Integer,
* Short, Long, Double, Float, BigDecimal or BigInteger.
*
* @param The number type
* @param name The name of the query parameter
* @param type The type to parse it to
* @return An optional which may contain a number of the passed type
*/
default Optional uriQueryParameter(CharSequence name, Class type) {
return asNumber(uriQueryParameter(name, false), type);
}
/**
* Get a URI query parameter as a boolean.
*
* @param name A query parameter name
* @return A boolean, if the query parameter is present
*/
default Optional booleanUriQueryParameter(CharSequence name) {
return uriQueryParameter(name, false)
.map(val -> StrUtil.equalsCharSeq(StringPool.TRUE, val)
? Boolean.TRUE
: Boolean.FALSE);
}
/**
* Get a path element as a number.
*
* @param A number type
* @param index the index within the URL path of the parameter
* @param type The type
* @return An optional which may contain a number of the passed type
*/
default Optional uriPathElement(int index, Class type) {
return asNumber(uriPathElement(index), type);
}
/**
* Get the URL anchor as a number.
*
* @param A number type
* @param type The type
* @return An optional which may contain a number of the passed type
*/
default Optional uriAnchor(Class type) {
return asNumber(uriAnchor(), type);
}
/**
* Get the HTTP method of the request.
*
* @return A method such as "GET"
*/
String httpMethod();
/**
* Determine if the method matches the string value of the passed object
* (allowing for anything that resolves case insensitively to an http method
* name to match).
*
* @param object An object
* @return True if the method name is a case insensitive match for the
* passed object
*/
default boolean isMethod(Object object) {
return Objects.requireNonNull(object, "object").toString().equalsIgnoreCase(httpMethod());
}
/**
* Get the request URI.
*
* @param preferHeaders If true, parse any of the common proxy headers
* x-forwarded-for, etc. and use that if present
* @return A string
*/
String requestUri(boolean preferHeaders);
/**
* Get the request URI preferring that value from the headers if there is
* one.
*
* @return A request uri
*/
default String requestUri() {
return requestUri(true);
}
static Optional asNumber(Optional value, Class type) {
try {
if (type == Long.class) {
return value.map(v -> type.cast(NumUtil.parseLong(v)));
} else if (type == Integer.class) {
return value.map(v -> type.cast(NumUtil.parseInt(v)));
} else if (type == Short.class) {
return value.map(val -> type.cast(Short.valueOf(val.toString())));
} else if (type == Byte.class) {
return value.map(val -> type.cast(Byte.valueOf(val.toString())));
} else if (type == Double.class) {
return value.map(val -> type.cast(Double.valueOf(val.toString())));
} else if (type == Float.class) {
return value.map(val -> type.cast(Float.valueOf(val.toString())));
} else if (type == BigInteger.class) {
return value.map(val -> type.cast(new BigInteger(val.toString())));
} else if (type == BigDecimal.class) {
return value.map(val -> type.cast(new BigDecimal(val.toString())));
} else {
throw new IllegalArgumentException("Unknown numeric type " + type);
}
} catch (NumberFormatException nfe) {
return Optional.empty();
}
}
}