|
|
|
@ -76,9 +76,9 @@ public abstract class PathHandler implements HttpHandler {
@@ -76,9 +76,9 @@ public abstract class PathHandler implements HttpHandler {
|
|
|
|
|
String method = ex.getRequestMethod(); |
|
|
|
|
LOG.log(INFO, "{0} {1}", method, path); |
|
|
|
|
boolean ignored = switch (method) { |
|
|
|
|
case DELETE -> doDelete(path,ex); |
|
|
|
|
case GET -> doGet(path,ex); |
|
|
|
|
case POST -> doPost(path,ex); |
|
|
|
|
case DELETE -> doDelete(path, ex); |
|
|
|
|
case GET -> doGet(path, ex); |
|
|
|
|
case POST -> doPost(path, ex); |
|
|
|
|
default -> false; |
|
|
|
|
}; |
|
|
|
|
ex.getResponseBody().close(); |
|
|
|
@ -86,116 +86,116 @@ public abstract class PathHandler implements HttpHandler {
@@ -86,116 +86,116 @@ public abstract class PathHandler implements HttpHandler {
|
|
|
|
|
|
|
|
|
|
public String relativePath(HttpExchange ex) { |
|
|
|
|
var requestPath = ex.getRequestURI().toString(); |
|
|
|
|
for (var path : paths){ |
|
|
|
|
if (requestPath.startsWith(path)) { |
|
|
|
|
requestPath = requestPath.substring(path.length()); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!requestPath.startsWith("/")) requestPath = "/" + requestPath; |
|
|
|
|
var pos = requestPath.indexOf("?"); |
|
|
|
|
if (pos >= 0) requestPath = requestPath.substring(0, pos); |
|
|
|
|
return requestPath; |
|
|
|
|
} |
|
|
|
|
for (var path : paths) { |
|
|
|
|
if (requestPath.startsWith(path)) { |
|
|
|
|
requestPath = requestPath.substring(path.length()); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!requestPath.startsWith("/")) requestPath = "/" + requestPath; |
|
|
|
|
var pos = requestPath.indexOf("?"); |
|
|
|
|
if (pos >= 0) requestPath = requestPath.substring(0, pos); |
|
|
|
|
return requestPath; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/******* begin of static methods *************/ |
|
|
|
|
/******* begin of static methods *************/ |
|
|
|
|
|
|
|
|
|
public static String body(HttpExchange ex) throws IOException { |
|
|
|
|
return new String(ex.getRequestBody().readAllBytes(), UTF_8); |
|
|
|
|
} |
|
|
|
|
public static String body(HttpExchange ex) throws IOException { |
|
|
|
|
return new String(ex.getRequestBody().readAllBytes(), UTF_8); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static Optional<String> getAuthToken(HttpExchange ex) { |
|
|
|
|
return getHeader(ex, AUTHORIZATION); |
|
|
|
|
} |
|
|
|
|
public static Optional<String> getAuthToken(HttpExchange ex) { |
|
|
|
|
return getHeader(ex, AUTHORIZATION); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static Optional<BasicAuth> getBasicAuth(HttpExchange ex) { |
|
|
|
|
return getAuthToken(ex) |
|
|
|
|
.filter(token -> token.startsWith("Basic ")) //
|
|
|
|
|
.map(token -> token.substring(6)) |
|
|
|
|
.map(Base64.getDecoder()::decode) |
|
|
|
|
.map(bytes -> new String(bytes, UTF_8)) |
|
|
|
|
.map(token -> token.split(":", 2)) |
|
|
|
|
.map(arr -> new BasicAuth(arr[0], arr[1])); |
|
|
|
|
} |
|
|
|
|
public static Optional<BasicAuth> getBasicAuth(HttpExchange ex) { |
|
|
|
|
return getAuthToken(ex) |
|
|
|
|
.filter(token -> token.startsWith("Basic ")) //
|
|
|
|
|
.map(token -> token.substring(6)) |
|
|
|
|
.map(Base64.getDecoder()::decode) |
|
|
|
|
.map(bytes -> new String(bytes, UTF_8)) |
|
|
|
|
.map(token -> token.split(":", 2)) |
|
|
|
|
.map(arr -> new BasicAuth(arr[0], arr[1])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static Optional<String> getBearer(HttpExchange ex) { |
|
|
|
|
return getAuthToken(ex).filter(token -> token.startsWith("Bearer ")).map(token -> token.substring(7)); |
|
|
|
|
} |
|
|
|
|
public static Optional<String> getBearer(HttpExchange ex) { |
|
|
|
|
return getAuthToken(ex).filter(token -> token.startsWith("Bearer ")).map(token -> token.substring(7)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static Optional<String> getHeader(HttpExchange ex, String key) { |
|
|
|
|
return nullable(ex.getRequestHeaders().get(key)).map(List::stream).flatMap(Stream::findFirst); |
|
|
|
|
} |
|
|
|
|
public static Optional<String> getHeader(HttpExchange ex, String key) { |
|
|
|
|
return nullable(ex.getRequestHeaders().get(key)).map(List::stream).flatMap(Stream::findFirst); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String hostname(HttpExchange ex) { |
|
|
|
|
var headers = ex.getRequestHeaders(); |
|
|
|
|
var host = headers.getFirst(FORWARDED_HOST); |
|
|
|
|
if (host == null) host = headers.getFirst(HOST); |
|
|
|
|
var proto = nullable(headers.getFirst("X-forwarded-proto")).orElseGet(() -> ex instanceof HttpsExchange ? "https" : "http"); |
|
|
|
|
return host == null ? null : proto + "://" + host; |
|
|
|
|
} |
|
|
|
|
public static String hostname(HttpExchange ex) { |
|
|
|
|
var headers = ex.getRequestHeaders(); |
|
|
|
|
var host = headers.getFirst(FORWARDED_HOST); |
|
|
|
|
if (host == null) host = headers.getFirst(HOST); |
|
|
|
|
var proto = nullable(headers.getFirst("X-forwarded-proto")).orElseGet(() -> ex instanceof HttpsExchange ? "https" : "http"); |
|
|
|
|
return host == null ? null : proto + "://" + host; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static JSONObject json(HttpExchange ex) throws IOException { |
|
|
|
|
return new JSONObject(body(ex)); |
|
|
|
|
} |
|
|
|
|
public static JSONObject json(HttpExchange ex) throws IOException { |
|
|
|
|
return new JSONObject(body(ex)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String language(HttpExchange ex) { |
|
|
|
|
return getHeader(ex, "Accept-Language") //
|
|
|
|
|
.map(s -> Arrays.stream(s.split(","))) |
|
|
|
|
.flatMap(Stream::findFirst) |
|
|
|
|
.orElse(DEFAULT_LANGUAGE); |
|
|
|
|
} |
|
|
|
|
public static String language(HttpExchange ex) { |
|
|
|
|
return getHeader(ex, "Accept-Language") //
|
|
|
|
|
.map(s -> Arrays.stream(s.split(","))) |
|
|
|
|
.flatMap(Stream::findFirst) |
|
|
|
|
.orElse(DEFAULT_LANGUAGE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean notFound(HttpExchange ex) throws IOException { |
|
|
|
|
LOG.log(ERROR, "not implemented"); |
|
|
|
|
return sendEmptyResponse(HTTP_NOT_FOUND, ex); |
|
|
|
|
} |
|
|
|
|
public static boolean notFound(HttpExchange ex) throws IOException { |
|
|
|
|
LOG.log(ERROR, "not implemented"); |
|
|
|
|
return sendEmptyResponse(HTTP_NOT_FOUND, ex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Map<String, String> queryParam(HttpExchange ex) { |
|
|
|
|
return Arrays |
|
|
|
|
.stream(ex.getRequestURI().getQuery().split("&")) //
|
|
|
|
|
.map(s -> s.split("=", 2)) |
|
|
|
|
.collect(Collectors.toMap(arr -> arr[0], arr -> arr[1])); |
|
|
|
|
} |
|
|
|
|
public Map<String, String> queryParam(HttpExchange ex) { |
|
|
|
|
return Arrays |
|
|
|
|
.stream(ex.getRequestURI().getQuery().split("&")) //
|
|
|
|
|
.map(s -> s.split("=", 2)) |
|
|
|
|
.collect(Collectors.toMap(arr -> arr[0], arr -> arr[1])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException { |
|
|
|
|
ex.sendResponseHeaders(statusCode, 0); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
public static boolean sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException { |
|
|
|
|
ex.sendResponseHeaders(statusCode, 0); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean sendRedirect(HttpExchange ex, String url) throws IOException { |
|
|
|
|
ex.getResponseHeaders().add("Location", url); |
|
|
|
|
return sendEmptyResponse(HTTP_MOVED_TEMP, ex); |
|
|
|
|
} |
|
|
|
|
public static boolean sendRedirect(HttpExchange ex, String url) throws IOException { |
|
|
|
|
ex.getResponseHeaders().add("Location", url); |
|
|
|
|
return sendEmptyResponse(HTTP_MOVED_TEMP, ex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean sendContent(HttpExchange ex, int status, byte[] bytes) throws IOException { |
|
|
|
|
LOG.log(DEBUG, "sending {0} response…", status); |
|
|
|
|
ex.sendResponseHeaders(status, bytes.length); |
|
|
|
|
ex.getResponseBody().write(bytes); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
public static boolean sendContent(HttpExchange ex, int status, byte[] bytes) throws IOException { |
|
|
|
|
LOG.log(DEBUG, "sending {0} response…", status); |
|
|
|
|
ex.sendResponseHeaders(status, bytes.length); |
|
|
|
|
ex.getResponseBody().write(bytes); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean sendContent(HttpExchange ex, int status, Object o) throws IOException { |
|
|
|
|
if (o instanceof List<?> list) o = new JSONArray(list); |
|
|
|
|
public static boolean sendContent(HttpExchange ex, int status, Object o) throws IOException { |
|
|
|
|
if (o instanceof List<?> list) o = new JSONArray(list); |
|
|
|
|
if (o instanceof Map<?, ?> map) o = new JSONObject(map); |
|
|
|
|
if (o instanceof Error<?> error) o = error.json(); |
|
|
|
|
return sendContent(ex, status, o.toString().getBytes(UTF_8)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static boolean sendContent(HttpExchange ex, byte[] bytes) throws IOException { |
|
|
|
|
return sendContent(ex, HTTP_OK, bytes); |
|
|
|
|
} |
|
|
|
|
public static boolean sendContent(HttpExchange ex, byte[] bytes) throws IOException { |
|
|
|
|
return sendContent(ex, HTTP_OK, bytes); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean sendContent(HttpExchange ex, Object o) throws IOException { |
|
|
|
|
return sendContent(ex, HTTP_OK, o); |
|
|
|
|
} |
|
|
|
|
public static boolean sendContent(HttpExchange ex, Object o) throws IOException { |
|
|
|
|
return sendContent(ex, HTTP_OK, o); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean serverError(HttpExchange ex, Object o) throws IOException { |
|
|
|
|
sendContent(ex, HTTP_INTERNAL_ERROR, o); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
public static boolean serverError(HttpExchange ex, Object o) throws IOException { |
|
|
|
|
sendContent(ex, HTTP_INTERNAL_ERROR, o); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String url(HttpExchange ex) { |
|
|
|
|
return hostname(ex) + ex.getRequestURI(); |
|
|
|
|
} |
|
|
|
|
public static String url(HttpExchange ex) { |
|
|
|
|
return hostname(ex) + ex.getRequestURI(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|