basic http server
~3h work
This commit is contained in:
parent
19a2d9bbb2
commit
765af93728
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### 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
|
||||
.idea/
|
||||
11
mtcg.iml
Normal file
11
mtcg.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>
|
||||
12
src/Main.java
Normal file
12
src/Main.java
Normal file
@ -0,0 +1,12 @@
|
||||
import at.nanopenguin.mtcg.http.Router;
|
||||
import at.nanopenguin.mtcg.http.Server;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("Hello world!");
|
||||
Server server = new Server(10001, 10, new Router());
|
||||
server.start();
|
||||
}
|
||||
}
|
||||
23
src/at/nanopenguin/mtcg/http/HttpStatus.java
Normal file
23
src/at/nanopenguin/mtcg/http/HttpStatus.java
Normal file
@ -0,0 +1,23 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
public enum HttpStatus {
|
||||
OK(200, "OK"),
|
||||
CREATED(201, "Created"),
|
||||
NO_CONTENT(204, "No Content"),
|
||||
BAD_REQUEST(400, "Bad Request"),
|
||||
UNAUTHORIZED(401, "Unauthorized"),
|
||||
FORBIDDEN(403, "Forbidden"),
|
||||
NOT_FOUND(404, "Not Found"),
|
||||
CONFLICT(409, "Conflict"),
|
||||
TEAPOT(418, "I'm a teapot"),
|
||||
INTERNAL(500, "Internal Server Error"),
|
||||
NOT_IMPLEMENTED(501, "Not Implemented");
|
||||
|
||||
public final int statusCode;
|
||||
public final String statusMessage;
|
||||
|
||||
HttpStatus(int code, String message) {
|
||||
this.statusCode = code;
|
||||
this.statusMessage = message;
|
||||
}
|
||||
}
|
||||
31
src/at/nanopenguin/mtcg/http/RequestHandler.java
Normal file
31
src/at/nanopenguin/mtcg/http/RequestHandler.java
Normal file
@ -0,0 +1,31 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
public class RequestHandler implements Runnable {
|
||||
private final Socket serviceSocket;
|
||||
private final Router router;
|
||||
private BufferedReader br;
|
||||
private OutputStream out;
|
||||
|
||||
public RequestHandler(Socket serviceSocket, Router router) {
|
||||
this.serviceSocket = serviceSocket;
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Response response = new Response(HttpStatus.OK, "application/json", "[]");
|
||||
|
||||
this.out = this.serviceSocket.getOutputStream();
|
||||
out.write(response.get().getBytes());
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/at/nanopenguin/mtcg/http/Response.java
Normal file
31
src/at/nanopenguin/mtcg/http/Response.java
Normal file
@ -0,0 +1,31 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class Response {
|
||||
private final HttpStatus httpStatus;
|
||||
private final String contentType;
|
||||
private final String content;
|
||||
|
||||
public Response(HttpStatus httpStatus, String contentType, String content) {
|
||||
this.httpStatus = httpStatus;
|
||||
this.contentType = contentType;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
|
||||
String localDatetime = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneId.of("UTC")));
|
||||
return "HTTP/1.1 " + this.httpStatus.statusCode + " " + this.httpStatus.statusMessage + "\r\n" +
|
||||
"Cache-Control: max-age=0\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Date: " + localDatetime + "\r\n" +
|
||||
"Expires: " + localDatetime + "\r\n" +
|
||||
"Content-Type: " + this.contentType + "\r\n" +
|
||||
"Content-Length: " + this.content.length() + "\r\n" +
|
||||
"\r\n" +
|
||||
this.content;
|
||||
}
|
||||
}
|
||||
4
src/at/nanopenguin/mtcg/http/Router.java
Normal file
4
src/at/nanopenguin/mtcg/http/Router.java
Normal file
@ -0,0 +1,4 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
public class Router {
|
||||
}
|
||||
36
src/at/nanopenguin/mtcg/http/Server.java
Normal file
36
src/at/nanopenguin/mtcg/http/Server.java
Normal file
@ -0,0 +1,36 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class Server {
|
||||
private final int port; // 16-bit unsigned, not enforced
|
||||
private final int threads;
|
||||
private final Router router;
|
||||
|
||||
public Server(int port, int threads, Router router) {
|
||||
this.port = port;
|
||||
this.threads = threads;
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
try (ServerSocket listener = new ServerSocket(this.port)) {
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(this.threads);
|
||||
|
||||
System.out.println("HTTP server running on http://localhost:" + this.port);
|
||||
|
||||
while (true) {
|
||||
final Socket serviceSocket = listener.accept();
|
||||
final RequestHandler requestHandler = new RequestHandler(serviceSocket, this.router);
|
||||
|
||||
executorService.submit(requestHandler);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user