initial commit
This commit is contained in:
commit
d40ca8cc56
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
11
asdf00.lib.httpserver.iml
Normal file
11
asdf00.lib.httpserver.iml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
7
src/dev/asdf00/lib/httpserver/Authorizer.java
Normal file
7
src/dev/asdf00/lib/httpserver/Authorizer.java
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.asdf00.lib.httpserver;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
|
||||||
|
public interface Authorizer {
|
||||||
|
boolean isAuthenticated(HttpExchange exchange);
|
||||||
|
}
|
||||||
119
src/dev/asdf00/lib/httpserver/HttpServerApi.java
Normal file
119
src/dev/asdf00/lib/httpserver/HttpServerApi.java
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
package dev.asdf00.lib.httpserver;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpContext;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
import dev.asdf00.lib.httpserver.annotations.HttpEndpoint;
|
||||||
|
import dev.asdf00.lib.httpserver.annotations.QParam;
|
||||||
|
import dev.asdf00.lib.httpserver.exceptions.HttpHandlingException;
|
||||||
|
import dev.asdf00.lib.httpserver.internal.DefaultAuthorizer;
|
||||||
|
import dev.asdf00.lib.httpserver.internal.EndpointContainer;
|
||||||
|
import dev.asdf00.lib.httpserver.internal.HttpHandlerImpl;
|
||||||
|
import dev.asdf00.lib.httpserver.utils.RequestType;
|
||||||
|
import dev.asdf00.lib.httpserver.utils.Response;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import static dev.asdf00.lib.httpserver.HttpServerApiUtils.*;
|
||||||
|
import static dev.asdf00.lib.httpserver.utils.RequestType.*;
|
||||||
|
|
||||||
|
public class HttpServerApi {
|
||||||
|
|
||||||
|
public static Response respond404(HttpExchange exchange) throws HttpHandlingException {
|
||||||
|
throw new HttpHandlingException(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServer create(int port, String rootLocation, Class<?> apiDefinition, Executor exec) throws IOException {
|
||||||
|
HttpServer server = HttpServer.create(new InetSocketAddress( port), 0);
|
||||||
|
server.setExecutor(exec);
|
||||||
|
|
||||||
|
// collect all http endpoints
|
||||||
|
HashMap<String, EndpointContainer>[] endpoints = new HashMap[3];
|
||||||
|
HashSet<String> locations = new HashSet<>();
|
||||||
|
for (int i = 0; i < endpoints.length; endpoints[i++] = new HashMap<>());
|
||||||
|
endpointLoop:
|
||||||
|
for (Method endpoint : apiDefinition.getDeclaredMethods()) {
|
||||||
|
HttpEndpoint spec = endpoint.getAnnotation(HttpEndpoint.class);
|
||||||
|
if (spec == null || spec.type() == INVALID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!endpoint.getReturnType().equals(Response.class)) {
|
||||||
|
System.err.printf("invalid return type %s!\nskipping %s ...\n", endpoint.getReturnType().getSimpleName(), endpoint.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestType type = spec.type();
|
||||||
|
String location = spec.location();
|
||||||
|
HashMap<String, EndpointContainer> epMap = endpoints[type.id];
|
||||||
|
if (epMap.containsKey(location)) {
|
||||||
|
System.err.printf("HttpEndpoint for type %s and location \"%s\" is defined multiple times!\nskipping %s ...\n",
|
||||||
|
type.name(), location, endpoint.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter[] params = endpoint.getParameters();
|
||||||
|
if (params.length < 1 || !HttpExchange.class.equals(params[0].getType())) {
|
||||||
|
System.err.printf("HttpEndpoint must have HttpExchange as first parameter!\nskipping %s ...\n",
|
||||||
|
endpoint.getReturnType().getSimpleName(), endpoint.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
params = Arrays.stream(params).skip(1).toArray(Parameter[]::new);
|
||||||
|
|
||||||
|
Class<?>[] pTypes = Arrays.stream(params).map(p -> p.getType()).toArray(Class[]::new);
|
||||||
|
String[] pNames = new String[params.length];
|
||||||
|
String[] stringVals = new String[params.length];
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
QParam name = params[i].getAnnotation(QParam.class);
|
||||||
|
if (name == null) {
|
||||||
|
System.err.printf("missing QParam annotation!\nskipping %s ...\n", endpoint.getName());
|
||||||
|
continue endpointLoop;
|
||||||
|
}
|
||||||
|
pNames[i] = name.name();
|
||||||
|
stringVals[i] = name.empty();
|
||||||
|
}
|
||||||
|
Object[] pDefaults = new Object[pTypes.length];
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < pTypes.length; i++) {
|
||||||
|
pDefaults[i] = parseValue(pTypes[i], stringVals[i]);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.err.printf("encountered error setting up HttpEndpoint (%s)!\nskipping %s ...\n", e.getMessage(), endpoint.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Authorizer auth;
|
||||||
|
try {
|
||||||
|
auth = spec.auth().getConstructor().newInstance();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
System.err.printf("encountered error setting up HttpEndpoint (%s)!\nskipping %s ...\n", e.getMessage(), endpoint.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
epMap.put(location, new EndpointContainer(endpoint, auth, pTypes, pNames, pDefaults));
|
||||||
|
locations.add(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create appropriate contexts and headers
|
||||||
|
EndpointContainer default404;
|
||||||
|
try {
|
||||||
|
Method respond404 = HttpServerApi.class.getMethod("respond404", HttpExchange.class);
|
||||||
|
default404 = new EndpointContainer(respond404, new DefaultAuthorizer(), new Class<?>[0], new String[0], new Object[0]);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// this would be an error inside this class
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
for (String loc : locations) {
|
||||||
|
HttpContext context = server.createContext(rootLocation + loc);
|
||||||
|
context.setHandler(new HttpHandlerImpl(Arrays.stream(endpoints).map(e -> e.getOrDefault(loc, default404)).toArray(EndpointContainer[]::new)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/dev/asdf00/lib/httpserver/HttpServerApiUtils.java
Normal file
86
src/dev/asdf00/lib/httpserver/HttpServerApiUtils.java
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
package dev.asdf00.lib.httpserver;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Headers;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpPrincipal;
|
||||||
|
import dev.asdf00.lib.httpserver.exceptions.HttpHandlingException;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class HttpServerApiUtils {
|
||||||
|
|
||||||
|
private static ClassLoader clsldr = HttpServerApiUtils.class.getClassLoader();
|
||||||
|
|
||||||
|
public static Stream patchFile(Map<String, String> patchMap, InputStream file) {
|
||||||
|
return new BufferedReader(new InputStreamReader(file)).lines().map(line -> {
|
||||||
|
for (String patch : patchMap.keySet()) {
|
||||||
|
String fullPatch = "${" + patch + "}";
|
||||||
|
line = line.replace(fullPatch, patchMap.get(patch));
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream readResource(Path path) throws HttpHandlingException {
|
||||||
|
InputStream res;
|
||||||
|
try {
|
||||||
|
res = clsldr.getResourceAsStream(path.toString());
|
||||||
|
} catch (InvalidPathException e) {
|
||||||
|
throw new HttpHandlingException(400);
|
||||||
|
}
|
||||||
|
if (res == null) {
|
||||||
|
throw new HttpHandlingException(404);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printRequestInfo(HttpExchange exchange) {
|
||||||
|
System.out.println("\n-- headers --");
|
||||||
|
Headers requestHeaders = exchange.getRequestHeaders();
|
||||||
|
requestHeaders.entrySet().forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("-- principle --");
|
||||||
|
HttpPrincipal principal = exchange.getPrincipal();
|
||||||
|
System.out.println(principal);
|
||||||
|
|
||||||
|
System.out.println("-- HTTP method --");
|
||||||
|
String requestMethod = exchange.getRequestMethod();
|
||||||
|
System.out.println(requestMethod);
|
||||||
|
|
||||||
|
System.out.println("-- query --");
|
||||||
|
URI requestURI = exchange.getRequestURI();
|
||||||
|
String query = requestURI.getQuery();
|
||||||
|
System.out.println(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T parseValue(Class<T> type, String value) {
|
||||||
|
if (String.class.equals(type)) {
|
||||||
|
return (T) value;
|
||||||
|
} else if (byte.class.equals(type)) {
|
||||||
|
return (T) Byte.valueOf(value);
|
||||||
|
} else if (short.class.equals(type)) {
|
||||||
|
return (T) Short.valueOf(value);
|
||||||
|
} else if (int.class.equals(type)) {
|
||||||
|
return (T) Integer.valueOf(value);
|
||||||
|
} else if (long.class.equals(type)) {
|
||||||
|
return (T) Long.valueOf(value);
|
||||||
|
} else if (float.class.equals(type)) {
|
||||||
|
return (T) Float.valueOf(value);
|
||||||
|
} else if (double.class.equals(type)) {
|
||||||
|
return (T) Double.valueOf(value);
|
||||||
|
} else if (boolean.class.equals(type)) {
|
||||||
|
return (T) Boolean.valueOf(value);
|
||||||
|
} else if (char.class.equals(type)) {
|
||||||
|
if (value.length() < 1) {
|
||||||
|
throw new IllegalArgumentException("cannon convert empty string to char");
|
||||||
|
}
|
||||||
|
return (T) Character.valueOf(value.charAt(0));
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(type.getSimpleName() + " is not a primitive");
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/dev/asdf00/lib/httpserver/annotations/HttpEndpoint.java
Normal file
26
src/dev/asdf00/lib/httpserver/annotations/HttpEndpoint.java
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
package dev.asdf00.lib.httpserver.annotations;
|
||||||
|
|
||||||
|
import dev.asdf00.lib.httpserver.Authorizer;
|
||||||
|
import dev.asdf00.lib.httpserver.internal.DefaultAuthorizer;
|
||||||
|
import dev.asdf00.lib.httpserver.utils.RequestType;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface HttpEndpoint {
|
||||||
|
RequestType type();
|
||||||
|
|
||||||
|
String location();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum auth level required to access the given resource. If an auth level greater -1 is
|
||||||
|
* specified, the auth service is queried and the returned auth level is appended to the
|
||||||
|
* HttpExchange provided to this endpoint.<br/>
|
||||||
|
* default: don't care = -1
|
||||||
|
*/
|
||||||
|
Class<? extends Authorizer> auth() default DefaultAuthorizer.class;
|
||||||
|
}
|
||||||
14
src/dev/asdf00/lib/httpserver/annotations/QParam.java
Normal file
14
src/dev/asdf00/lib/httpserver/annotations/QParam.java
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dev.asdf00.lib.httpserver.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface QParam {
|
||||||
|
String name();
|
||||||
|
String empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.asdf00.lib.httpserver.exceptions;
|
||||||
|
|
||||||
|
public class HttpHandlingException extends Exception {
|
||||||
|
public final int statusCode;
|
||||||
|
public HttpHandlingException(int statusCode) {
|
||||||
|
super("Http Error " + statusCode);
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package dev.asdf00.lib.httpserver.internal;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import dev.asdf00.lib.httpserver.Authorizer;
|
||||||
|
|
||||||
|
public class DefaultAuthorizer implements Authorizer {
|
||||||
|
@Override
|
||||||
|
public boolean isAuthenticated(HttpExchange exchange) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package dev.asdf00.lib.httpserver.internal;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import dev.asdf00.lib.httpserver.Authorizer;
|
||||||
|
import dev.asdf00.lib.httpserver.exceptions.HttpHandlingException;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static dev.asdf00.lib.httpserver.HttpServerApiUtils.parseValue;
|
||||||
|
|
||||||
|
public class EndpointContainer {
|
||||||
|
public final Method handler;
|
||||||
|
public final Authorizer auth;
|
||||||
|
public final Class<?>[] pTypes;
|
||||||
|
public final String[] pNames;
|
||||||
|
public final Object[] pDefaults;
|
||||||
|
|
||||||
|
public EndpointContainer(Method handler, Authorizer auth, Class<?>[] pTypes, String[] paramNames, Object[] pDefaults) {
|
||||||
|
this.handler = handler;
|
||||||
|
this.auth = auth;
|
||||||
|
this.pTypes = pTypes;
|
||||||
|
this.pNames = paramNames;
|
||||||
|
this.pDefaults = pDefaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] parseOrDefaults(HttpExchange exchange, String values) throws HttpHandlingException {
|
||||||
|
String[] args;
|
||||||
|
if (values == null) {
|
||||||
|
args = new String[0];
|
||||||
|
} else {
|
||||||
|
args = values.split("&");
|
||||||
|
}
|
||||||
|
return parseOrDefaults(exchange, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] parseOrDefaults(HttpExchange exchange, String[] values) throws HttpHandlingException {
|
||||||
|
Object[] vals = new Object[pNames.length + 1];
|
||||||
|
vals[0] = exchange;
|
||||||
|
for (int i = 0; i < pNames.length; i++) {
|
||||||
|
vals[i + 1] = pDefaults[i];
|
||||||
|
for (int j = 0; j < values.length; j++) {
|
||||||
|
String[] split = values[j].split("=");
|
||||||
|
if (split.length < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pNames[i].equals(split[0])) {
|
||||||
|
try {
|
||||||
|
vals[i + 1] = parseValue(pTypes[i], split[1]);
|
||||||
|
break;
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
// skip assignment and use default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vals;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/dev/asdf00/lib/httpserver/internal/HttpHandlerImpl.java
Normal file
56
src/dev/asdf00/lib/httpserver/internal/HttpHandlerImpl.java
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
package dev.asdf00.lib.httpserver.internal;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import dev.asdf00.lib.httpserver.HttpServerApiUtils;
|
||||||
|
import dev.asdf00.lib.httpserver.exceptions.HttpHandlingException;
|
||||||
|
import dev.asdf00.lib.httpserver.utils.RequestType;
|
||||||
|
import dev.asdf00.lib.httpserver.utils.Response;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import static dev.asdf00.lib.httpserver.utils.RequestType.*;
|
||||||
|
|
||||||
|
public class HttpHandlerImpl implements HttpHandler {
|
||||||
|
private final EndpointContainer[] endpointContainer;
|
||||||
|
|
||||||
|
public HttpHandlerImpl(EndpointContainer... containers) {
|
||||||
|
endpointContainer = containers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(HttpExchange exchange) {
|
||||||
|
try {
|
||||||
|
RequestType type = RequestType.from(exchange.getRequestMethod());
|
||||||
|
if (type == INVALID) {
|
||||||
|
throw new HttpHandlingException(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndpointContainer target = endpointContainer[type.id];
|
||||||
|
if (!target.auth.isAuthenticated(exchange)) {
|
||||||
|
throw new HttpHandlingException(402);
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = exchange.getRequestURI().getQuery();
|
||||||
|
Object[] args = target.parseOrDefaults(exchange, query);
|
||||||
|
Response response = (Response) target.handler.invoke(null, args);
|
||||||
|
response.send();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof InvocationTargetException) {
|
||||||
|
e = (Exception) e.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
int errorCode = 500;
|
||||||
|
if (e instanceof HttpHandlingException) {
|
||||||
|
errorCode = ((HttpHandlingException) e).statusCode;
|
||||||
|
} else if (e instanceof IndexOutOfBoundsException) {
|
||||||
|
errorCode = 400;
|
||||||
|
}
|
||||||
|
Response r = new Response(exchange).status(errorCode).contentType(Response.ContentType.HTML);
|
||||||
|
r.append(String.format("<h1>ERROR %s</h1>\n", errorCode));
|
||||||
|
r.append(String.format("<p>something fucky is a foot!\n%s</p>", e.getMessage()));
|
||||||
|
r.send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/dev/asdf00/lib/httpserver/utils/RequestType.java
Normal file
25
src/dev/asdf00/lib/httpserver/utils/RequestType.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package dev.asdf00.lib.httpserver.utils;
|
||||||
|
|
||||||
|
|
||||||
|
public enum RequestType {
|
||||||
|
INVALID(-1),
|
||||||
|
GET(0),
|
||||||
|
POST(1),
|
||||||
|
DELETE(2);
|
||||||
|
|
||||||
|
public final int id;
|
||||||
|
RequestType(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestType from(String parse) {
|
||||||
|
if ("GET".equals(parse)) {
|
||||||
|
return GET;
|
||||||
|
} else if ("POST".equals(parse)) {
|
||||||
|
return POST;
|
||||||
|
} else if ("DELETE".equals(parse)) {
|
||||||
|
return DELETE;
|
||||||
|
}
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/dev/asdf00/lib/httpserver/utils/Response.java
Normal file
74
src/dev/asdf00/lib/httpserver/utils/Response.java
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
package dev.asdf00.lib.httpserver.utils;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import dev.asdf00.lib.httpserver.HttpServerApiUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Response {
|
||||||
|
public enum ContentType {
|
||||||
|
PLAIN("text/plain"),
|
||||||
|
HTML("text/html"),
|
||||||
|
JS("text/javascript");
|
||||||
|
private final String type;
|
||||||
|
ContentType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int statusCode = 500;
|
||||||
|
private ContentType cType = ContentType.PLAIN;
|
||||||
|
private final HttpExchange exchange;
|
||||||
|
private final StringBuilder response;
|
||||||
|
|
||||||
|
public Response(HttpExchange exchange) {
|
||||||
|
this.exchange = exchange;
|
||||||
|
response = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response status(int code) {
|
||||||
|
statusCode = code;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response contentType(ContentType type) {
|
||||||
|
cType = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response append(String line) {
|
||||||
|
response.append(line);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response append(StringBuilder line) {
|
||||||
|
response.append(line);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response append(Stream line) {
|
||||||
|
response.append(line.collect(Collectors.joining("\n")));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response append(InputStream line) {
|
||||||
|
response.append(new BufferedReader(new InputStreamReader(line)).lines().collect(Collectors.joining("\n")));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean send() {
|
||||||
|
try {
|
||||||
|
exchange.getResponseHeaders().add("Content-type", cType.type);
|
||||||
|
exchange.sendResponseHeaders(statusCode, response.length());
|
||||||
|
try (OutputStream os = exchange.getResponseBody()) {
|
||||||
|
os.write(response.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user