diff options
author | davidovski <david@sendula.com> | 2022-11-30 10:06:56 +0000 |
---|---|---|
committer | davidovski <david@sendula.com> | 2022-11-30 10:06:56 +0000 |
commit | 290c68795d8100cc97b8b53d80f331e536fc71b1 (patch) | |
tree | bf0068c4c9121406df9bc90f5c159fd93de8a61e /src/webserver/src |
Diffstat (limited to 'src/webserver/src')
4 files changed, 323 insertions, 0 deletions
diff --git a/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java b/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java new file mode 100644 index 0000000..5ef2cfe --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/APIRequestHandler.java @@ -0,0 +1,112 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class APIRequestHandler implements HttpHandler { + + private NameDatabaseManager nameDatabaseManager; + + public APIRequestHandler() { + nameDatabaseManager = new NameDatabaseManager(new File("names.db")); + } + + @Override + public void handle(HttpExchange exchange) throws IOException { + // get the requested path + String path = exchange.getRequestURI().getPath(); + + System.out.println(path); + + if (path.startsWith("/api/name")) { + + // parse the body as a json object + JSONTokener jsonParser = new JSONTokener(exchange.getRequestBody()); + JSONObject json = (JSONObject) jsonParser.nextValue(); + + System.out.println(json.toString(2)); + + if (json == null) { + // Malformed JSON request, 400 + sendJSON(exchange, (new JSONObject()).put("message", "Malformed JSON body"), 400); + return; + } + + // generate name(s) and send it + generateName(exchange, json); + } else { + sendJSON(exchange, (new JSONObject()).put("message", "Not Found"), 404); + } + } + + public void generateName(HttpExchange exchange, JSONObject options) throws JSONException, IOException { + String origin = options.optString("origin", "none").toLowerCase(); + + int count = options.optInt("count", 1); + + // ensure that the count is between 1-100 + if (count < 1 || count > 100) { + sendJSON(exchange, (new JSONObject()).put("message", "Name count is out of range: Ensure that the request is between 1 and 100 names"), 400); + return; + } + + String gender = options.optString("gender", "female"); + + // ensure that the gender is either male or female + if (!gender.equals("male") && !gender.equals("female")) { + sendJSON(exchange, (new JSONObject()).put("message", "Requested gender is invalid"), 400); + return; + } + + // Store the names in an array + List<String> names = nameDatabaseManager.getRandomNames(origin, gender, count); + + if (options.optBoolean("surname")) { + List<String> surnames = nameDatabaseManager.getRandomNames(origin, "surname", count); + + // Add surnames to the end of each firstname in the names list + for (int i = 0; i < count; i++) { + String fullname = names.get(i) + " " + surnames.get(i); + names.set(i, fullname); + } + } + + // Create the response json object + JSONObject response = new JSONObject(); + response.put("message", "Generated " + count + " names"); + response.put("names", new JSONArray(names)); + + // send the json back to the client + sendJSON(exchange, response, 200); + } + + public void sendJSON(HttpExchange exchange, JSONObject json, int responseCode) throws IOException { + // convert the json to a string + String response = json.toString(2); + + // calculate the response content size + int contentSize = response.toString().getBytes().length; + + // set the response headers + exchange.getResponseHeaders().add("Content-Type", "text/json"); + exchange.sendResponseHeaders(responseCode, contentSize); + + // write the response to the output stream + OutputStream outputStream = exchange.getResponseBody(); + + outputStream.write(response.toString().getBytes()); + outputStream.close(); + } + +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java b/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java new file mode 100644 index 0000000..8822d9c --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/NameDatabaseManager.java @@ -0,0 +1,75 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class NameDatabaseManager { + private File databaseFile; + private Connection connection; + + private static final String TABLE = "names"; + + public NameDatabaseManager(File databaseFile) { + this.databaseFile = databaseFile; + + connect(); + } + + /** + * Creates a connection to the database. If one could not be created, the connection will remain as null + */ + private void connect() { + connection = null; + try { + connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getPath()); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public List<String> getRandomNames(String origin, String category, int quantitiy) { + // create the set to return, even if empty + List<String> names = new ArrayList<String>(); + + if (connection != null) { + // Create an sql statement + String sql = "SELECT Name FROM " + TABLE + " WHERE Origin=? AND Category=? ORDER BY RANDOM() LIMIT ?;"; + PreparedStatement statement; + try { + statement = connection.prepareStatement(sql); + + // insert relevant values into the statement + statement.setString(1, origin); + statement.setString(2, category); + statement.setInt(3, quantitiy); + + // execute the query and get the result + ResultSet result = statement.executeQuery(); + + // Add all of the results to the names set + while (result.next()) { + String name = result.getString("Name"); + names.add(name); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + } + return names; + } + + public static void main(String[] args) { + NameDatabaseManager dbManager = new NameDatabaseManager(new File("names.db")); + List<String> names = dbManager.getRandomNames("spain", "female", 10); + for (String name : names) { + System.out.println(name); + } + } +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java b/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java new file mode 100644 index 0000000..d10d0b1 --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/StaticRequestHandler.java @@ -0,0 +1,85 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class StaticRequestHandler implements HttpHandler { + private File root; + + public StaticRequestHandler(File root) { + this.root = root; + } + + @Override + public void handle(HttpExchange exchange) throws IOException { + // get the requested path + String path = exchange.getRequestURI().getPath(); + + File requested = new File(root, path); + + // automatically send the index of a directory + if (requested.isDirectory()) { + requested = new File(requested, "index.html"); + } + + // ensure that the file is in the intended document root + if (!isInRoot(requested, root)) { + sendText(exchange, "Access Denied", 403); + } else if (requested.exists()) { + sendFile(exchange, requested); + } else { + // send 404 if the file isnt found + sendText(exchange, "File Not Found", 404); + } + } + + private void sendFile(HttpExchange exchange, File file) throws IOException { + // read the file as into an array of bytes + byte[] bytes = Files.readAllBytes(file.toPath()); + + // send the file headers + exchange.sendResponseHeaders(200, bytes.length); + + // send the file body + OutputStream os = exchange.getResponseBody(); + os.write(bytes); + os.close(); + } + + private void sendText(HttpExchange exchange, String response, int responseCode) throws IOException { + // calculate the response content size + int contentSize = response.toString().getBytes().length; + + // set the response headers + exchange.getResponseHeaders().add("Content-Type", "text/json"); + exchange.sendResponseHeaders(responseCode, contentSize); + + // write the response to the output stream + OutputStream outputStream = exchange.getResponseBody(); + + outputStream.write(response.toString().getBytes()); + outputStream.close(); + } + + public static boolean isInRoot(File request, File root) { + File parentFile = request; + + // start from the requested file and traverse upwards until reaching the root directory + while (parentFile != null) { + if (root.equals(parentFile)) { + return true; + } + parentFile = parentFile.getParentFile(); + } + + // If there isn't a parent file, return false + return false; + } + +} diff --git a/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java b/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java new file mode 100644 index 0000000..60b311f --- /dev/null +++ b/src/webserver/src/main/java/io/github/davidovski/names/WebServer.java @@ -0,0 +1,51 @@ +package io.github.davidovski.names; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.sun.net.httpserver.HttpServer; + +@SuppressWarnings("restriction") +public class WebServer { + private int port; + private HttpServer server; + + public WebServer(int port) throws IOException { + this.port = port; + + // create an HTTP server instance + InetSocketAddress socketAddress = new InetSocketAddress(port); + server = HttpServer.create(socketAddress, 0); + + // create a context for the static request handler + server.createContext("/", new StaticRequestHandler(new File("dist"))); + // create a context for the api request handler + server.createContext("/api", new APIRequestHandler()); + + } + + public void start() { + server.start(); + + // tell the user that the webserver has been started, and the port used + System.out.println("Webserver started on port " + port); + } + + + public static void main(String[] args) throws IOException { + + // set a default port number + int port = 8080; + + // parse the arguments for a port number + if (args.length > 0) + port = Integer.parseInt(args[0]); + + // Create the webserver instance + WebServer webServer = new WebServer(port); + + // start the webserver + webServer.start(); + } +} |