From 11649a632cfa6ae224f99bdc32ec99ecac19245a Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 24 Jun 2020 09:32:00 +0900 Subject: [PATCH 01/65] =?UTF-8?q?main()=20=EC=95=84=EA=B7=9C=EB=A8=BC?= =?UTF-8?q?=ED=8A=B8=20java=20=EC=8A=A4=ED=83=80=EC=9D=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/WebServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/webserver/WebServer.java b/src/main/java/webserver/WebServer.java index 91f4a0fbc..3a34f98db 100644 --- a/src/main/java/webserver/WebServer.java +++ b/src/main/java/webserver/WebServer.java @@ -10,8 +10,8 @@ public class WebServer { private static final Logger log = LoggerFactory.getLogger(WebServer.class); private static final int DEFAULT_PORT = 8080; - public static void main(String args[]) throws Exception { - int port = 0; + public static void main(String[] args) throws Exception { + int port; if (args == null || args.length == 0) { port = DEFAULT_PORT; } else { From b03c59360717e9f83b89e7d1164bbb753d4eaeae Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 24 Jun 2020 22:53:00 +0900 Subject: [PATCH 02/65] =?UTF-8?q?webapp=20=EB=94=94=EB=A0=89=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20=ED=95=98=EC=9C=84=EC=97=90=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=ED=8C=8C=EC=9D=BC=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=8B=9C=EC=97=90=20=ED=95=B4=EB=8B=B9=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 42 +++++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 90195ec4e..82eab0fae 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,10 +1,11 @@ package webserver; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.net.Socket; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,7 +13,7 @@ public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); - private Socket connection; + private final Socket connection; public RequestHandler(Socket connectionSocket) { this.connection = connectionSocket; @@ -22,10 +23,37 @@ public void run() { log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort()); - try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { + try (InputStream in = connection.getInputStream(); + OutputStream out = connection.getOutputStream()) { // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + Map requestMessage = new HashMap<>(); + String line; + while (!"".equals(line = bufferedReader.readLine())) { + if (Objects.isNull(line)) { + break; + } + + if (requestMessage.isEmpty()) { + final String[] s = line.split(" "); + requestMessage.put("Method", s[0]); + requestMessage.put("Path", s[1]); + requestMessage.put("Version", s[2]); + continue; + } + + final int i = line.indexOf(":"); + requestMessage.put(line.substring(0, i), line.substring(i + 2)); + } + + for (Map.Entry stringStringEntry : requestMessage.entrySet()) { + log.info("key '{}' value '{}'", stringStringEntry.getKey(), stringStringEntry.getValue()); + } + + final byte[] body = Files.readAllBytes(new File("./webapp" + requestMessage.get("Path")).toPath()); + DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); +// byte[] body = "Hello World".getBytes(); response200Header(dos, body.length); responseBody(dos, body); } catch (IOException e) { From ebaf4478ec4c2bf4c35c0da61762b5fbb29e5bea Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 07:18:57 +0900 Subject: [PATCH 03/65] =?UTF-8?q?Junit=20=EB=B2=84=EC=A0=84=205=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 ++++++++++--- src/test/java/util/HttpRequestUtilsTest.java | 5 ++--- src/test/java/util/IOUtilsTest.java | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index a98034b22..354b44d61 100644 --- a/pom.xml +++ b/pom.xml @@ -14,9 +14,16 @@ - junit - junit - 4.11 + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + + org.junit.vintage + junit-vintage-engine + 5.6.2 test diff --git a/src/test/java/util/HttpRequestUtilsTest.java b/src/test/java/util/HttpRequestUtilsTest.java index a4265f5e7..7a955d97a 100644 --- a/src/test/java/util/HttpRequestUtilsTest.java +++ b/src/test/java/util/HttpRequestUtilsTest.java @@ -1,12 +1,11 @@ package util; import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.MatcherAssert.*; import java.util.Map; -import org.junit.Test; - +import org.junit.jupiter.api.Test; import util.HttpRequestUtils.Pair; public class HttpRequestUtilsTest { diff --git a/src/test/java/util/IOUtilsTest.java b/src/test/java/util/IOUtilsTest.java index 3c00cc4fa..eb8812be6 100644 --- a/src/test/java/util/IOUtilsTest.java +++ b/src/test/java/util/IOUtilsTest.java @@ -3,7 +3,7 @@ import java.io.BufferedReader; import java.io.StringReader; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; From eb2ee7a9399ded8e596cef939347d78de5870708 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:21:55 +0900 Subject: [PATCH 04/65] =?UTF-8?q?Controller=20=EC=9D=B8=ED=84=B0=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=EC=99=80=20index.html=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=ED=95=98=EB=8A=94=20MainController=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 9 +++ src/main/java/controller/MainController.java | 68 ++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/main/java/controller/Controller.java create mode 100644 src/main/java/controller/MainController.java diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java new file mode 100644 index 000000000..1e2ef154b --- /dev/null +++ b/src/main/java/controller/Controller.java @@ -0,0 +1,9 @@ +package controller; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public interface Controller { + void process(InputStream in, OutputStream out) throws IOException; +} diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java new file mode 100644 index 000000000..1c4811a07 --- /dev/null +++ b/src/main/java/controller/MainController.java @@ -0,0 +1,68 @@ +package controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import webserver.RequestHandler; + +import java.io.*; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class MainController implements Controller{ + private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + @Override + public void process(InputStream in, OutputStream out) throws IOException { + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + Map requestMessage = new HashMap<>(); + String line; + while (!"".equals(line = bufferedReader.readLine())) { + if (Objects.isNull(line)) { + break; + } + + if (requestMessage.isEmpty()) { + final String[] s = line.split(" "); + requestMessage.put("Method", s[0]); + requestMessage.put("Path", s[1]); + requestMessage.put("Version", s[2]); + continue; + } + + final int i = line.indexOf(":"); + requestMessage.put(line.substring(0, i), line.substring(i + 2)); + } + + for (Map.Entry stringStringEntry : requestMessage.entrySet()) { + log.info("key '{}' value '{}'", stringStringEntry.getKey(), stringStringEntry.getValue()); + } + + final byte[] body = Files.readAllBytes(new File("./webapp" + requestMessage.get("Path")).toPath()); + + DataOutputStream dos = new DataOutputStream(out); + response200Header(dos, body.length); + responseBody(dos, body); + } + + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void responseBody(DataOutputStream dos, byte[] body) { + try { + dos.write(body, 0, body.length); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} From f1fc1ad110bc45c7f222dbc03396a5ee55d69bbf Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:22:35 +0900 Subject: [PATCH 05/65] =?UTF-8?q?RequestHandler=EA=B0=80=20Controller?= =?UTF-8?q?=EC=97=90=20=EC=9D=98=EC=A1=B4=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 55 ++------------------- 1 file changed, 4 insertions(+), 51 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 82eab0fae..0ae20be61 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -7,6 +7,8 @@ import java.util.Map; import java.util.Objects; +import controller.Controller; +import controller.MainController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,57 +27,8 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); - Map requestMessage = new HashMap<>(); - String line; - while (!"".equals(line = bufferedReader.readLine())) { - if (Objects.isNull(line)) { - break; - } - - if (requestMessage.isEmpty()) { - final String[] s = line.split(" "); - requestMessage.put("Method", s[0]); - requestMessage.put("Path", s[1]); - requestMessage.put("Version", s[2]); - continue; - } - - final int i = line.indexOf(":"); - requestMessage.put(line.substring(0, i), line.substring(i + 2)); - } - - for (Map.Entry stringStringEntry : requestMessage.entrySet()) { - log.info("key '{}' value '{}'", stringStringEntry.getKey(), stringStringEntry.getValue()); - } - - final byte[] body = Files.readAllBytes(new File("./webapp" + requestMessage.get("Path")).toPath()); - - DataOutputStream dos = new DataOutputStream(out); -// byte[] body = "Hello World".getBytes(); - response200Header(dos, body.length); - responseBody(dos, body); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { - try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, body.length); - dos.flush(); + Controller c = new MainController(); + c.process(in, out); } catch (IOException e) { log.error(e.getMessage()); } From bcfc4e383fde272fabfd3019e7f2994ee4e380f7 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:30:03 +0900 Subject: [PATCH 06/65] =?UTF-8?q?process()=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20InputStream=20->=20Map=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 3 ++- src/main/java/controller/MainController.java | 28 ++------------------ 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 1e2ef154b..156b7680a 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -3,7 +3,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Map; public interface Controller { - void process(InputStream in, OutputStream out) throws IOException; + void process(Map requestInfo, OutputStream out) throws IOException; } diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java index 1c4811a07..db6d951df 100644 --- a/src/main/java/controller/MainController.java +++ b/src/main/java/controller/MainController.java @@ -14,32 +14,8 @@ public class MainController implements Controller{ private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @Override - public void process(InputStream in, OutputStream out) throws IOException { - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); - Map requestMessage = new HashMap<>(); - String line; - while (!"".equals(line = bufferedReader.readLine())) { - if (Objects.isNull(line)) { - break; - } - - if (requestMessage.isEmpty()) { - final String[] s = line.split(" "); - requestMessage.put("Method", s[0]); - requestMessage.put("Path", s[1]); - requestMessage.put("Version", s[2]); - continue; - } - - final int i = line.indexOf(":"); - requestMessage.put(line.substring(0, i), line.substring(i + 2)); - } - - for (Map.Entry stringStringEntry : requestMessage.entrySet()) { - log.info("key '{}' value '{}'", stringStringEntry.getKey(), stringStringEntry.getValue()); - } - - final byte[] body = Files.readAllBytes(new File("./webapp" + requestMessage.get("Path")).toPath()); + public void process(Map requestInfo, OutputStream out) throws IOException { + final byte[] body = Files.readAllBytes(new File("./webapp" + requestInfo.get("Path")).toPath()); DataOutputStream dos = new DataOutputStream(out); response200Header(dos, body.length); From d14f2956cb8118b3f4f7aca210701475d87cce32 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:41:36 +0900 Subject: [PATCH 07/65] =?UTF-8?q?=EC=A0=95=EC=A0=81=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20DefaultController=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/DefaultController.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/controller/DefaultController.java diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java new file mode 100644 index 000000000..b465f51b5 --- /dev/null +++ b/src/main/java/controller/DefaultController.java @@ -0,0 +1,45 @@ +package controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import webserver.RequestHandler; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Map; + +public class DefaultController implements Controller{ + private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + @Override + public void process(Map requestInfo, OutputStream out) throws IOException { + final byte[] body = Files.readAllBytes(new File("./webapp" + requestInfo.get("Path")).toPath()); + + DataOutputStream dos = new DataOutputStream(out); + response200Header(dos, body.length); + responseBody(dos, body); + } + + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void responseBody(DataOutputStream dos, byte[] body) { + try { + dos.write(body, 0, body.length); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} From 5f297e0b4433c4348dfb63e2a782d82198cc377d Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:42:31 +0900 Subject: [PATCH 08/65] =?UTF-8?q?Path=EC=97=90=20=EB=A7=9E=EB=8A=94=20Cont?= =?UTF-8?q?roller=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20Constr?= =?UTF-8?q?uctor=20=EC=83=9D=EC=84=B1,=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 21 +++++++++++++++ src/main/java/controller/MainController.java | 9 ++++--- src/main/java/webserver/RequestHandler.java | 27 +++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 src/main/java/controller/ControllerConstructor.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java new file mode 100644 index 000000000..795c34c6f --- /dev/null +++ b/src/main/java/controller/ControllerConstructor.java @@ -0,0 +1,21 @@ +package controller; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class ControllerConstructor { + private final static Map pathAndControllers = new HashMap<>(); + static { + pathAndControllers.put("/", new MainController()); + pathAndControllers.put("/index.html", new MainController()); + } + + public static Controller getController(String path) { + final Controller controller = pathAndControllers.get(path); + if (Objects.isNull(controller)) { + return new DefaultController(); + } + return controller; + } +} diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java index db6d951df..ebfa0721f 100644 --- a/src/main/java/controller/MainController.java +++ b/src/main/java/controller/MainController.java @@ -4,18 +4,19 @@ import org.slf4j.LoggerFactory; import webserver.RequestHandler; -import java.io.*; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Files; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; public class MainController implements Controller{ private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @Override public void process(Map requestInfo, OutputStream out) throws IOException { - final byte[] body = Files.readAllBytes(new File("./webapp" + requestInfo.get("Path")).toPath()); + final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); DataOutputStream dos = new DataOutputStream(out); response200Header(dos, body.length); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 0ae20be61..f7bb923cd 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -8,6 +8,7 @@ import java.util.Objects; import controller.Controller; +import controller.ControllerConstructor; import controller.MainController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,8 +28,30 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - Controller c = new MainController(); - c.process(in, out); + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + Map requestInfo = new HashMap<>(); + String line; + while (!"".equals(line = bufferedReader.readLine())) { + if (Objects.isNull(line)) { + break; + } + + if (requestInfo.isEmpty()) { + final String[] s = line.split(" "); + requestInfo.put("Method", s[0]); + requestInfo.put("Path", s[1]); + requestInfo.put("Version", s[2]); + continue; + } + + final int i = line.indexOf(":"); + requestInfo.put(line.substring(0, i), line.substring(i + 2)); + } + + log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); + + Controller c = ControllerConstructor.getController(requestInfo.get("Path")); + c.process(requestInfo, out); } catch (IOException e) { log.error(e.getMessage()); } From 6151bc855aa0992741c619bf65b73290740f0935 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:50:22 +0900 Subject: [PATCH 09/65] =?UTF-8?q?Controller=20=EC=8B=B1=EA=B8=80=ED=86=A4?= =?UTF-8?q?=20=EA=B0=9D=EC=B2=B4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/ControllerConstructor.java | 6 +++--- src/main/java/controller/DefaultController.java | 7 +++++++ src/main/java/controller/MainController.java | 9 ++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 795c34c6f..b6f3139bf 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -7,14 +7,14 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { - pathAndControllers.put("/", new MainController()); - pathAndControllers.put("/index.html", new MainController()); + pathAndControllers.put("/", MainController.getInstance()); + pathAndControllers.put("/index.html", MainController.getInstance()); } public static Controller getController(String path) { final Controller controller = pathAndControllers.get(path); if (Objects.isNull(controller)) { - return new DefaultController(); + return DefaultController.getInstance(); } return controller; } diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index b465f51b5..0d8229249 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -12,8 +12,15 @@ import java.util.Map; public class DefaultController implements Controller{ + private static final Controller instance = new DefaultController(); private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + private DefaultController() {} + + public static Controller getInstance() { + return instance; + } + @Override public void process(Map requestInfo, OutputStream out) throws IOException { final byte[] body = Files.readAllBytes(new File("./webapp" + requestInfo.get("Path")).toPath()); diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java index ebfa0721f..bcfc17998 100644 --- a/src/main/java/controller/MainController.java +++ b/src/main/java/controller/MainController.java @@ -11,9 +11,16 @@ import java.nio.file.Files; import java.util.Map; -public class MainController implements Controller{ +public class MainController implements Controller { + private static final Controller instance = new MainController(); private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + private MainController() {} + + public static Controller getInstance() { + return instance; + } + @Override public void process(Map requestInfo, OutputStream out) throws IOException { final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); From 4ca975241e83929b2671d392b4576d2800739c83 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 09:54:07 +0900 Subject: [PATCH 10/65] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/ControllerConstructor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index b6f3139bf..c00e7b3a9 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -8,7 +8,6 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { pathAndControllers.put("/", MainController.getInstance()); - pathAndControllers.put("/index.html", MainController.getInstance()); } public static Controller getController(String path) { From a75390d55d8844d3b9ef30e1f4b563a736e03c0a Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 10:07:27 +0900 Subject: [PATCH 11/65] =?UTF-8?q?Controller=20=EC=A0=91=EA=B7=BC=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 2 +- src/main/java/controller/MainController.java | 2 +- src/main/java/webserver/RequestHandler.java | 12 +++++------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 0d8229249..00ff77a25 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -11,7 +11,7 @@ import java.nio.file.Files; import java.util.Map; -public class DefaultController implements Controller{ +class DefaultController implements Controller{ private static final Controller instance = new DefaultController(); private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java index bcfc17998..1084ca3c2 100644 --- a/src/main/java/controller/MainController.java +++ b/src/main/java/controller/MainController.java @@ -11,7 +11,7 @@ import java.nio.file.Files; import java.util.Map; -public class MainController implements Controller { +class MainController implements Controller { private static final Controller instance = new MainController(); private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index f7bb923cd..9046a3986 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,18 +1,16 @@ package webserver; +import controller.Controller; +import controller.ControllerConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.*; import java.net.Socket; -import java.nio.file.Files; import java.util.HashMap; import java.util.Map; import java.util.Objects; -import controller.Controller; -import controller.ControllerConstructor; -import controller.MainController; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); From 8bac4b2df190a2cead958e91c4f01ba142cce8a1 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 10:19:29 +0900 Subject: [PATCH 12/65] =?UTF-8?q?InputStream=EC=9D=84=20RequestInfo?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=94=EA=BE=B8=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?Uitls=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/util/HttpRequestUtils.java | 30 +++++++++++++++++++++ src/main/java/webserver/RequestHandler.java | 25 +++-------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main/java/util/HttpRequestUtils.java b/src/main/java/util/HttpRequestUtils.java index c4cd95c0d..cb5eb2a5a 100644 --- a/src/main/java/util/HttpRequestUtils.java +++ b/src/main/java/util/HttpRequestUtils.java @@ -1,7 +1,13 @@ package util; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import com.google.common.base.Strings; @@ -106,4 +112,28 @@ public String toString() { return "Pair [key=" + key + ", value=" + value + "]"; } } + + public static Map getRequestInfoFrom(InputStream in) throws IOException { + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + Map requestInfo = new HashMap<>(); + String line; + while (!"".equals(line = bufferedReader.readLine())) { + if (Objects.isNull(line)) { + break; + } + + if (requestInfo.isEmpty()) { + final String[] s = line.split(" "); + requestInfo.put("Method", s[0]); + requestInfo.put("Path", s[1]); + requestInfo.put("Version", s[2]); + continue; + } + + final int i = line.indexOf(":"); + requestInfo.put(line.substring(0, i), line.substring(i + 2)); + } + + return requestInfo; + } } diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 9046a3986..d21b628dd 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -7,9 +7,9 @@ import java.io.*; import java.net.Socket; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; + +import static util.HttpRequestUtils.getRequestInfoFrom; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -26,26 +26,7 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); - Map requestInfo = new HashMap<>(); - String line; - while (!"".equals(line = bufferedReader.readLine())) { - if (Objects.isNull(line)) { - break; - } - - if (requestInfo.isEmpty()) { - final String[] s = line.split(" "); - requestInfo.put("Method", s[0]); - requestInfo.put("Path", s[1]); - requestInfo.put("Version", s[2]); - continue; - } - - final int i = line.indexOf(":"); - requestInfo.put(line.substring(0, i), line.substring(i + 2)); - } - + Map requestInfo = getRequestInfoFrom(in); log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); Controller c = ControllerConstructor.getController(requestInfo.get("Path")); From d786159151e2f511fdd4f06a0aa7c6bb94c5ecd7 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 10:23:59 +0900 Subject: [PATCH 13/65] =?UTF-8?q?LoggerFactorry=20class=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 2 +- src/main/java/controller/MainController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 00ff77a25..d4a36465b 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -13,7 +13,7 @@ class DefaultController implements Controller{ private static final Controller instance = new DefaultController(); - private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + private static final Logger log = LoggerFactory.getLogger(DefaultController.class); private DefaultController() {} diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java index 1084ca3c2..89ddcdbbf 100644 --- a/src/main/java/controller/MainController.java +++ b/src/main/java/controller/MainController.java @@ -13,7 +13,7 @@ class MainController implements Controller { private static final Controller instance = new MainController(); - private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + private static final Logger log = LoggerFactory.getLogger(MainController.class); private MainController() {} From 1d1272e7472a21f05e0ff076b7916fdd744c7c8d Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 10:55:32 +0900 Subject: [PATCH 14/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD2=20G?= =?UTF-8?q?ET=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 7 +++ .../java/controller/UserCreateController.java | 63 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/main/java/controller/UserCreateController.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index c00e7b3a9..e8aa51613 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -8,13 +8,20 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { pathAndControllers.put("/", MainController.getInstance()); + pathAndControllers.put("/user/create", UserCreateController.getInstance()); } public static Controller getController(String path) { + if (path.contains("?")) { + path = path.split("\\?")[0]; + } + final Controller controller = pathAndControllers.get(path); + if (Objects.isNull(controller)) { return DefaultController.getInstance(); } + return controller; } } diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java new file mode 100644 index 000000000..fc2a6b1d5 --- /dev/null +++ b/src/main/java/controller/UserCreateController.java @@ -0,0 +1,63 @@ +package controller; + +import db.DataBase; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import webserver.RequestHandler; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Map; + +import static util.HttpRequestUtils.parseQueryString; + +class UserCreateController implements Controller { + private static final Controller instance = new UserCreateController(); + private static final Logger log = LoggerFactory.getLogger(UserCreateController.class); + + private UserCreateController() {} + + public static Controller getInstance() { + return instance; + } + + @Override + public void process(Map requestInfo, OutputStream out) throws IOException { + final String path = requestInfo.get("Path"); + final Map queryString = parseQueryString(path.split("\\?")[1]); + User newUser = new User(queryString.get("userId"), queryString.get("password"), queryString.get("name"), queryString.get("email")); + + log.info("Create User: {}", newUser.toString()); + DataBase.addUser(newUser); + + final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); + + final DataOutputStream dos = new DataOutputStream(out); + response200Header(dos, 0); + responseBody(dos, null); + } + + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void responseBody(DataOutputStream dos, byte[] body) { + try { + dos.write(body, 0, 0); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} From fc11dd2a634ce5849ceb9d9e9b9b777999185def Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 12:42:04 +0900 Subject: [PATCH 15/65] =?UTF-8?q?Controller=20=EB=A7=A4=ED=95=91=EC=9D=84?= =?UTF-8?q?=20=EC=9A=94=EC=B2=ADmethod=20+=20path=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 18 ++++-- ...ller.java => UserGetCreateController.java} | 9 ++- .../controller/UserPostCreateController.java | 62 +++++++++++++++++++ src/main/java/webserver/RequestHandler.java | 2 +- 4 files changed, 80 insertions(+), 11 deletions(-) rename src/main/java/controller/{UserCreateController.java => UserGetCreateController.java} (89%) create mode 100644 src/main/java/controller/UserPostCreateController.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index e8aa51613..a59c326f8 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -7,16 +7,20 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { - pathAndControllers.put("/", MainController.getInstance()); - pathAndControllers.put("/user/create", UserCreateController.getInstance()); + pathAndControllers.put("GET /", MainController.getInstance()); + pathAndControllers.put("GET /user/create", UserGetCreateController.getInstance()); + pathAndControllers.put("POST /user/create", UserPostCreateController.getInstance()); } - public static Controller getController(String path) { - if (path.contains("?")) { + public static Controller getController(Map requestInfo) { + String method = requestInfo.get("Method"); + String path = requestInfo.get("Path"); + + if (hasQueryString(path)) { path = path.split("\\?")[0]; } - final Controller controller = pathAndControllers.get(path); + final Controller controller = pathAndControllers.get(method + " " + path); if (Objects.isNull(controller)) { return DefaultController.getInstance(); @@ -24,4 +28,8 @@ public static Controller getController(String path) { return controller; } + + private static boolean hasQueryString(String path) { + return path.contains("?"); + } } diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserGetCreateController.java similarity index 89% rename from src/main/java/controller/UserCreateController.java rename to src/main/java/controller/UserGetCreateController.java index fc2a6b1d5..d9b2e1d5e 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserGetCreateController.java @@ -4,7 +4,6 @@ import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import webserver.RequestHandler; import java.io.DataOutputStream; import java.io.File; @@ -15,11 +14,11 @@ import static util.HttpRequestUtils.parseQueryString; -class UserCreateController implements Controller { - private static final Controller instance = new UserCreateController(); - private static final Logger log = LoggerFactory.getLogger(UserCreateController.class); +class UserGetCreateController implements Controller { + private static final Controller instance = new UserGetCreateController(); + private static final Logger log = LoggerFactory.getLogger(UserGetCreateController.class); - private UserCreateController() {} + private UserGetCreateController() {} public static Controller getInstance() { return instance; diff --git a/src/main/java/controller/UserPostCreateController.java b/src/main/java/controller/UserPostCreateController.java new file mode 100644 index 000000000..f75043ef4 --- /dev/null +++ b/src/main/java/controller/UserPostCreateController.java @@ -0,0 +1,62 @@ +package controller; + +import db.DataBase; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Map; + +import static util.HttpRequestUtils.parseQueryString; + +class UserPostCreateController implements Controller { + private static final Controller instance = new UserPostCreateController(); + private static final Logger log = LoggerFactory.getLogger(UserPostCreateController.class); + + private UserPostCreateController() {} + + public static Controller getInstance() { + return instance; + } + + @Override + public void process(Map requestInfo, OutputStream out) throws IOException { + final String path = requestInfo.get("Path"); + final Map queryString = parseQueryString(path.split("\\?")[1]); + User newUser = new User(queryString.get("userId"), queryString.get("password"), queryString.get("name"), queryString.get("email")); + + log.info("Create User: {}", newUser.toString()); + DataBase.addUser(newUser); + + final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); + + final DataOutputStream dos = new DataOutputStream(out); + response200Header(dos, 0); + responseBody(dos, null); + } + + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void responseBody(DataOutputStream dos, byte[] body) { + try { + dos.write(body, 0, 0); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index d21b628dd..cbb345788 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -29,7 +29,7 @@ public void run() { Map requestInfo = getRequestInfoFrom(in); log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); - Controller c = ControllerConstructor.getController(requestInfo.get("Path")); + Controller c = ControllerConstructor.getController(requestInfo); c.process(requestInfo, out); } catch (IOException e) { log.error(e.getMessage()); From 7829db0fc45fcfefe4fb1f418474f736903b46b4 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 12:55:58 +0900 Subject: [PATCH 16/65] =?UTF-8?q?=EC=9A=94=EC=B2=AD=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A1=9C=20=ED=97=A4=EB=8D=94=20=EC=B6=94=EC=B6=9C=ED=95=A0?= =?UTF-8?q?=EB=95=8C=20parseHeader()=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/util/HttpRequestUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/util/HttpRequestUtils.java b/src/main/java/util/HttpRequestUtils.java index cb5eb2a5a..384065652 100644 --- a/src/main/java/util/HttpRequestUtils.java +++ b/src/main/java/util/HttpRequestUtils.java @@ -130,8 +130,8 @@ public static Map getRequestInfoFrom(InputStream in) throws IOEx continue; } - final int i = line.indexOf(":"); - requestInfo.put(line.substring(0, i), line.substring(i + 2)); + final Pair pair = parseHeader(line); + requestInfo.put(pair.key, pair.value); } return requestInfo; From be57b3fe7eb3e5afd61152543e1e68e816344e3e Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 20:18:49 +0900 Subject: [PATCH 17/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD3=20P?= =?UTF-8?q?OST=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/UserGetCreateController.java | 4 ++-- .../java/controller/UserPostCreateController.java | 9 ++++----- src/main/java/util/HttpRequestUtils.java | 13 +++++++++++++ src/main/java/webserver/RequestHandler.java | 8 ++++++++ webapp/user/form.html | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/main/java/controller/UserGetCreateController.java b/src/main/java/controller/UserGetCreateController.java index d9b2e1d5e..343f76e04 100644 --- a/src/main/java/controller/UserGetCreateController.java +++ b/src/main/java/controller/UserGetCreateController.java @@ -36,8 +36,8 @@ public void process(Map requestInfo, OutputStream out) throws IO final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); final DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, 0); - responseBody(dos, null); + response200Header(dos, body.length); + responseBody(dos, body); } private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { diff --git a/src/main/java/controller/UserPostCreateController.java b/src/main/java/controller/UserPostCreateController.java index f75043ef4..6f45a07d7 100644 --- a/src/main/java/controller/UserPostCreateController.java +++ b/src/main/java/controller/UserPostCreateController.java @@ -26,9 +26,8 @@ public static Controller getInstance() { @Override public void process(Map requestInfo, OutputStream out) throws IOException { - final String path = requestInfo.get("Path"); - final Map queryString = parseQueryString(path.split("\\?")[1]); - User newUser = new User(queryString.get("userId"), queryString.get("password"), queryString.get("name"), queryString.get("email")); + final Map content = parseQueryString(requestInfo.get("body")); + User newUser = new User(content.get("userId"), content.get("password"), content.get("name"), content.get("email")); log.info("Create User: {}", newUser.toString()); DataBase.addUser(newUser); @@ -36,8 +35,8 @@ public void process(Map requestInfo, OutputStream out) throws IO final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); final DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, 0); - responseBody(dos, null); + response200Header(dos, body.length); + responseBody(dos, body); } private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { diff --git a/src/main/java/util/HttpRequestUtils.java b/src/main/java/util/HttpRequestUtils.java index 384065652..c54f7a1a5 100644 --- a/src/main/java/util/HttpRequestUtils.java +++ b/src/main/java/util/HttpRequestUtils.java @@ -117,6 +117,7 @@ public static Map getRequestInfoFrom(InputStream in) throws IOEx final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); Map requestInfo = new HashMap<>(); String line; + int contentLength = 0; while (!"".equals(line = bufferedReader.readLine())) { if (Objects.isNull(line)) { break; @@ -131,9 +132,21 @@ public static Map getRequestInfoFrom(InputStream in) throws IOEx } final Pair pair = parseHeader(line); + if (pair == null) { + continue; + } + + if (pair.key.equals("Content-Length")) { + contentLength = Integer.parseInt(pair.value); + } requestInfo.put(pair.key, pair.value); } + if (contentLength > 0) { + String body = IOUtils.readData(bufferedReader, contentLength); + requestInfo.put("body", body); + } + return requestInfo; } } diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index cbb345788..4abc95546 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -4,10 +4,13 @@ import controller.ControllerConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; import java.io.*; import java.net.Socket; +import java.util.HashMap; import java.util.Map; +import java.util.Objects; import static util.HttpRequestUtils.getRequestInfoFrom; @@ -27,8 +30,13 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { Map requestInfo = getRequestInfoFrom(in); + log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); + for (Map.Entry stringStringEntry : requestInfo.entrySet()) { + System.out.println(stringStringEntry.getKey() + ", " + stringStringEntry.getValue()); + } + Controller c = ControllerConstructor.getController(requestInfo); c.process(requestInfo, out); } catch (IOException e) { diff --git a/webapp/user/form.html b/webapp/user/form.html index 96fe1bd3a..f7a3b5612 100644 --- a/webapp/user/form.html +++ b/webapp/user/form.html @@ -75,7 +75,7 @@
-
+
From cc18e8dd336da8c0449398566cfd760ee238cc29 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 20:22:57 +0900 Subject: [PATCH 18/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD4=203?= =?UTF-8?q?02=20status=20code=20=EC=A0=81=EC=9A=A9=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EC=9D=B8=EB=8D=B1=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/UserPostCreateController.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/main/java/controller/UserPostCreateController.java b/src/main/java/controller/UserPostCreateController.java index 6f45a07d7..d917b0174 100644 --- a/src/main/java/controller/UserPostCreateController.java +++ b/src/main/java/controller/UserPostCreateController.java @@ -32,30 +32,17 @@ public void process(Map requestInfo, OutputStream out) throws IO log.info("Create User: {}", newUser.toString()); DataBase.addUser(newUser); - final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); - final DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, body.length); - responseBody(dos, body); + response302Header(dos, "/"); } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + private void response302Header(DataOutputStream dos, String url) { try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); + dos.writeBytes("Location: " + url + "\r\n"); dos.writeBytes("\r\n"); } catch (IOException e) { log.error(e.getMessage()); } } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, 0); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); - } - } } From 3b577423be6e1d254ca684129009f5d1e321052d Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 22:41:39 +0900 Subject: [PATCH 19/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD5=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 1 + .../java/controller/UserLoginController.java | 57 +++++++++++++++++++ src/main/java/webserver/RequestHandler.java | 4 -- 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/main/java/controller/UserLoginController.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index a59c326f8..1d2c67816 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -10,6 +10,7 @@ public class ControllerConstructor { pathAndControllers.put("GET /", MainController.getInstance()); pathAndControllers.put("GET /user/create", UserGetCreateController.getInstance()); pathAndControllers.put("POST /user/create", UserPostCreateController.getInstance()); + pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); } public static Controller getController(Map requestInfo) { diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java new file mode 100644 index 000000000..a7ebcc024 --- /dev/null +++ b/src/main/java/controller/UserLoginController.java @@ -0,0 +1,57 @@ +package controller; + +import db.DataBase; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; + +import static util.HttpRequestUtils.parseQueryString; + +class UserLoginController implements Controller { + private static final Controller instance = new UserLoginController(); + private static final Logger log = LoggerFactory.getLogger(UserLoginController.class); + + private UserLoginController() {} + + public static Controller getInstance() { + return instance; + } + + @Override + public void process(Map requestInfo, OutputStream out) throws IOException { + final Map content = parseQueryString(requestInfo.get("body")); + final User user = DataBase.findUserById(content.get("userId")); + + final DataOutputStream dos = new DataOutputStream(out); + + if (user == null) { + log.info("Login fail no user"); + response302Header(dos, "/user/login_failed.html", false); + return; + } + + if (user.getPassword().equals(content.get("password"))) { + log.info("Login success: {}", user.getName()); + response302Header(dos, "/", true); + } else { + log.info("Login fail: {}", user.getName()); + response302Header(dos, "/user/login_failed.html", false); + } + } + + private void response302Header(DataOutputStream dos, String url, boolean logined) { + try { + dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); + dos.writeBytes("Location: " + url + "\r\n"); + dos.writeBytes("Set-Cookie: logined=" + logined + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 4abc95546..b2a65b4f3 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -33,10 +33,6 @@ public void run() { log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); - for (Map.Entry stringStringEntry : requestInfo.entrySet()) { - System.out.println(stringStringEntry.getKey() + ", " + stringStringEntry.getValue()); - } - Controller c = ControllerConstructor.getController(requestInfo); c.process(requestInfo, out); } catch (IOException e) { From 52b539feba432dec4507afbb83a4d17c0610cda8 Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 23:03:28 +0900 Subject: [PATCH 20/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD6=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EB=AA=A9=EB=A1=9D=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 1 + .../java/controller/UserListController.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/main/java/controller/UserListController.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 1d2c67816..a1b607abe 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -11,6 +11,7 @@ public class ControllerConstructor { pathAndControllers.put("GET /user/create", UserGetCreateController.getInstance()); pathAndControllers.put("POST /user/create", UserPostCreateController.getInstance()); pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); + pathAndControllers.put("GET /user/list", UserListController.getInstance()); } public static Controller getController(Map requestInfo) { diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java new file mode 100644 index 000000000..e0b5dd735 --- /dev/null +++ b/src/main/java/controller/UserListController.java @@ -0,0 +1,81 @@ +package controller; + +import db.DataBase; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Collection; +import java.util.Map; + +import static util.HttpRequestUtils.parseCookies; + +class UserListController implements Controller { + private static final Controller instance = new UserListController(); + private static final Logger log = LoggerFactory.getLogger(UserListController.class); + + private UserListController() {} + + public static Controller getInstance() { + return instance; + } + + @Override + public void process(Map requestInfo, OutputStream out) throws IOException { + boolean logined = false; + try { + final String cookie = requestInfo.get("Cookie"); + final Map cookies = parseCookies(cookie); + logined = Boolean.parseBoolean(cookies.get("logined")); + } catch (NullPointerException e) { + log.info("invalid cookie"); + } + + final DataOutputStream dos = new DataOutputStream(out); + + if (logined) { + log.info("Login user"); + final Collection all = DataBase.findAll(); + StringBuilder sb = new StringBuilder(); + for (User user : all) { + sb.append(user.getName()).append(": ").append(user.getEmail()).append("\r\n"); + } + + final byte[] body = sb.toString().getBytes(); + + response200Header(dos, body.length); + responseBody(dos, body); + } else { + log.info("Logout user"); + final byte[] body = Files.readAllBytes(new File("./webapp" + "/login.html").toPath()); + + response200Header(dos, body.length); + responseBody(dos, body); + } + } + + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void responseBody(DataOutputStream dos, byte[] body) { + try { + dos.write(body, 0, body.length); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } +} From 9823a7343f29f847206cc96db299563247682b6a Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 23:13:12 +0900 Subject: [PATCH 21/65] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD7=20c?= =?UTF-8?q?ss=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index d4a36465b..79475056e 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -11,11 +11,12 @@ import java.nio.file.Files; import java.util.Map; -class DefaultController implements Controller{ +class DefaultController implements Controller { private static final Controller instance = new DefaultController(); private static final Logger log = LoggerFactory.getLogger(DefaultController.class); - private DefaultController() {} + private DefaultController() { + } public static Controller getInstance() { return instance; @@ -23,17 +24,19 @@ public static Controller getInstance() { @Override public void process(Map requestInfo, OutputStream out) throws IOException { - final byte[] body = Files.readAllBytes(new File("./webapp" + requestInfo.get("Path")).toPath()); + final String path = requestInfo.get("Path"); + final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); + final String fileType = path.substring(path.lastIndexOf(".") + 1); DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, body.length); + response200Header(dos, body.length, fileType); responseBody(dos, body); } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + private void response200Header(DataOutputStream dos, int lengthOfBodyContent, String fileType) { try { dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); + dos.writeBytes("Content-Type: text/" + fileType + ";charset=utf-8\r\n"); dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); dos.writeBytes("\r\n"); } catch (IOException e) { From 5f97448e4e496859f53d825f41230a14c768a20b Mon Sep 17 00:00:00 2001 From: siyoon Date: Thu, 25 Jun 2020 23:23:54 +0900 Subject: [PATCH 22/65] =?UTF-8?q?MainController=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20Default=EC=97=90=EC=84=9C=20=EB=A3=A8?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerConstructor.java | 1 - .../java/controller/DefaultController.java | 6 ++- src/main/java/controller/MainController.java | 52 ------------------- 3 files changed, 5 insertions(+), 54 deletions(-) delete mode 100644 src/main/java/controller/MainController.java diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index a1b607abe..bcf4bd426 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -7,7 +7,6 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { - pathAndControllers.put("GET /", MainController.getInstance()); pathAndControllers.put("GET /user/create", UserGetCreateController.getInstance()); pathAndControllers.put("POST /user/create", UserPostCreateController.getInstance()); pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 79475056e..790dc7868 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -24,7 +24,11 @@ public static Controller getInstance() { @Override public void process(Map requestInfo, OutputStream out) throws IOException { - final String path = requestInfo.get("Path"); + String path = requestInfo.get("Path"); + if (path.equals("/")) { + path = "/index.html"; + } + final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); final String fileType = path.substring(path.lastIndexOf(".") + 1); diff --git a/src/main/java/controller/MainController.java b/src/main/java/controller/MainController.java deleted file mode 100644 index 89ddcdbbf..000000000 --- a/src/main/java/controller/MainController.java +++ /dev/null @@ -1,52 +0,0 @@ -package controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import webserver.RequestHandler; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; -import java.util.Map; - -class MainController implements Controller { - private static final Controller instance = new MainController(); - private static final Logger log = LoggerFactory.getLogger(MainController.class); - - private MainController() {} - - public static Controller getInstance() { - return instance; - } - - @Override - public void process(Map requestInfo, OutputStream out) throws IOException { - final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); - - DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, body.length); - responseBody(dos, body); - } - - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { - try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, body.length); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); - } - } -} From ed0ebf6f9bdba1cdce593ae0d61cf0eecdee1137 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 02:18:29 +0900 Subject: [PATCH 23/65] =?UTF-8?q?=EC=9D=91=EB=8B=B5=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20Response=20=EA=B0=9D=EC=B2=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 6 +- .../controller/ControllerConstructor.java | 9 +- .../java/controller/DefaultController.java | 62 ++++++---- .../java/controller/UserCreateController.java | 38 ++++++ .../controller/UserGetCreateController.java | 62 ---------- .../java/controller/UserListController.java | 47 +++----- .../java/controller/UserLoginController.java | 44 ++++--- .../controller/UserPostCreateController.java | 48 -------- src/main/java/model/RedirectResponse.java | 111 ++++++++++++++++++ src/main/java/model/Response.java | 7 ++ src/main/java/model/StaticFileResponse.java | 90 ++++++++++++++ src/main/java/webserver/RequestHandler.java | 17 ++- 12 files changed, 335 insertions(+), 206 deletions(-) create mode 100644 src/main/java/controller/UserCreateController.java delete mode 100644 src/main/java/controller/UserGetCreateController.java delete mode 100644 src/main/java/controller/UserPostCreateController.java create mode 100644 src/main/java/model/RedirectResponse.java create mode 100644 src/main/java/model/Response.java create mode 100644 src/main/java/model/StaticFileResponse.java diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 156b7680a..170a0928e 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,10 +1,10 @@ package controller; +import model.Response; + import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Map; public interface Controller { - void process(Map requestInfo, OutputStream out) throws IOException; + Response process(Map requestInfo) throws IOException; } diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index bcf4bd426..06380c74f 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -7,8 +7,7 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); static { - pathAndControllers.put("GET /user/create", UserGetCreateController.getInstance()); - pathAndControllers.put("POST /user/create", UserPostCreateController.getInstance()); + pathAndControllers.put("POST /user/create", UserCreateController.getInstance()); pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); pathAndControllers.put("GET /user/list", UserListController.getInstance()); } @@ -18,7 +17,7 @@ public static Controller getController(Map requestInfo) { String path = requestInfo.get("Path"); if (hasQueryString(path)) { - path = path.split("\\?")[0]; + path = subStringQueryString(path); } final Controller controller = pathAndControllers.get(method + " " + path); @@ -30,6 +29,10 @@ public static Controller getController(Map requestInfo) { return controller; } + private static String subStringQueryString(String path) { + return path.split("\\?")[0]; + } + private static boolean hasQueryString(String path) { return path.contains("?"); } diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 790dc7868..a6e5b8a86 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -1,13 +1,12 @@ package controller; +import model.Response; +import model.StaticFileResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import webserver.RequestHandler; -import java.io.DataOutputStream; import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.nio.file.Files; import java.util.Map; @@ -23,37 +22,48 @@ public static Controller getInstance() { } @Override - public void process(Map requestInfo, OutputStream out) throws IOException { - String path = requestInfo.get("Path"); - if (path.equals("/")) { - path = "/index.html"; - } + public Response process(Map requestInfo) throws IOException { + final String path = getPath(requestInfo); + final String mediaType = getMediaType(requestInfo); final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); - final String fileType = path.substring(path.lastIndexOf(".") + 1); - DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, body.length, fileType); - responseBody(dos, body); + return StaticFileResponse.builder() + .status(200) + .header("Content-Type", mediaType + ";charset=utf-8") + .header("Content-Length", body.length) + .body(body) + .build(); } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent, String fileType) { - try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/" + fileType + ";charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); + private String getMediaType(Map requestInfo) { + final String path = requestInfo.get("Path"); + final String fileType = path.substring(path.lastIndexOf(".") + 1); + + switch (fileType) { + case "html": + return "text/html"; + case "css": + return "text/css"; + case "js": + return "text/javascript"; + case "png": + return "image/png"; + case "ico": + return "image/ico"; + case "woff": + return "font/woff"; + default: + log.debug("Can't find proper media-type: {}", fileType); + return "unknown"; } } - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, body.length); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); + private String getPath(Map requestInfo) { + String path = requestInfo.get("Path"); + if (path.equals("/")) { + return "/index.html"; } + return path; } } diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java new file mode 100644 index 000000000..b06afacae --- /dev/null +++ b/src/main/java/controller/UserCreateController.java @@ -0,0 +1,38 @@ +package controller; + +import db.DataBase; +import model.RedirectResponse; +import model.Response; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Map; + +import static util.HttpRequestUtils.parseQueryString; + +class UserCreateController implements Controller { + private static final Controller instance = new UserCreateController(); + private static final Logger log = LoggerFactory.getLogger(UserCreateController.class); + + private UserCreateController() {} + + public static Controller getInstance() { + return instance; + } + + @Override + public Response process(Map requestInfo) throws IOException { + final Map content = parseQueryString(requestInfo.get("body")); + User newUser = new User(content.get("userId"), content.get("password"), content.get("name"), content.get("email")); + + log.info("Create User: {}", newUser.toString()); + DataBase.addUser(newUser); + + return RedirectResponse.builder() + .status(302) + .location("/") + .build(); + } +} diff --git a/src/main/java/controller/UserGetCreateController.java b/src/main/java/controller/UserGetCreateController.java deleted file mode 100644 index 343f76e04..000000000 --- a/src/main/java/controller/UserGetCreateController.java +++ /dev/null @@ -1,62 +0,0 @@ -package controller; - -import db.DataBase; -import model.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; -import java.util.Map; - -import static util.HttpRequestUtils.parseQueryString; - -class UserGetCreateController implements Controller { - private static final Controller instance = new UserGetCreateController(); - private static final Logger log = LoggerFactory.getLogger(UserGetCreateController.class); - - private UserGetCreateController() {} - - public static Controller getInstance() { - return instance; - } - - @Override - public void process(Map requestInfo, OutputStream out) throws IOException { - final String path = requestInfo.get("Path"); - final Map queryString = parseQueryString(path.split("\\?")[1]); - User newUser = new User(queryString.get("userId"), queryString.get("password"), queryString.get("name"), queryString.get("email")); - - log.info("Create User: {}", newUser.toString()); - DataBase.addUser(newUser); - - final byte[] body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath()); - - final DataOutputStream dos = new DataOutputStream(out); - response200Header(dos, body.length); - responseBody(dos, body); - } - - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { - try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, 0); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); - } - } -} diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index e0b5dd735..532ffe07f 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,6 +1,9 @@ package controller; import db.DataBase; +import model.RedirectResponse; +import model.Response; +import model.StaticFileResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +29,7 @@ public static Controller getInstance() { } @Override - public void process(Map requestInfo, OutputStream out) throws IOException { + public Response process(Map requestInfo) { boolean logined = false; try { final String cookie = requestInfo.get("Cookie"); @@ -36,46 +39,28 @@ public void process(Map requestInfo, OutputStream out) throws IO log.info("invalid cookie"); } - final DataOutputStream dos = new DataOutputStream(out); - if (logined) { log.info("Login user"); final Collection all = DataBase.findAll(); StringBuilder sb = new StringBuilder(); for (User user : all) { - sb.append(user.getName()).append(": ").append(user.getEmail()).append("\r\n"); + sb.append(user.getName()).append(": ").append(user.getEmail()).append("
"); } final byte[] body = sb.toString().getBytes(); - response200Header(dos, body.length); - responseBody(dos, body); - } else { - log.info("Logout user"); - final byte[] body = Files.readAllBytes(new File("./webapp" + "/login.html").toPath()); - - response200Header(dos, body.length); - responseBody(dos, body); + return StaticFileResponse.builder() + .status(200) + .header("Content-Type", "text/html;charset=utf-8") + .header("Content-Length", body.length) + .body(body) + .build(); } - } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { - try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, body.length); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); - } + log.info("Logout user"); + return RedirectResponse.builder() + .status(302) + .location("/user/login.html") + .build(); } } diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index a7ebcc024..9fece4615 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -1,6 +1,8 @@ package controller; import db.DataBase; +import model.RedirectResponse; +import model.Response; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,42 +18,36 @@ class UserLoginController implements Controller { private static final Controller instance = new UserLoginController(); private static final Logger log = LoggerFactory.getLogger(UserLoginController.class); - private UserLoginController() {} + private UserLoginController() { + } public static Controller getInstance() { return instance; } @Override - public void process(Map requestInfo, OutputStream out) throws IOException { + public Response process(Map requestInfo) throws IOException { final Map content = parseQueryString(requestInfo.get("body")); final User user = DataBase.findUserById(content.get("userId")); - final DataOutputStream dos = new DataOutputStream(out); - - if (user == null) { - log.info("Login fail no user"); - response302Header(dos, "/user/login_failed.html", false); - return; + if (isLoginFailed(content, user)) { + log.debug("Login fail: {}", user == null ? "[No user]" : user.getName()); + return RedirectResponse.builder() + .status(302) + .location("/user/login_failed.html") + .cookie("logined", false) + .build(); } - if (user.getPassword().equals(content.get("password"))) { - log.info("Login success: {}", user.getName()); - response302Header(dos, "/", true); - } else { - log.info("Login fail: {}", user.getName()); - response302Header(dos, "/user/login_failed.html", false); - } + log.debug("Login success: {}", user.getName()); + return RedirectResponse.builder() + .status(302) + .location("/") + .cookie("logined", true) + .build(); } - private void response302Header(DataOutputStream dos, String url, boolean logined) { - try { - dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); - dos.writeBytes("Location: " + url + "\r\n"); - dos.writeBytes("Set-Cookie: logined=" + logined + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } + private boolean isLoginFailed(Map content, User user) { + return user == null || !user.getPassword().equals(content.get("password")); } } diff --git a/src/main/java/controller/UserPostCreateController.java b/src/main/java/controller/UserPostCreateController.java deleted file mode 100644 index d917b0174..000000000 --- a/src/main/java/controller/UserPostCreateController.java +++ /dev/null @@ -1,48 +0,0 @@ -package controller; - -import db.DataBase; -import model.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; -import java.util.Map; - -import static util.HttpRequestUtils.parseQueryString; - -class UserPostCreateController implements Controller { - private static final Controller instance = new UserPostCreateController(); - private static final Logger log = LoggerFactory.getLogger(UserPostCreateController.class); - - private UserPostCreateController() {} - - public static Controller getInstance() { - return instance; - } - - @Override - public void process(Map requestInfo, OutputStream out) throws IOException { - final Map content = parseQueryString(requestInfo.get("body")); - User newUser = new User(content.get("userId"), content.get("password"), content.get("name"), content.get("email")); - - log.info("Create User: {}", newUser.toString()); - DataBase.addUser(newUser); - - final DataOutputStream dos = new DataOutputStream(out); - response302Header(dos, "/"); - } - - private void response302Header(DataOutputStream dos, String url) { - try { - dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); - dos.writeBytes("Location: " + url + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } -} diff --git a/src/main/java/model/RedirectResponse.java b/src/main/java/model/RedirectResponse.java new file mode 100644 index 000000000..012195166 --- /dev/null +++ b/src/main/java/model/RedirectResponse.java @@ -0,0 +1,111 @@ +package model; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +public class RedirectResponse implements Response{ + private static final Logger log = LoggerFactory.getLogger(RedirectResponse.class); + + private final int status; + private final Map headers; + private final Map cookies; + private final String location; + private final byte[] body; + + public RedirectResponse(int status, Map headers, Map cookies, String location, byte[] body) { + this.status = status; + this.headers = headers; + this.cookies = cookies; + this.location = location; + this.body = body; + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public void write(OutputStream out) { + DataOutputStream dos = new DataOutputStream(out); + writeHeader(dos); + writeBody(dos); + } + + private void writeHeader(DataOutputStream dos) { + try { + dos.writeBytes("HTTP/1.1 " + status + " \r\n"); + dos.writeBytes("Location: " + location + " \r\n"); + dos.writeBytes("Set-Cookie: " + "logined=" + cookies.get("logined") + "\r\n"); + for (Map.Entry header : headers.entrySet()) { + dos.writeBytes(header.getKey() + ": " + header.getValue() + "\r\n"); + } + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void writeBody(DataOutputStream dos) { + try { + if (body != null) { + dos.write(body, 0, body.length); + } + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public static class Builder { + private int status; + private final Map headers; + private final Map cookies; + private String location; + private byte[] body; + + public Builder() { + headers = new HashMap<>(); + cookies = new HashMap<>(); + } + + public Builder status(int status) { + this.status = status; + return this; + } + + public Builder header(String key, String value) { + this.headers.put(key, value); + return this; + } + + public Builder header(String key, int value) { + this.headers.put(key, String.valueOf(value)); + return this; + } + + public Builder cookie(String key, boolean value) { + this.cookies.put(key, String.valueOf(value)); + return this; + } + + public Builder location(String location) { + this.location = location; + return this; + } + + public Builder body(byte[] body) { + this.body = body; + return this; + } + + public RedirectResponse build() { + return new RedirectResponse(status, headers, cookies, location, body); + } + } +} diff --git a/src/main/java/model/Response.java b/src/main/java/model/Response.java new file mode 100644 index 000000000..a983c38af --- /dev/null +++ b/src/main/java/model/Response.java @@ -0,0 +1,7 @@ +package model; + +import java.io.OutputStream; + +public interface Response { + void write(OutputStream outputStream); +} diff --git a/src/main/java/model/StaticFileResponse.java b/src/main/java/model/StaticFileResponse.java new file mode 100644 index 000000000..dbeb3963c --- /dev/null +++ b/src/main/java/model/StaticFileResponse.java @@ -0,0 +1,90 @@ +package model; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +public class StaticFileResponse implements Response { + private static final Logger log = LoggerFactory.getLogger(StaticFileResponse.class); + + private final int status; + private final Map headers; + private final byte[] body; + + private StaticFileResponse(int status, Map headers, byte[] body) { + this.status = status; + this.headers = headers; + this.body = body; + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public void write(OutputStream out) { + DataOutputStream dos = new DataOutputStream(out); + writeHeader(dos); + writeBody(dos); + } + + private void writeHeader(DataOutputStream dos) { + try { + dos.writeBytes("HTTP/1.1 " + status + " \r\n"); + for (Map.Entry header : headers.entrySet()) { + dos.writeBytes(header.getKey() + ": " + header.getValue() + "\r\n"); + } + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void writeBody(DataOutputStream dos) { + try { + dos.write(body, 0, body.length); + dos.flush(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public static class Builder { + private int status; + private final Map headers; + private byte[] body; + + public Builder() { + headers = new HashMap<>(); + } + + public Builder status(int status) { + this.status = status; + return this; + } + + public Builder header(String key, String value) { + this.headers.put(key, value); + return this; + } + + public Builder header(String key, int value) { + this.headers.put(key, String.valueOf(value)); + return this; + } + + public Builder body(byte[] body) { + this.body = body; + return this; + } + + public StaticFileResponse build() { + return new StaticFileResponse(status, headers, body); + } + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index b2a65b4f3..17e07b4b9 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,15 +2,16 @@ import controller.Controller; import controller.ControllerConstructor; +import model.Response; +import model.StaticFileResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import util.HttpRequestUtils; -import java.io.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.Socket; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; import static util.HttpRequestUtils.getRequestInfoFrom; @@ -30,11 +31,9 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { Map requestInfo = getRequestInfoFrom(in); - - log.debug("Method: {}, Path: {}", requestInfo.get("Method"), requestInfo.get("Path")); - - Controller c = ControllerConstructor.getController(requestInfo); - c.process(requestInfo, out); + final Controller c = ControllerConstructor.getController(requestInfo); + final Response response = c.process(requestInfo); + response.write(out); } catch (IOException e) { log.error(e.getMessage()); } From df48ca3f047e8f6e6d24be16e46e36e3d8cd04d6 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 02:21:49 +0900 Subject: [PATCH 24/65] =?UTF-8?q?User=20=EC=83=9D=EC=84=B1=EC=8B=9C?= =?UTF-8?q?=EC=97=90=20body=20content=EB=A5=BC=20=EC=9D=B8=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8A=94=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserCreateController.java | 4 ++-- src/main/java/controller/UserLoginController.java | 2 +- src/main/java/model/User.java | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index b06afacae..70cd4f8e0 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -23,9 +23,9 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) throws IOException { + public Response process(Map requestInfo) { final Map content = parseQueryString(requestInfo.get("body")); - User newUser = new User(content.get("userId"), content.get("password"), content.get("name"), content.get("email")); + User newUser = new User(content); log.info("Create User: {}", newUser.toString()); DataBase.addUser(newUser); diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 9fece4615..56a05375f 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -26,7 +26,7 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) throws IOException { + public Response process(Map requestInfo) { final Map content = parseQueryString(requestInfo.get("body")); final User user = DataBase.findUserById(content.get("userId")); diff --git a/src/main/java/model/User.java b/src/main/java/model/User.java index b7abb7304..584d5bb14 100644 --- a/src/main/java/model/User.java +++ b/src/main/java/model/User.java @@ -1,5 +1,7 @@ package model; +import java.util.Map; + public class User { private String userId; private String password; @@ -13,6 +15,13 @@ public User(String userId, String password, String name, String email) { this.email = email; } + public User(Map content) { + this.userId = content.get("userId"); + this.password = content.get("password"); + this.name = content.get("name"); + this.email = content.get("email"); + } + public String getUserId() { return userId; } From 31a15fe8910d38d3d7c386dc6c7d6389e8ce43a8 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 02:25:39 +0900 Subject: [PATCH 25/65] =?UTF-8?q?requestInfo=20final=20=ED=82=A4=EC=9B=8C?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 17e07b4b9..f58b42eee 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -3,7 +3,6 @@ import controller.Controller; import controller.ControllerConstructor; import model.Response; -import model.StaticFileResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +29,7 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - Map requestInfo = getRequestInfoFrom(in); + final Map requestInfo = getRequestInfoFrom(in); final Controller c = ControllerConstructor.getController(requestInfo); final Response response = c.process(requestInfo); response.write(out); From c8bc061c6f821e8b3f9cee7b95c9aab3556edcd8 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 02:27:22 +0900 Subject: [PATCH 26/65] =?UTF-8?q?Response=20=EB=AA=A8=EB=8D=B8=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20controller=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=ED=95=98=EC=9C=84=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 2 +- src/main/java/controller/DefaultController.java | 4 ++-- src/main/java/controller/UserCreateController.java | 5 ++--- src/main/java/controller/UserListController.java | 11 +++-------- src/main/java/controller/UserLoginController.java | 7 ++----- .../java/{ => controller}/model/RedirectResponse.java | 2 +- src/main/java/{ => controller}/model/Response.java | 2 +- .../{ => controller}/model/StaticFileResponse.java | 2 +- src/main/java/webserver/RequestHandler.java | 6 +++--- 9 files changed, 16 insertions(+), 25 deletions(-) rename src/main/java/{ => controller}/model/RedirectResponse.java (99%) rename src/main/java/{ => controller}/model/Response.java (80%) rename src/main/java/{ => controller}/model/StaticFileResponse.java (98%) diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 170a0928e..d765fe035 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,6 +1,6 @@ package controller; -import model.Response; +import controller.model.Response; import java.io.IOException; import java.util.Map; diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index a6e5b8a86..b5b3c1f28 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -1,7 +1,7 @@ package controller; -import model.Response; -import model.StaticFileResponse; +import controller.model.Response; +import controller.model.StaticFileResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index 70cd4f8e0..292831266 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -1,13 +1,12 @@ package controller; import db.DataBase; -import model.RedirectResponse; -import model.Response; +import controller.model.RedirectResponse; +import controller.model.Response; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Map; import static util.HttpRequestUtils.parseQueryString; diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 532ffe07f..5466a4b12 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,18 +1,13 @@ package controller; import db.DataBase; -import model.RedirectResponse; -import model.Response; -import model.StaticFileResponse; +import controller.model.RedirectResponse; +import controller.model.Response; +import controller.model.StaticFileResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; import java.util.Collection; import java.util.Map; diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 56a05375f..56f5163ae 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -1,15 +1,12 @@ package controller; import db.DataBase; -import model.RedirectResponse; -import model.Response; +import controller.model.RedirectResponse; +import controller.model.Response; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; import java.util.Map; import static util.HttpRequestUtils.parseQueryString; diff --git a/src/main/java/model/RedirectResponse.java b/src/main/java/controller/model/RedirectResponse.java similarity index 99% rename from src/main/java/model/RedirectResponse.java rename to src/main/java/controller/model/RedirectResponse.java index 012195166..efd9cb8b5 100644 --- a/src/main/java/model/RedirectResponse.java +++ b/src/main/java/controller/model/RedirectResponse.java @@ -1,4 +1,4 @@ -package model; +package controller.model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/model/Response.java b/src/main/java/controller/model/Response.java similarity index 80% rename from src/main/java/model/Response.java rename to src/main/java/controller/model/Response.java index a983c38af..02ae25edd 100644 --- a/src/main/java/model/Response.java +++ b/src/main/java/controller/model/Response.java @@ -1,4 +1,4 @@ -package model; +package controller.model; import java.io.OutputStream; diff --git a/src/main/java/model/StaticFileResponse.java b/src/main/java/controller/model/StaticFileResponse.java similarity index 98% rename from src/main/java/model/StaticFileResponse.java rename to src/main/java/controller/model/StaticFileResponse.java index dbeb3963c..6d6c67b76 100644 --- a/src/main/java/model/StaticFileResponse.java +++ b/src/main/java/controller/model/StaticFileResponse.java @@ -1,4 +1,4 @@ -package model; +package controller.model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index f58b42eee..c0e59fd95 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,7 +2,7 @@ import controller.Controller; import controller.ControllerConstructor; -import model.Response; +import controller.model.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,8 +30,8 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { final Map requestInfo = getRequestInfoFrom(in); - final Controller c = ControllerConstructor.getController(requestInfo); - final Response response = c.process(requestInfo); + final Controller controller = ControllerConstructor.getController(requestInfo); + final Response response = controller.process(requestInfo); response.write(out); } catch (IOException e) { log.error(e.getMessage()); From 97b0bfbb5fe211b81ee54fda47c260de4ddc02e1 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 09:29:06 +0900 Subject: [PATCH 27/65] =?UTF-8?q?=EC=9A=94=EC=B2=AD=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20=EB=A7=B5=EC=97=90=EC=84=9C=20=EC=9D=BC=EA=B8=89?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 4 +- .../controller/ControllerConstructor.java | 8 ++- .../java/controller/DefaultController.java | 31 ++++---- .../java/controller/UserCreateController.java | 5 +- .../java/controller/UserListController.java | 5 +- .../java/controller/UserLoginController.java | 5 +- .../java/controller/model/HttpRequest.java | 72 +++++++++++++++++++ src/main/java/util/HttpRequestUtils.java | 37 ---------- src/main/java/webserver/RequestHandler.java | 10 ++- 9 files changed, 107 insertions(+), 70 deletions(-) create mode 100644 src/main/java/controller/model/HttpRequest.java diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index d765fe035..e2525bcef 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,10 +1,10 @@ package controller; +import controller.model.HttpRequest; import controller.model.Response; import java.io.IOException; -import java.util.Map; public interface Controller { - Response process(Map requestInfo) throws IOException; + Response process(HttpRequest httpRequest) throws IOException; } diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 06380c74f..624311a97 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -1,5 +1,7 @@ package controller; +import controller.model.HttpRequest; + import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -12,9 +14,9 @@ public class ControllerConstructor { pathAndControllers.put("GET /user/list", UserListController.getInstance()); } - public static Controller getController(Map requestInfo) { - String method = requestInfo.get("Method"); - String path = requestInfo.get("Path"); + public static Controller getOf(HttpRequest request) { + final String method = request.get("Method"); + String path = request.get("Path"); if (hasQueryString(path)) { path = subStringQueryString(path); diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index b5b3c1f28..f218d7396 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -1,5 +1,6 @@ package controller; +import controller.model.HttpRequest; import controller.model.Response; import controller.model.StaticFileResponse; import org.slf4j.Logger; @@ -8,7 +9,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.Map; class DefaultController implements Controller { private static final Controller instance = new DefaultController(); @@ -22,10 +22,9 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) throws IOException { - final String path = getPath(requestInfo); - final String mediaType = getMediaType(requestInfo); - + public Response process(HttpRequest request) throws IOException { + final String path = getPath(request); + final String mediaType = getMediaType(request); final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); return StaticFileResponse.builder() @@ -36,9 +35,17 @@ public Response process(Map requestInfo) throws IOException { .build(); } - private String getMediaType(Map requestInfo) { - final String path = requestInfo.get("Path"); - final String fileType = path.substring(path.lastIndexOf(".") + 1); + private String getPath(HttpRequest request) { + final String path = request.get("Path"); + if (path.equals("/")) { + return "/index.html"; + } + return path; + } + + private String getMediaType(HttpRequest request) { + final String path = request.get("Path"); + final String fileType = path.substring(path.lastIndexOf("\\.") + 1); switch (fileType) { case "html": @@ -58,12 +65,4 @@ private String getMediaType(Map requestInfo) { return "unknown"; } } - - private String getPath(Map requestInfo) { - String path = requestInfo.get("Path"); - if (path.equals("/")) { - return "/index.html"; - } - return path; - } } diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index 292831266..13f3a892b 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -1,5 +1,6 @@ package controller; +import controller.model.HttpRequest; import db.DataBase; import controller.model.RedirectResponse; import controller.model.Response; @@ -22,8 +23,8 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) { - final Map content = parseQueryString(requestInfo.get("body")); + public Response process(HttpRequest request) { + final Map content = parseQueryString(request.get("body")); User newUser = new User(content); log.info("Create User: {}", newUser.toString()); diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 5466a4b12..f1a52cc2b 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,5 +1,6 @@ package controller; +import controller.model.HttpRequest; import db.DataBase; import controller.model.RedirectResponse; import controller.model.Response; @@ -24,10 +25,10 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) { + public Response process(HttpRequest request) { boolean logined = false; try { - final String cookie = requestInfo.get("Cookie"); + final String cookie = request.get("Cookie"); final Map cookies = parseCookies(cookie); logined = Boolean.parseBoolean(cookies.get("logined")); } catch (NullPointerException e) { diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 56f5163ae..5c85c544f 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -1,5 +1,6 @@ package controller; +import controller.model.HttpRequest; import db.DataBase; import controller.model.RedirectResponse; import controller.model.Response; @@ -23,8 +24,8 @@ public static Controller getInstance() { } @Override - public Response process(Map requestInfo) { - final Map content = parseQueryString(requestInfo.get("body")); + public Response process(HttpRequest request) { + final Map content = parseQueryString(request.get("body")); final User user = DataBase.findUserById(content.get("userId")); if (isLoginFailed(content, user)) { diff --git a/src/main/java/controller/model/HttpRequest.java b/src/main/java/controller/model/HttpRequest.java new file mode 100644 index 000000000..1f1d20f5b --- /dev/null +++ b/src/main/java/controller/model/HttpRequest.java @@ -0,0 +1,72 @@ +package controller.model; + +import util.HttpRequestUtils; +import util.IOUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import static util.HttpRequestUtils.parseHeader; + +public class HttpRequest { + private final Map requestInfo; + + private HttpRequest(InputStream in) throws IOException { + requestInfo = new HashMap<>(); + + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + + int contentLength = parseHeaders(bufferedReader); + + if (contentLength > 0) { + parseBody(bufferedReader, contentLength); + } + } + + public static HttpRequest from(InputStream in) throws IOException { + return new HttpRequest(in); + } + + private int parseHeaders(BufferedReader bufferedReader) throws IOException { + String line; + int contentLength = 0; + while (!"".equals(line = bufferedReader.readLine())) { + if (Objects.isNull(line)) { + break; + } + + if (requestInfo.isEmpty()) { + final String[] s = line.split(" "); + requestInfo.put("Method", s[0]); + requestInfo.put("Path", s[1]); + requestInfo.put("Version", s[2]); + continue; + } + + final HttpRequestUtils.Pair pair = parseHeader(line); + if (Objects.isNull(pair)) { + continue; + } + + if (pair.getKey().equals("Content-Length")) { + contentLength = Integer.parseInt(pair.getValue()); + } + requestInfo.put(pair.getKey(), pair.getValue()); + } + return contentLength; + } + + private void parseBody(BufferedReader bufferedReader, int contentLength) throws IOException { + String body = IOUtils.readData(bufferedReader, contentLength); + requestInfo.put("body", body); + } + + public String get(String key) { + return requestInfo.get(key); + } +} diff --git a/src/main/java/util/HttpRequestUtils.java b/src/main/java/util/HttpRequestUtils.java index c54f7a1a5..e54cba985 100644 --- a/src/main/java/util/HttpRequestUtils.java +++ b/src/main/java/util/HttpRequestUtils.java @@ -112,41 +112,4 @@ public String toString() { return "Pair [key=" + key + ", value=" + value + "]"; } } - - public static Map getRequestInfoFrom(InputStream in) throws IOException { - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); - Map requestInfo = new HashMap<>(); - String line; - int contentLength = 0; - while (!"".equals(line = bufferedReader.readLine())) { - if (Objects.isNull(line)) { - break; - } - - if (requestInfo.isEmpty()) { - final String[] s = line.split(" "); - requestInfo.put("Method", s[0]); - requestInfo.put("Path", s[1]); - requestInfo.put("Version", s[2]); - continue; - } - - final Pair pair = parseHeader(line); - if (pair == null) { - continue; - } - - if (pair.key.equals("Content-Length")) { - contentLength = Integer.parseInt(pair.value); - } - requestInfo.put(pair.key, pair.value); - } - - if (contentLength > 0) { - String body = IOUtils.readData(bufferedReader, contentLength); - requestInfo.put("body", body); - } - - return requestInfo; - } } diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index c0e59fd95..08e2f64b5 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,6 +2,7 @@ import controller.Controller; import controller.ControllerConstructor; +import controller.model.HttpRequest; import controller.model.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,9 +11,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; -import java.util.Map; - -import static util.HttpRequestUtils.getRequestInfoFrom; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -29,9 +27,9 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - final Map requestInfo = getRequestInfoFrom(in); - final Controller controller = ControllerConstructor.getController(requestInfo); - final Response response = controller.process(requestInfo); + final HttpRequest httpRequest = HttpRequest.from(in); + final Controller controller = ControllerConstructor.getOf(httpRequest); + final Response response = controller.process(httpRequest); response.write(out); } catch (IOException e) { log.error(e.getMessage()); From c92df75f465449a85bf45fcd5d06adb70e0da6b9 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 09:33:08 +0900 Subject: [PATCH 28/65] =?UTF-8?q?substring=20str=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index f218d7396..f46b67a5e 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -45,7 +45,7 @@ private String getPath(HttpRequest request) { private String getMediaType(HttpRequest request) { final String path = request.get("Path"); - final String fileType = path.substring(path.lastIndexOf("\\.") + 1); + final String fileType = path.substring(path.lastIndexOf(".") + 1); switch (fileType) { case "html": From 7b50393a7e72db3713aed4c28e3d14970ebaafc9 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 09:53:21 +0900 Subject: [PATCH 29/65] =?UTF-8?q?=EC=9D=91=EB=8B=B5=EA=B0=9D=EC=B2=B4=20Ht?= =?UTF-8?q?tpResponse=20=ED=95=98=EB=82=98=EB=A1=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/Controller.java | 4 +- .../controller/ControllerConstructor.java | 6 +- .../java/controller/DefaultController.java | 7 +- .../java/controller/UserCreateController.java | 7 +- .../java/controller/UserListController.java | 10 +-- .../java/controller/UserLoginController.java | 9 +- ...edirectResponse.java => HttpResponse.java} | 42 +++++---- src/main/java/controller/model/Response.java | 7 -- .../controller/model/StaticFileResponse.java | 90 ------------------- src/main/java/webserver/RequestHandler.java | 4 +- 10 files changed, 44 insertions(+), 142 deletions(-) rename src/main/java/controller/model/{RedirectResponse.java => HttpResponse.java} (70%) delete mode 100644 src/main/java/controller/model/Response.java delete mode 100644 src/main/java/controller/model/StaticFileResponse.java diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index e2525bcef..79463ac09 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,10 +1,10 @@ package controller; import controller.model.HttpRequest; -import controller.model.Response; +import controller.model.HttpResponse; import java.io.IOException; public interface Controller { - Response process(HttpRequest httpRequest) throws IOException; + HttpResponse process(HttpRequest httpRequest) throws IOException; } diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 624311a97..6e799cf61 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -24,11 +24,7 @@ public static Controller getOf(HttpRequest request) { final Controller controller = pathAndControllers.get(method + " " + path); - if (Objects.isNull(controller)) { - return DefaultController.getInstance(); - } - - return controller; + return Objects.isNull(controller) ? DefaultController.getInstance() : controller; } private static String subStringQueryString(String path) { diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index f46b67a5e..d51b2c000 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -1,8 +1,7 @@ package controller; import controller.model.HttpRequest; -import controller.model.Response; -import controller.model.StaticFileResponse; +import controller.model.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,12 +21,12 @@ public static Controller getInstance() { } @Override - public Response process(HttpRequest request) throws IOException { + public HttpResponse process(HttpRequest request) throws IOException { final String path = getPath(request); final String mediaType = getMediaType(request); final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); - return StaticFileResponse.builder() + return HttpResponse.builder() .status(200) .header("Content-Type", mediaType + ";charset=utf-8") .header("Content-Length", body.length) diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index 13f3a892b..e913ea1bc 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -2,8 +2,7 @@ import controller.model.HttpRequest; import db.DataBase; -import controller.model.RedirectResponse; -import controller.model.Response; +import controller.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,14 +22,14 @@ public static Controller getInstance() { } @Override - public Response process(HttpRequest request) { + public HttpResponse process(HttpRequest request) { final Map content = parseQueryString(request.get("body")); User newUser = new User(content); log.info("Create User: {}", newUser.toString()); DataBase.addUser(newUser); - return RedirectResponse.builder() + return HttpResponse.builder() .status(302) .location("/") .build(); diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index f1a52cc2b..68367bd4c 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -2,9 +2,7 @@ import controller.model.HttpRequest; import db.DataBase; -import controller.model.RedirectResponse; -import controller.model.Response; -import controller.model.StaticFileResponse; +import controller.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,7 +23,7 @@ public static Controller getInstance() { } @Override - public Response process(HttpRequest request) { + public HttpResponse process(HttpRequest request) { boolean logined = false; try { final String cookie = request.get("Cookie"); @@ -45,7 +43,7 @@ public Response process(HttpRequest request) { final byte[] body = sb.toString().getBytes(); - return StaticFileResponse.builder() + return HttpResponse.builder() .status(200) .header("Content-Type", "text/html;charset=utf-8") .header("Content-Length", body.length) @@ -54,7 +52,7 @@ public Response process(HttpRequest request) { } log.info("Logout user"); - return RedirectResponse.builder() + return HttpResponse.builder() .status(302) .location("/user/login.html") .build(); diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 5c85c544f..39cf06a56 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -2,8 +2,7 @@ import controller.model.HttpRequest; import db.DataBase; -import controller.model.RedirectResponse; -import controller.model.Response; +import controller.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,13 +23,13 @@ public static Controller getInstance() { } @Override - public Response process(HttpRequest request) { + public HttpResponse process(HttpRequest request) { final Map content = parseQueryString(request.get("body")); final User user = DataBase.findUserById(content.get("userId")); if (isLoginFailed(content, user)) { log.debug("Login fail: {}", user == null ? "[No user]" : user.getName()); - return RedirectResponse.builder() + return HttpResponse.builder() .status(302) .location("/user/login_failed.html") .cookie("logined", false) @@ -38,7 +37,7 @@ public Response process(HttpRequest request) { } log.debug("Login success: {}", user.getName()); - return RedirectResponse.builder() + return HttpResponse.builder() .status(302) .location("/") .cookie("logined", true) diff --git a/src/main/java/controller/model/RedirectResponse.java b/src/main/java/controller/model/HttpResponse.java similarity index 70% rename from src/main/java/controller/model/RedirectResponse.java rename to src/main/java/controller/model/HttpResponse.java index efd9cb8b5..77bbb07b6 100644 --- a/src/main/java/controller/model/RedirectResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -9,20 +9,18 @@ import java.util.HashMap; import java.util.Map; -public class RedirectResponse implements Response{ - private static final Logger log = LoggerFactory.getLogger(RedirectResponse.class); +import static java.util.stream.Collectors.joining; + +public class HttpResponse { + private static final Logger log = LoggerFactory.getLogger(HttpResponse.class); private final int status; private final Map headers; - private final Map cookies; - private final String location; private final byte[] body; - public RedirectResponse(int status, Map headers, Map cookies, String location, byte[] body) { + public HttpResponse(int status, Map headers, byte[] body) { this.status = status; this.headers = headers; - this.cookies = cookies; - this.location = location; this.body = body; } @@ -30,7 +28,6 @@ public static Builder builder() { return new Builder(); } - @Override public void write(OutputStream out) { DataOutputStream dos = new DataOutputStream(out); writeHeader(dos); @@ -40,8 +37,6 @@ public void write(OutputStream out) { private void writeHeader(DataOutputStream dos) { try { dos.writeBytes("HTTP/1.1 " + status + " \r\n"); - dos.writeBytes("Location: " + location + " \r\n"); - dos.writeBytes("Set-Cookie: " + "logined=" + cookies.get("logined") + "\r\n"); for (Map.Entry header : headers.entrySet()) { dos.writeBytes(header.getKey() + ": " + header.getValue() + "\r\n"); } @@ -66,7 +61,6 @@ public static class Builder { private int status; private final Map headers; private final Map cookies; - private String location; private byte[] body; public Builder() { @@ -80,22 +74,22 @@ public Builder status(int status) { } public Builder header(String key, String value) { - this.headers.put(key, value); + headers.put(key, value); return this; } public Builder header(String key, int value) { - this.headers.put(key, String.valueOf(value)); + headers.put(key, String.valueOf(value)); return this; } public Builder cookie(String key, boolean value) { - this.cookies.put(key, String.valueOf(value)); + cookies.put(key, String.valueOf(value)); return this; } public Builder location(String location) { - this.location = location; + headers.put("Location", location); return this; } @@ -104,8 +98,22 @@ public Builder body(byte[] body) { return this; } - public RedirectResponse build() { - return new RedirectResponse(status, headers, cookies, location, body); + public HttpResponse build() { + putCookiesOnHeader(); + return new HttpResponse(status, headers, body); + } + + private void putCookiesOnHeader() { + if (cookies.isEmpty()) { + return; + } + + final String cookies = this.cookies.entrySet() + .stream() + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(joining(";")); + + headers.put("Set-Cookie", cookies); } } } diff --git a/src/main/java/controller/model/Response.java b/src/main/java/controller/model/Response.java deleted file mode 100644 index 02ae25edd..000000000 --- a/src/main/java/controller/model/Response.java +++ /dev/null @@ -1,7 +0,0 @@ -package controller.model; - -import java.io.OutputStream; - -public interface Response { - void write(OutputStream outputStream); -} diff --git a/src/main/java/controller/model/StaticFileResponse.java b/src/main/java/controller/model/StaticFileResponse.java deleted file mode 100644 index 6d6c67b76..000000000 --- a/src/main/java/controller/model/StaticFileResponse.java +++ /dev/null @@ -1,90 +0,0 @@ -package controller.model; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -public class StaticFileResponse implements Response { - private static final Logger log = LoggerFactory.getLogger(StaticFileResponse.class); - - private final int status; - private final Map headers; - private final byte[] body; - - private StaticFileResponse(int status, Map headers, byte[] body) { - this.status = status; - this.headers = headers; - this.body = body; - } - - public static Builder builder() { - return new Builder(); - } - - @Override - public void write(OutputStream out) { - DataOutputStream dos = new DataOutputStream(out); - writeHeader(dos); - writeBody(dos); - } - - private void writeHeader(DataOutputStream dos) { - try { - dos.writeBytes("HTTP/1.1 " + status + " \r\n"); - for (Map.Entry header : headers.entrySet()) { - dos.writeBytes(header.getKey() + ": " + header.getValue() + "\r\n"); - } - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - private void writeBody(DataOutputStream dos) { - try { - dos.write(body, 0, body.length); - dos.flush(); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - public static class Builder { - private int status; - private final Map headers; - private byte[] body; - - public Builder() { - headers = new HashMap<>(); - } - - public Builder status(int status) { - this.status = status; - return this; - } - - public Builder header(String key, String value) { - this.headers.put(key, value); - return this; - } - - public Builder header(String key, int value) { - this.headers.put(key, String.valueOf(value)); - return this; - } - - public Builder body(byte[] body) { - this.body = body; - return this; - } - - public StaticFileResponse build() { - return new StaticFileResponse(status, headers, body); - } - } -} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 08e2f64b5..fda67810e 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -3,7 +3,7 @@ import controller.Controller; import controller.ControllerConstructor; import controller.model.HttpRequest; -import controller.model.Response; +import controller.model.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +29,7 @@ public void run() { OutputStream out = connection.getOutputStream()) { final HttpRequest httpRequest = HttpRequest.from(in); final Controller controller = ControllerConstructor.getOf(httpRequest); - final Response response = controller.process(httpRequest); + final HttpResponse response = controller.process(httpRequest); response.write(out); } catch (IOException e) { log.error(e.getMessage()); From 2542ccb3bfb383c3ea99f0f50601bab028ee2d37 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 10:00:50 +0900 Subject: [PATCH 30/65] =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/ControllerConstructor.java | 4 ++++ src/main/java/controller/DefaultController.java | 2 +- src/main/java/controller/UserCreateController.java | 4 ++-- src/main/java/controller/UserListController.java | 2 +- src/main/java/controller/model/HttpResponse.java | 4 ++-- src/main/java/webserver/RequestHandler.java | 1 + 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 6e799cf61..d437b592c 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -8,6 +8,10 @@ public class ControllerConstructor { private final static Map pathAndControllers = new HashMap<>(); + + private ControllerConstructor() { + } + static { pathAndControllers.put("POST /user/create", UserCreateController.getInstance()); pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index d51b2c000..afe9018cd 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -44,7 +44,7 @@ private String getPath(HttpRequest request) { private String getMediaType(HttpRequest request) { final String path = request.get("Path"); - final String fileType = path.substring(path.lastIndexOf(".") + 1); + final String fileType = path.substring(path.lastIndexOf('.') + 1); switch (fileType) { case "html": diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index e913ea1bc..9546ca9c1 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -24,9 +24,9 @@ public static Controller getInstance() { @Override public HttpResponse process(HttpRequest request) { final Map content = parseQueryString(request.get("body")); - User newUser = new User(content); + final User newUser = new User(content); - log.info("Create User: {}", newUser.toString()); + log.info("Create User: {}", newUser); DataBase.addUser(newUser); return HttpResponse.builder() diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 68367bd4c..8f78dc3d9 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -36,7 +36,7 @@ public HttpResponse process(HttpRequest request) { if (logined) { log.info("Login user"); final Collection all = DataBase.findAll(); - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); for (User user : all) { sb.append(user.getName()).append(": ").append(user.getEmail()).append("
"); } diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/controller/model/HttpResponse.java index 77bbb07b6..b3fa183ea 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -108,12 +108,12 @@ private void putCookiesOnHeader() { return; } - final String cookies = this.cookies.entrySet() + final String joinedCookies = this.cookies.entrySet() .stream() .map(e -> e.getKey() + "=" + e.getValue()) .collect(joining(";")); - headers.put("Set-Cookie", cookies); + headers.put("Set-Cookie", joinedCookies); } } } diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index fda67810e..62a1e069e 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -21,6 +21,7 @@ public RequestHandler(Socket connectionSocket) { this.connection = connectionSocket; } + @Override public void run() { log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort()); From 017bbfdebcfe389cc5b424e4ec3ff5c544ed4b9e Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 10:03:12 +0900 Subject: [PATCH 31/65] =?UTF-8?q?=EB=A7=A4=EC=A7=81=EB=84=98=EB=B2=84=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index afe9018cd..a1dbc1df4 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -12,6 +12,7 @@ class DefaultController implements Controller { private static final Controller instance = new DefaultController(); private static final Logger log = LoggerFactory.getLogger(DefaultController.class); + private static final String STATIC_FILE_PATH = "./webapp"; private DefaultController() { } @@ -24,7 +25,8 @@ public static Controller getInstance() { public HttpResponse process(HttpRequest request) throws IOException { final String path = getPath(request); final String mediaType = getMediaType(request); - final byte[] body = Files.readAllBytes(new File("./webapp" + path).toPath()); + + final byte[] body = Files.readAllBytes(new File(STATIC_FILE_PATH + path).toPath()); return HttpResponse.builder() .status(200) From 0a349b5b3af518785da2b27cd397bd18e1a55ee6 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 10:19:42 +0900 Subject: [PATCH 32/65] =?UTF-8?q?=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 62a1e069e..6f53231d2 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -30,8 +30,8 @@ public void run() { OutputStream out = connection.getOutputStream()) { final HttpRequest httpRequest = HttpRequest.from(in); final Controller controller = ControllerConstructor.getOf(httpRequest); - final HttpResponse response = controller.process(httpRequest); - response.write(out); + final HttpResponse httpResponse = controller.process(httpRequest); + httpResponse.write(out); } catch (IOException e) { log.error(e.getMessage()); } From 0f8d386e117aabf0db1ffd8138fc64b15df043d3 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:26:56 +0900 Subject: [PATCH 33/65] =?UTF-8?q?location=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserCreateController.java | 2 +- src/main/java/controller/UserListController.java | 2 +- src/main/java/controller/UserLoginController.java | 4 ++-- src/main/java/controller/model/HttpResponse.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index 9546ca9c1..c75caf40d 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -31,7 +31,7 @@ public HttpResponse process(HttpRequest request) { return HttpResponse.builder() .status(302) - .location("/") + .redirect("/") .build(); } } diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 8f78dc3d9..36537f7b2 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -54,7 +54,7 @@ public HttpResponse process(HttpRequest request) { log.info("Logout user"); return HttpResponse.builder() .status(302) - .location("/user/login.html") + .redirect("/user/login.html") .build(); } } diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 39cf06a56..bf29e1c21 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -31,7 +31,7 @@ public HttpResponse process(HttpRequest request) { log.debug("Login fail: {}", user == null ? "[No user]" : user.getName()); return HttpResponse.builder() .status(302) - .location("/user/login_failed.html") + .redirect("/user/login_failed.html") .cookie("logined", false) .build(); } @@ -39,7 +39,7 @@ public HttpResponse process(HttpRequest request) { log.debug("Login success: {}", user.getName()); return HttpResponse.builder() .status(302) - .location("/") + .redirect("/") .cookie("logined", true) .build(); } diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/controller/model/HttpResponse.java index b3fa183ea..e1bf2e374 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -88,7 +88,7 @@ public Builder cookie(String key, boolean value) { return this; } - public Builder location(String location) { + public Builder redirect(String location) { headers.put("Location", location); return this; } From ac412611fec112c9a7ee2489bb4c13373ed2dd0e Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:39:24 +0900 Subject: [PATCH 34/65] =?UTF-8?q?Request=20get()=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=8E=B8=EC=9D=98=EC=84=B1=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/ControllerConstructor.java | 6 ++---- .../java/controller/DefaultController.java | 9 +++------ .../java/controller/UserCreateController.java | 2 +- .../java/controller/UserListController.java | 3 +-- .../java/controller/UserLoginController.java | 4 +--- .../java/controller/model/HttpRequest.java | 18 +++++++++++++++++- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index d437b592c..746963381 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -19,15 +19,13 @@ private ControllerConstructor() { } public static Controller getOf(HttpRequest request) { - final String method = request.get("Method"); - String path = request.get("Path"); - + final String method = request.getMethod(); + String path = request.getPath(); if (hasQueryString(path)) { path = subStringQueryString(path); } final Controller controller = pathAndControllers.get(method + " " + path); - return Objects.isNull(controller) ? DefaultController.getInstance() : controller; } diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index a1dbc1df4..34b38586e 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -24,28 +24,25 @@ public static Controller getInstance() { @Override public HttpResponse process(HttpRequest request) throws IOException { final String path = getPath(request); - final String mediaType = getMediaType(request); - final byte[] body = Files.readAllBytes(new File(STATIC_FILE_PATH + path).toPath()); return HttpResponse.builder() .status(200) - .header("Content-Type", mediaType + ";charset=utf-8") + .header("Content-Type", getMediaType(path) + ";charset=utf-8") .header("Content-Length", body.length) .body(body) .build(); } private String getPath(HttpRequest request) { - final String path = request.get("Path"); + final String path = request.getPath(); if (path.equals("/")) { return "/index.html"; } return path; } - private String getMediaType(HttpRequest request) { - final String path = request.get("Path"); + private String getMediaType(String path) { final String fileType = path.substring(path.lastIndexOf('.') + 1); switch (fileType) { diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index c75caf40d..d962780ef 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -23,7 +23,7 @@ public static Controller getInstance() { @Override public HttpResponse process(HttpRequest request) { - final Map content = parseQueryString(request.get("body")); + final Map content = request.getParsedBody(); final User newUser = new User(content); log.info("Create User: {}", newUser); diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 36537f7b2..4559d2705 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -26,8 +26,7 @@ public static Controller getInstance() { public HttpResponse process(HttpRequest request) { boolean logined = false; try { - final String cookie = request.get("Cookie"); - final Map cookies = parseCookies(cookie); + final Map cookies = request.getCookies(); logined = Boolean.parseBoolean(cookies.get("logined")); } catch (NullPointerException e) { log.info("invalid cookie"); diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index bf29e1c21..80d070f84 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -9,8 +9,6 @@ import java.util.Map; -import static util.HttpRequestUtils.parseQueryString; - class UserLoginController implements Controller { private static final Controller instance = new UserLoginController(); private static final Logger log = LoggerFactory.getLogger(UserLoginController.class); @@ -24,7 +22,7 @@ public static Controller getInstance() { @Override public HttpResponse process(HttpRequest request) { - final Map content = parseQueryString(request.get("body")); + final Map content = request.getParsedBody(); final User user = DataBase.findUserById(content.get("userId")); if (isLoginFailed(content, user)) { diff --git a/src/main/java/controller/model/HttpRequest.java b/src/main/java/controller/model/HttpRequest.java index 1f1d20f5b..7a586c470 100644 --- a/src/main/java/controller/model/HttpRequest.java +++ b/src/main/java/controller/model/HttpRequest.java @@ -11,7 +11,7 @@ import java.util.Map; import java.util.Objects; -import static util.HttpRequestUtils.parseHeader; +import static util.HttpRequestUtils.*; public class HttpRequest { private final Map requestInfo; @@ -69,4 +69,20 @@ private void parseBody(BufferedReader bufferedReader, int contentLength) throws public String get(String key) { return requestInfo.get(key); } + + public String getPath() { + return requestInfo.get("Path"); + } + + public String getMethod() { + return requestInfo.get("Method"); + } + + public Map getCookies() { + return parseCookies(requestInfo.get("Cookie")); + } + + public Map getParsedBody() { + return parseQueryString(requestInfo.get("body")); + } } From 8fa791fcdc40c21903dc105307ee96d5e062ee52 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:43:45 +0900 Subject: [PATCH 35/65] =?UTF-8?q?UserListController=20private=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/UserListController.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 4559d2705..f3ca000ea 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -24,23 +24,11 @@ public static Controller getInstance() { @Override public HttpResponse process(HttpRequest request) { - boolean logined = false; - try { - final Map cookies = request.getCookies(); - logined = Boolean.parseBoolean(cookies.get("logined")); - } catch (NullPointerException e) { - log.info("invalid cookie"); - } + boolean logined = isLogined(request); if (logined) { log.info("Login user"); - final Collection all = DataBase.findAll(); - final StringBuilder sb = new StringBuilder(); - for (User user : all) { - sb.append(user.getName()).append(": ").append(user.getEmail()).append("
"); - } - - final byte[] body = sb.toString().getBytes(); + final byte[] body = getUserListAsBytes(); return HttpResponse.builder() .status(200) @@ -56,4 +44,23 @@ public HttpResponse process(HttpRequest request) { .redirect("/user/login.html") .build(); } + + private boolean isLogined(HttpRequest request) { + try { + final Map cookies = request.getCookies(); + return Boolean.parseBoolean(cookies.get("logined")); + } catch (NullPointerException e) { + log.info("invalid cookie"); + return false; + } + } + + private byte[] getUserListAsBytes() { + final Collection all = DataBase.findAll(); + final StringBuilder sb = new StringBuilder(); + for (User user : all) { + sb.append(user.getName()).append(": ").append(user.getEmail()).append("
"); + } + return sb.toString().getBytes(); + } } From 201484d977cb46d5c50c0019386d51ee11d7a6c9 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:44:44 +0900 Subject: [PATCH 36/65] =?UTF-8?q?else=20=EB=AC=B8=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=202=EB=B6=84=EA=B8=B0=20=EA=B0=95=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserListController.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index f3ca000ea..ede978892 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -29,20 +29,19 @@ public HttpResponse process(HttpRequest request) { if (logined) { log.info("Login user"); final byte[] body = getUserListAsBytes(); - return HttpResponse.builder() .status(200) .header("Content-Type", "text/html;charset=utf-8") .header("Content-Length", body.length) .body(body) .build(); + } else { + log.info("Logout user"); + return HttpResponse.builder() + .status(302) + .redirect("/user/login.html") + .build(); } - - log.info("Logout user"); - return HttpResponse.builder() - .status(302) - .redirect("/user/login.html") - .build(); } private boolean isLogined(HttpRequest request) { From 3219d68cf0b90662c25a0ff7c25df0b389d42800 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:45:23 +0900 Subject: [PATCH 37/65] =?UTF-8?q?else=20=EB=AC=B8=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=202=EB=B6=84=EA=B8=B0=20=EA=B0=95=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserLoginController.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 80d070f84..c30075d4f 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -32,14 +32,14 @@ public HttpResponse process(HttpRequest request) { .redirect("/user/login_failed.html") .cookie("logined", false) .build(); + } else { + log.debug("Login success: {}", user.getName()); + return HttpResponse.builder() + .status(302) + .redirect("/") + .cookie("logined", true) + .build(); } - - log.debug("Login success: {}", user.getName()); - return HttpResponse.builder() - .status(302) - .redirect("/") - .cookie("logined", true) - .build(); } private boolean isLoginFailed(Map content, User user) { From 2ff17ef23e4daba6c4b564e07089a261a5553699 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:48:54 +0900 Subject: [PATCH 38/65] =?UTF-8?q?if=20=EC=A1=B0=EA=B1=B4=EC=9D=84=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=EC=A1=B0=EA=B1=B4=20=EB=A8=BC=EC=A0=80=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/UserLoginController.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index c30075d4f..e847026c5 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -25,24 +25,24 @@ public HttpResponse process(HttpRequest request) { final Map content = request.getParsedBody(); final User user = DataBase.findUserById(content.get("userId")); - if (isLoginFailed(content, user)) { - log.debug("Login fail: {}", user == null ? "[No user]" : user.getName()); + if (isLoginSuccess(content, user)) { + log.debug("Login success: {}", user.getName()); return HttpResponse.builder() .status(302) - .redirect("/user/login_failed.html") - .cookie("logined", false) + .redirect("/") + .cookie("logined", true) .build(); } else { - log.debug("Login success: {}", user.getName()); + log.debug("Login fail: {}", user == null ? "[No user]" : user.getName()); return HttpResponse.builder() .status(302) - .redirect("/") - .cookie("logined", true) + .redirect("/user/login_failed.html") + .cookie("logined", false) .build(); } } - private boolean isLoginFailed(Map content, User user) { - return user == null || !user.getPassword().equals(content.get("password")); + private boolean isLoginSuccess(Map content, User user) { + return user != null && user.getPassword().equals(content.get("password")); } } From 0432530d66c5b3358e4aae8c703150c5a5927177 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 14:49:09 +0900 Subject: [PATCH 39/65] =?UTF-8?q?null=20=EA=B2=80=EC=82=AC=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/model/HttpResponse.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/controller/model/HttpResponse.java index e1bf2e374..706afa999 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -8,6 +8,7 @@ import java.io.OutputStream; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import static java.util.stream.Collectors.joining; @@ -48,7 +49,7 @@ private void writeHeader(DataOutputStream dos) { private void writeBody(DataOutputStream dos) { try { - if (body != null) { + if (Objects.nonNull(body)) { dos.write(body, 0, body.length); } dos.flush(); From a506a43564e8a1a8ba08a06946d2b52d8a2e91e1 Mon Sep 17 00:00:00 2001 From: siyoon Date: Fri, 26 Jun 2020 17:48:35 +0900 Subject: [PATCH 40/65] =?UTF-8?q?parseHttpMethodAndPath()=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/model/HttpRequest.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/controller/model/HttpRequest.java b/src/main/java/controller/model/HttpRequest.java index 7a586c470..d55b73cd1 100644 --- a/src/main/java/controller/model/HttpRequest.java +++ b/src/main/java/controller/model/HttpRequest.java @@ -18,11 +18,8 @@ public class HttpRequest { private HttpRequest(InputStream in) throws IOException { requestInfo = new HashMap<>(); - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); - int contentLength = parseHeaders(bufferedReader); - if (contentLength > 0) { parseBody(bufferedReader, contentLength); } @@ -41,10 +38,7 @@ private int parseHeaders(BufferedReader bufferedReader) throws IOException { } if (requestInfo.isEmpty()) { - final String[] s = line.split(" "); - requestInfo.put("Method", s[0]); - requestInfo.put("Path", s[1]); - requestInfo.put("Version", s[2]); + parseHttpMethodAndPath(line); continue; } @@ -53,14 +47,22 @@ private int parseHeaders(BufferedReader bufferedReader) throws IOException { continue; } + requestInfo.put(pair.getKey(), pair.getValue()); + if (pair.getKey().equals("Content-Length")) { contentLength = Integer.parseInt(pair.getValue()); } - requestInfo.put(pair.getKey(), pair.getValue()); } return contentLength; } + private void parseHttpMethodAndPath(String line) { + final String[] s = line.split(" "); + requestInfo.put("Method", s[0]); + requestInfo.put("Path", s[1]); + requestInfo.put("Version", s[2]); + } + private void parseBody(BufferedReader bufferedReader, int contentLength) throws IOException { String body = IOUtils.readData(bufferedReader, contentLength); requestInfo.put("body", body); From cc4be1d3c15ec40b8f2d122569ad185a12caac5f Mon Sep 17 00:00:00 2001 From: siyoon Date: Sat, 27 Jun 2020 19:31:49 +0900 Subject: [PATCH 41/65] =?UTF-8?q?=EC=B6=94=EC=83=81=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A1=9C=20=EC=9A=94=EC=B2=AD=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=EB=B6=84=ED=95=98=EC=97=AC=EC=84=9C=20doG?= =?UTF-8?q?et()=20doPost()=20=EB=B6=84=EA=B8=B0=EC=B2=98=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 무언가 사전 혹은 사후에 해야하는 AOP작업도 결국 이런식으로 구현 되었다는 사실! 잘 기억해서 상속에 베스트 예제로 삼자. --- .../java/controller/AbstractController.java | 29 +++++++++++++++++++ src/main/java/controller/Controller.java | 2 +- .../controller/ControllerConstructor.java | 8 ++--- .../java/controller/DefaultController.java | 4 +-- .../java/controller/UserCreateController.java | 4 +-- .../java/controller/UserListController.java | 4 +-- .../java/controller/UserLoginController.java | 4 +-- 7 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 src/main/java/controller/AbstractController.java diff --git a/src/main/java/controller/AbstractController.java b/src/main/java/controller/AbstractController.java new file mode 100644 index 000000000..e362885f7 --- /dev/null +++ b/src/main/java/controller/AbstractController.java @@ -0,0 +1,29 @@ +package controller; + +import controller.model.HttpRequest; +import controller.model.HttpResponse; + +import java.io.IOException; + +public abstract class AbstractController implements Controller { + public final HttpResponse process(HttpRequest httpRequest) throws IOException, IllegalAccessException { + final String method = httpRequest.getMethod(); + + switch (method) { + case "GET": + return doGet(httpRequest); + case "POST": + return doPost(httpRequest); + default: + throw new IllegalArgumentException("Illegal Http Method"); + } + } + + protected HttpResponse doGet(HttpRequest httpRequest) throws IOException, IllegalAccessException { + throw new IllegalAccessException("doGet() is not overridden."); + } + + protected HttpResponse doPost(HttpRequest httpRequest) throws IOException, IllegalAccessException { + throw new IllegalAccessException("doPost() is not overridden."); + } +} diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 79463ac09..34114f7c6 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -6,5 +6,5 @@ import java.io.IOException; public interface Controller { - HttpResponse process(HttpRequest httpRequest) throws IOException; + HttpResponse process(HttpRequest httpRequest) throws IOException, IllegalAccessException; } diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 746963381..fc75346d9 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -13,9 +13,9 @@ private ControllerConstructor() { } static { - pathAndControllers.put("POST /user/create", UserCreateController.getInstance()); - pathAndControllers.put("POST /user/login", UserLoginController.getInstance()); - pathAndControllers.put("GET /user/list", UserListController.getInstance()); + pathAndControllers.put("/user/create", UserCreateController.getInstance()); + pathAndControllers.put("/user/login", UserLoginController.getInstance()); + pathAndControllers.put("/user/list", UserListController.getInstance()); } public static Controller getOf(HttpRequest request) { @@ -25,7 +25,7 @@ public static Controller getOf(HttpRequest request) { path = subStringQueryString(path); } - final Controller controller = pathAndControllers.get(method + " " + path); + final Controller controller = pathAndControllers.get(path); return Objects.isNull(controller) ? DefaultController.getInstance() : controller; } diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 34b38586e..b7119dced 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -9,7 +9,7 @@ import java.io.IOException; import java.nio.file.Files; -class DefaultController implements Controller { +class DefaultController extends AbstractController { private static final Controller instance = new DefaultController(); private static final Logger log = LoggerFactory.getLogger(DefaultController.class); private static final String STATIC_FILE_PATH = "./webapp"; @@ -22,7 +22,7 @@ public static Controller getInstance() { } @Override - public HttpResponse process(HttpRequest request) throws IOException { + protected HttpResponse doGet(HttpRequest request) throws IOException { final String path = getPath(request); final byte[] body = Files.readAllBytes(new File(STATIC_FILE_PATH + path).toPath()); diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index d962780ef..bb1c91a88 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -11,7 +11,7 @@ import static util.HttpRequestUtils.parseQueryString; -class UserCreateController implements Controller { +class UserCreateController extends AbstractController { private static final Controller instance = new UserCreateController(); private static final Logger log = LoggerFactory.getLogger(UserCreateController.class); @@ -22,7 +22,7 @@ public static Controller getInstance() { } @Override - public HttpResponse process(HttpRequest request) { + protected HttpResponse doPost(HttpRequest request) { final Map content = request.getParsedBody(); final User newUser = new User(content); diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index ede978892..e71d239ec 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -12,7 +12,7 @@ import static util.HttpRequestUtils.parseCookies; -class UserListController implements Controller { +class UserListController extends AbstractController { private static final Controller instance = new UserListController(); private static final Logger log = LoggerFactory.getLogger(UserListController.class); @@ -23,7 +23,7 @@ public static Controller getInstance() { } @Override - public HttpResponse process(HttpRequest request) { + protected HttpResponse doGet(HttpRequest request) { boolean logined = isLogined(request); if (logined) { diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index e847026c5..1800edc19 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -9,7 +9,7 @@ import java.util.Map; -class UserLoginController implements Controller { +class UserLoginController extends AbstractController { private static final Controller instance = new UserLoginController(); private static final Logger log = LoggerFactory.getLogger(UserLoginController.class); @@ -21,7 +21,7 @@ public static Controller getInstance() { } @Override - public HttpResponse process(HttpRequest request) { + protected HttpResponse doPost(HttpRequest request) { final Map content = request.getParsedBody(); final User user = DataBase.findUserById(content.get("userId")); From 2572f117f016c6273d44c0502ac38c3146b45855 Mon Sep 17 00:00:00 2001 From: siyoon Date: Mon, 29 Jun 2020 11:10:30 +0900 Subject: [PATCH 42/65] =?UTF-8?q?HttpMethod=20=EB=A7=A4=EC=A7=81=EB=84=98?= =?UTF-8?q?=EB=B2=84=20enum=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/AbstractController.java | 7 ++++--- src/main/java/model/HttpMethod.java | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/main/java/model/HttpMethod.java diff --git a/src/main/java/controller/AbstractController.java b/src/main/java/controller/AbstractController.java index e362885f7..54da8ab61 100644 --- a/src/main/java/controller/AbstractController.java +++ b/src/main/java/controller/AbstractController.java @@ -2,17 +2,18 @@ import controller.model.HttpRequest; import controller.model.HttpResponse; +import model.HttpMethod; import java.io.IOException; public abstract class AbstractController implements Controller { public final HttpResponse process(HttpRequest httpRequest) throws IOException, IllegalAccessException { - final String method = httpRequest.getMethod(); + final HttpMethod method = HttpMethod.valueOf(httpRequest.getMethod()); switch (method) { - case "GET": + case GET: return doGet(httpRequest); - case "POST": + case POST: return doPost(httpRequest); default: throw new IllegalArgumentException("Illegal Http Method"); diff --git a/src/main/java/model/HttpMethod.java b/src/main/java/model/HttpMethod.java new file mode 100644 index 000000000..2716903b4 --- /dev/null +++ b/src/main/java/model/HttpMethod.java @@ -0,0 +1,6 @@ +package model; + +public enum HttpMethod { + GET, + POST +} From 2f0a64251b931c9d534822619f5183171a7fc99a Mon Sep 17 00:00:00 2001 From: siyoon Date: Mon, 29 Jun 2020 11:23:12 +0900 Subject: [PATCH 43/65] =?UTF-8?q?MediaType=20=EB=A7=A4=EC=A7=81=EB=84=98?= =?UTF-8?q?=EB=B2=84=20enum=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/DefaultController.java | 19 +------------- src/main/java/model/MediaType.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 src/main/java/model/MediaType.java diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index b7119dced..39ccfee06 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -44,23 +44,6 @@ private String getPath(HttpRequest request) { private String getMediaType(String path) { final String fileType = path.substring(path.lastIndexOf('.') + 1); - - switch (fileType) { - case "html": - return "text/html"; - case "css": - return "text/css"; - case "js": - return "text/javascript"; - case "png": - return "image/png"; - case "ico": - return "image/ico"; - case "woff": - return "font/woff"; - default: - log.debug("Can't find proper media-type: {}", fileType); - return "unknown"; - } + return getMediaType(fileType); } } diff --git a/src/main/java/model/MediaType.java b/src/main/java/model/MediaType.java new file mode 100644 index 000000000..96431a5c6 --- /dev/null +++ b/src/main/java/model/MediaType.java @@ -0,0 +1,25 @@ +package model; + +public enum MediaType { + HTML("text/html"), + CSS("text/css"), + JS("text/javascript"), + PNG("image/png"), + ICO("image/ico"), + WOFF("font/woff"); + + private final String mediaType; + + MediaType(String mediaType) { + this.mediaType = mediaType; + } + + public static String getMediaType(String fileType) { + try { + return valueOf(fileType.toUpperCase()).mediaType; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return "unknown"; + } + } +} From e523815847f3e09578eeaf41292f8f98cd108456 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 30 Jun 2020 10:01:05 +0900 Subject: [PATCH 44/65] =?UTF-8?q?=EC=96=91=ED=8C=8C=203=EC=9E=A5=20TIL=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 235fddaea..09ddb4b63 100644 --- a/README.md +++ b/README.md @@ -15,22 +15,157 @@ * 각 요구사항을 구현하는 것이 중요한 것이 아니라 구현 과정을 통해 학습한 내용을 인식하는 것이 배움에 중요하다. ### 요구사항 1 - http://localhost:8080/index.html로 접속시 응답 -* +*네트워크 요청 받아드리기* +1. java.net.ServerSocket(portNumber)를 생성하면 해당포트로 연결되는 네트워크 접속을 감지한다. +2. (무한루프를 통해서) 소켓접속이 감지되면, 해당 소켓을 분석하여서 적절한 로직을 수행한다. +3. 소켓의 inputStream에는 요청정보들이 담겨있고, outputStream에 응답정보를 작성할 수 있다. ### 요구사항 2 - get 방식으로 회원가입 -* +* 요청 path에 queryString으로 정보들이 들어온다. ### 요구사항 3 - post 방식으로 회원가입 -* +*HTTP 프로토콜* +- 요청 +``` +GET /path HTTP/1.1 +Accept: application/json +Authorization: Bearer UExBMDFUMDRQV1MwMnzpdvtYYNWMSJ7CL8h0zM6q6a9ntw +... (`key: value` 형태의 헤더정보) +(빈줄) +...(바디정보) +``` + +- 응답 +``` +HTTP/1.1 200 OK +Date: Mon, 23 May 2005 22:38:34 GMT +Content-Type: text/html; charset=UTF-8 +Content-Encoding: UTF-8 +... (`key: value` 형태의 헤더정보) +(빈줄) +...(바디정보) +... +``` + +- (HTTP) 프로토콜이란, 결국 약속! 이다. *문자열*로 요청을 보내지만 클라이언트와 서버간에 *약속되어져 있는 형태*로 보내면 된다. 약속된 형태의 *문자열*을 클라이언트와 서버가 subString하여 파싱하고 정보를 추출하는 것이다. + - 예를들어 헤더정보는 반드시 `key: value` 형태여야 한다. 콜론뒤에 빈칸도 포함되어있어야 한다! + - 예를들어 순서는 반드시 `요청라인(첫줄)-헤더정보-빈줄-바디정보` 여야한다. + - 바디정보에 form 정보가 `key1=value1;key2=value2` 형태로 드러있다. ### 요구사항 4 - redirect 방식으로 이동 -* +* HTTP 응답라인(첫줄)에 status 코드가 300번대라면, 클라이언트에게 리다이렉트를 하라는 프로토콜이다. +* 헤더정보에 `Location: /redirect-url` 형태로 보내면 어떤 주소로 리다이렉트 해야하는지 클라이언트에게 알려줄 수 있다. +* *HTTP는 프로토콜(약속)* 이고, 실제 형태는 문자열일뿐이다. ### 요구사항 5 - cookie -* +* 요청 헤더에 `Cookie: key1=value1;key2=value2` 형태로 클라이언트가 가지고 있는 쿠키 값을 서버에게 보낸다. +* 응답 헤더에 `Set-Cookie: key1=value1;key2=value2` 형태로 서버가 클라이언트에게 쿠키 값을 설정하라고 알려준다. +* *HTTP는 프로토콜(약속)* 이고, 실제 형태는 문자열일뿐이다. ### 요구사항 6 - stylesheet 적용 -* +* 응답 헤더에 `Content-Type: text/css` 형태로 서버가 클라이언트에게 css 파일이라는 점을 알려준다. +* *HTTP는 프로토콜(약속)* 이고, 실제 형태는 문자열일뿐이다. + +### 설계적 영감 +- path를 매핑하는 작업에서 전략패턴을 적용하고 각 컨트롤러는 Constructor를 이용하여서 매핑해두었다 :thumbup: +- 컨트롤러들은 하나씩만 필요하여 싱글톤으로 만들었다. +- 스프링은 전략패턴과 싱글톤을 '쉽게' 구현하도록 도와준다. 그래서 개발자들이 이 패턴들을 사용하지 않아도 되는 편의가 생겼다. +- 싱글톤으로 분리하면, 이를 이용하면서 파생되는 DTO(Data,Domain..) 객체들이 *필연적으로* 만들어진다. 이를 잘 인지하고 분리하자! (HttpRuqest, HttpResponse) +- AOP같이 모든 작업들의 선작업 혹은 후작업이 필요하다면, 여기서 상속을 사용해보는 것을 고려해보자! (중복때문에 상속사용하는게 아니다. AOP를 구현하기 위함) + +### ec2 서버에 배포 후 +*EC2 접속하기* +1. chmod 400 jwp-book.pem + - 키파일 퍼미션을 400으로 두어야 ssh가 작동한다. (라고 aws에서 안내해줌) +2. ssh -i "jwp-book.pem" [ubuntu@ec2-13-124-248-99.ap-northeast-2.compute.amazonaws.com](mailto:ubuntu@ec2-13-124-248-99.ap-northeast-2.compute.amazonaws.com) + - ssh로 키파일을 이용하여서 ec2에 접속 + - ubuntu@ 는 계정명을 말하는것 같다. 뒤에 주소는 ec2에서 명시하는 퍼블릭IP + - 그래서 아마존 리눅스로 다시 만드니까 유저명이 ec2-user였고 ec2-user@로 해야 됐다! + +*한글 로케일 설정하기* +1. sudo locale-gen ko_KR.EUC-KR ko_KR.UTF-8 +2. sudo dpkg-reconfigure locales +3. .bash_profile 파일에 설정추가 + ``` + LANG="ko_KR.UTF-8" + LANGUAGE="ko_KR:ko:en_US:en" + ``` +4. source .bash_profile + +*JDK와 메이븐 설치하기* +1. wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" [https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz](https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz) + - jdk 다운로드 +2. gunzip openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz + - 압축풀기 gz +3. tar -xvf openjdk-8u41-b04-linux-x64-14_jan_2020.tar + - 압축풀기 tar (따로따로 풀어야하네) +4. ln -s java-se-8u41-ri/ java + - 압축푼 디렉토리 'java'로 심볼릭 링크 만들기 +5. 프로필 파일에 path 추가 (로케일 설정시에 사용했던 .bash_profile에다가 했다) + ``` + bash + export JAVA_HOME=~/java + export PATH=$PATH:$JAVA_HOME/bin + ``` + - JAVA_HOME에 (심볼릭 설정한) java 폴더 설정하고 + - PATH설정 추가! +6. source .bash_profile + - 설정 반영 +7. java -version + - path설정이 잘 되었나 확인 +8. wget [http://apache.mirror.cdnetworks.com/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz](http://apache.mirror.cdnetworks.com/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz) + - 메이븐 다운로드 +9. gunzip apache-maven-3.6.3-bin.tar.gz + - 압축풀기 +10. tar -xvf apache-maven-3.6.3-bin.tar + - 압축풀기 +11. 프로필 파일에 메이븐 path 추가 + ``` + bash + export JAVA_HOME=~/java + export MAVEN_HOME=~/maven + export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin + ``` +12. source .bash_profile +13. env + - 환경설정 확인 +14. mvn -version + - path 설정 잘 됐나 확인 + +*JDK, 메이븐 설치하기 (apt-get으로)* +- 이렇게 하니까 메이븐 에러가 안남.. 아니면 우분투 버전을 16버전으로 하니까 안나는 걸 수 도있어 +- sudo apt-get install openjdk-8-jdk +- sudo apt-get install maven + +*Git 설치하고 프로젝트 받기* +1. (sudo apt-get install git) + - 보통 설치가 되어있음 +2. git —version + - git 설치되었는지 확인 +3. git clone [https://github.com/siyoon210/web-application-server](https://github.com/siyoon210/web-application-server) + - 배포할 레포 git clone +4. mvn clean package + - 클론해온 레포 디렉토리 안에서 실행 + - 메이븐으로 삭제(clean) 후 빌드(package) + - 결과물은 target 디렉토리 안에 생김 +5. git clone [https://github.com/siyoon210/web-application-server](https://github.com/siyoon210/web-application-server) + - 배포할 레포 git clone +6. mvn clean package + - 클론해온 레포 디렉토리 안에서 실행 + - 메이븐으로 삭제(clean) 후 빌드(package) + - 결과물은 target 디렉토리 안에 생김 -### heroku 서버에 배포 후 -* \ No newline at end of file +*ec2 포트열기* +- ec2 정보에서 `보안그룹`을 선택한다. (보통 launch-wizard-4 이런식에 이름으로 되어있음) +- `사용자 지정 TCP` 8080(원하는 번호) 포트를 공개한다. (혹은 HTTP 80을 오픈해도 됨) + - 소스가 0.0.0.0/0, 이랑 ::/0 두개가 생기는데 뭔지는 잘 모르겠음 + +*빌드 배포하기* +- mvn clean package +- java -cp target/classes:target/dependecy/* webserver.Webserver 8080 +- 재배포하기 위해서 프로세스 끄기 + - ps -ef | grep webserver + - 실행한 프로세스 아이디(PID)를 찾고 + - kill -9 $PID + - 웹서버 종료 + - 위에 배포코드실행 \ No newline at end of file From 5e64036920863db4497ab1fb0531ed055d307543 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 30 Jun 2020 10:22:05 +0900 Subject: [PATCH 45/65] =?UTF-8?q?=EB=AF=B8=EC=82=AC=EC=9A=A9=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/ControllerConstructor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index fc75346d9..325212403 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -19,7 +19,6 @@ private ControllerConstructor() { } public static Controller getOf(HttpRequest request) { - final String method = request.getMethod(); String path = request.getPath(); if (hasQueryString(path)) { path = subStringQueryString(path); From 762e8a14b3ca58ca556aaf3b14526f435d749d94 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 30 Jun 2020 10:22:47 +0900 Subject: [PATCH 46/65] =?UTF-8?q?ReuqestHandler=EA=B0=80=20IllegalAccessEx?= =?UTF-8?q?ception=EB=8F=84=20=EC=BA=90=EC=B9=98=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 6f53231d2..a389fa09b 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -32,7 +32,7 @@ public void run() { final Controller controller = ControllerConstructor.getOf(httpRequest); final HttpResponse httpResponse = controller.process(httpRequest); httpResponse.write(out); - } catch (IOException e) { + } catch (IOException | IllegalAccessException e) { log.error(e.getMessage()); } } From 621fe167905077b2cb5ed0be0fd5762dfd037c5f Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 30 Jun 2020 22:57:26 +0900 Subject: [PATCH 47/65] =?UTF-8?q?HttpResponse=EC=97=90=20forawrd=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/DefaultController.java | 12 +----------- src/main/java/controller/UserListController.java | 3 ++- .../java/controller/UserLoginController.java | 3 ++- src/main/java/controller/model/HttpResponse.java | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index 39ccfee06..fa3885728 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -11,8 +11,6 @@ class DefaultController extends AbstractController { private static final Controller instance = new DefaultController(); - private static final Logger log = LoggerFactory.getLogger(DefaultController.class); - private static final String STATIC_FILE_PATH = "./webapp"; private DefaultController() { } @@ -24,13 +22,10 @@ public static Controller getInstance() { @Override protected HttpResponse doGet(HttpRequest request) throws IOException { final String path = getPath(request); - final byte[] body = Files.readAllBytes(new File(STATIC_FILE_PATH + path).toPath()); return HttpResponse.builder() .status(200) - .header("Content-Type", getMediaType(path) + ";charset=utf-8") - .header("Content-Length", body.length) - .body(body) + .forward(path) .build(); } @@ -41,9 +36,4 @@ private String getPath(HttpRequest request) { } return path; } - - private String getMediaType(String path) { - final String fileType = path.substring(path.lastIndexOf('.') + 1); - return getMediaType(fileType); - } } diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index e71d239ec..bec2fe92a 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.Collection; import java.util.Map; @@ -23,7 +24,7 @@ public static Controller getInstance() { } @Override - protected HttpResponse doGet(HttpRequest request) { + protected HttpResponse doGet(HttpRequest request) throws IOException { boolean logined = isLogined(request); if (logined) { diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 1800edc19..1472c2f17 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.Map; class UserLoginController extends AbstractController { @@ -21,7 +22,7 @@ public static Controller getInstance() { } @Override - protected HttpResponse doPost(HttpRequest request) { + protected HttpResponse doPost(HttpRequest request) throws IOException { final Map content = request.getParsedBody(); final User user = DataBase.findUserById(content.get("userId")); diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/controller/model/HttpResponse.java index 706afa999..d7233e7c9 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -1,11 +1,14 @@ package controller.model; +import model.MediaType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.DataOutputStream; +import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.nio.file.Files; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -14,6 +17,7 @@ public class HttpResponse { private static final Logger log = LoggerFactory.getLogger(HttpResponse.class); + private static final String STATIC_FILE_PATH = "./webapp"; private final int status; private final Map headers; @@ -94,6 +98,13 @@ public Builder redirect(String location) { return this; } + public Builder forward(String path) throws IOException { + body(Files.readAllBytes(new File(STATIC_FILE_PATH + path).toPath())); + header("Content-Type", getMediaType(path) + ";charset=utf-8"); + header("Content-Length", body.length); + return this; + } + public Builder body(byte[] body) { this.body = body; return this; @@ -104,6 +115,11 @@ public HttpResponse build() { return new HttpResponse(status, headers, body); } + private String getMediaType(String path) { + final String fileType = path.substring(path.lastIndexOf('.') + 1); + return MediaType.getMediaType(fileType); + } + private void putCookiesOnHeader() { if (cookies.isEmpty()) { return; From dff049868130d64dff7972793a29bab889457f98 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 7 Jul 2020 09:06:11 +0900 Subject: [PATCH 48/65] =?UTF-8?q?ThreadPoolExecutor=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=20=EC=93=B0=EB=A0=88=EB=93=9C=ED=92=80=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/WebServer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/webserver/WebServer.java b/src/main/java/webserver/WebServer.java index 3a34f98db..4d9aac835 100644 --- a/src/main/java/webserver/WebServer.java +++ b/src/main/java/webserver/WebServer.java @@ -2,7 +2,10 @@ import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import com.google.common.collect.Queues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,16 +21,14 @@ public static void main(String[] args) throws Exception { port = Integer.parseInt(args[0]); } - // 서버소켓을 생성한다. 웹서버는 기본적으로 8080번 포트를 사용한다. + final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 6, 5, TimeUnit.SECONDS, Queues.newLinkedBlockingQueue(6)); try (ServerSocket listenSocket = new ServerSocket(port)) { log.info("Web Application Server started {} port.", port); - // 클라이언트가 연결될때까지 대기한다. Socket connection; while ((connection = listenSocket.accept()) != null) { - RequestHandler requestHandler = new RequestHandler(connection); - requestHandler.start(); + threadPoolExecutor.execute(new RequestHandler(connection)); } } } From 3e43525d572441ef63b7604a5cc11b922dedce62 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 7 Jul 2020 09:27:24 +0900 Subject: [PATCH 49/65] =?UTF-8?q?=EC=98=88=EC=A0=9C=20String=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20HttpRequestTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/webserver/HttpRequestTest.java | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/java/webserver/HttpRequestTest.java diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java new file mode 100644 index 000000000..e643cea9d --- /dev/null +++ b/src/test/java/webserver/HttpRequestTest.java @@ -0,0 +1,33 @@ +package webserver; + +import controller.model.HttpRequest; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class HttpRequestTest { + @Test + public void request_POST() throws Exception { + //given + final String request = "POST /user/create HTTP/1.1\n" + + "Host: localhost:8080\n" + + "Connection: keep-alive\n" + + "Contetn-Length: 46\n" + + "Content-Type: application/x-www-form-urlencoded\n" + + "Accept: */*\n" + + "\n" + + "userId=puru&password=passoword&name=siyoon"; + + final InputStream in = new ByteArrayInputStream(request.getBytes()); + + //when + final HttpRequest httpRequest = HttpRequest.from(in); + + //then + assertThat(httpRequest.getMethod(), is("POST")); + } +} From fa0fa3e7eb8fdcccb5e5201ac81cff3312aceefe Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 7 Jul 2020 09:48:31 +0900 Subject: [PATCH 50/65] =?UTF-8?q?HttpReqeust=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 ++ .../java/controller/model/HttpRequest.java | 7 +++ src/test/java/webserver/HttpRequestTest.java | 55 +++++++++++++++---- 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 354b44d61..ea1ec9ecf 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,12 @@ 18.0 + + org.assertj + assertj-core + 3.16.1 + test + ch.qos.logback diff --git a/src/main/java/controller/model/HttpRequest.java b/src/main/java/controller/model/HttpRequest.java index d55b73cd1..8cb8aded7 100644 --- a/src/main/java/controller/model/HttpRequest.java +++ b/src/main/java/controller/model/HttpRequest.java @@ -87,4 +87,11 @@ public Map getCookies() { public Map getParsedBody() { return parseQueryString(requestInfo.get("body")); } + + @Override + public String toString() { + return "HttpRequest{" + + "requestInfo=" + requestInfo + + '}'; + } } diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java index e643cea9d..0ca63afaf 100644 --- a/src/test/java/webserver/HttpRequestTest.java +++ b/src/test/java/webserver/HttpRequestTest.java @@ -1,33 +1,64 @@ package webserver; import controller.model.HttpRequest; +import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; +import java.util.Map; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; public class HttpRequestTest { - @Test - public void request_POST() throws Exception { + private HttpRequest httpRequest; + + @BeforeEach + public void init() throws IOException { //given - final String request = "POST /user/create HTTP/1.1\n" - + "Host: localhost:8080\n" - + "Connection: keep-alive\n" - + "Contetn-Length: 46\n" + final String request = "POST /user/create HTTP/1.1\r\n" + + "Host: localhost:8080\r\n" + + "Connection: keep-alive\r\n" + + "Content-Length: 46\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Accept: */*\n" + "\n" - + "userId=puru&password=passoword&name=siyoon"; + + "userId=puru&password=1234&name=siyoon"; final InputStream in = new ByteArrayInputStream(request.getBytes()); //when - final HttpRequest httpRequest = HttpRequest.from(in); + this.httpRequest = HttpRequest.from(in); + } - //then - assertThat(httpRequest.getMethod(), is("POST")); + @Test + @DisplayName("HTTP요청에서 요청라인(HTTP메서드와 경로)를 파싱한다.") + public void getHttpMethodFromRequest() throws Exception { + assertThat(httpRequest.getMethod()).isEqualTo("POST"); + assertThat(httpRequest.getPath()).isEqualTo("/user/create"); + } + + @Test + @DisplayName("HTTP요청에서 헤더정보를 파싱한다.") + public void getHttpHeaderInfosFromRequest() throws Exception { + assertThat(httpRequest.get("Host")).isEqualTo("localhost:8080"); + assertThat(httpRequest.get("Connection")).isEqualTo("keep-alive"); + assertThat(httpRequest.get("Content-Length")).isEqualTo("46"); + assertThat(httpRequest.get("Content-Type")).isEqualTo("application/x-www-form-urlencoded"); + assertThat(httpRequest.get("Accept")).isEqualTo("*/*"); + } + + @Test + @DisplayName("HTTP요청에서 바디정보를 파싱한다.") + public void getHttpBodyInfosFromRequest() throws Exception { + final Map body = httpRequest.getParsedBody(); + assertThat(body).isNotNull(); + assertThat(body.get("userId")).isEqualTo("puru"); + assertThat(body.get("password")).isEqualTo("1234"); + assertThat(body.get("name")).isEqualTo("siyoon"); } } From 9f3384deac9c6e3a079bfe2ce129313af61583fe Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 7 Jul 2020 09:53:26 +0900 Subject: [PATCH 51/65] =?UTF-8?q?HttpReqeust=20=EC=BF=A0=ED=82=A4=ED=8C=8C?= =?UTF-8?q?=EC=8B=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/webserver/HttpRequestTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java index 0ca63afaf..7c482005b 100644 --- a/src/test/java/webserver/HttpRequestTest.java +++ b/src/test/java/webserver/HttpRequestTest.java @@ -26,6 +26,7 @@ public void init() throws IOException { + "Content-Length: 46\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Accept: */*\n" + + "Cookie: isLogined=false;cookie2=value2\n" + "\n" + "userId=puru&password=1234&name=siyoon"; @@ -52,6 +53,15 @@ public void getHttpHeaderInfosFromRequest() throws Exception { assertThat(httpRequest.get("Accept")).isEqualTo("*/*"); } + @Test + @DisplayName("HTTP요청에서 쿠키정보를 파싱한다.") + public void getHttpCookieInfosFromRequest() throws Exception { + final Map cookies = httpRequest.getCookies(); + assertThat(cookies).isNotNull(); + assertThat(cookies.get("isLogined")).isEqualTo("false"); + assertThat(cookies.get("cookie2")).isEqualTo("value2"); + } + @Test @DisplayName("HTTP요청에서 바디정보를 파싱한다.") public void getHttpBodyInfosFromRequest() throws Exception { From 350a7719512313af961e3463f51fe49f88745369 Mon Sep 17 00:00:00 2001 From: siyoon Date: Tue, 7 Jul 2020 09:58:51 +0900 Subject: [PATCH 52/65] =?UTF-8?q?HttpReqeust=20import=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94,=20=EC=9D=98=EB=AF=B8=EC=97=86=EB=8A=94=20throw=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/webserver/HttpRequestTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java index 7c482005b..757914701 100644 --- a/src/test/java/webserver/HttpRequestTest.java +++ b/src/test/java/webserver/HttpRequestTest.java @@ -1,7 +1,6 @@ package webserver; import controller.model.HttpRequest; -import org.junit.Before; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,9 +19,9 @@ public class HttpRequestTest { @BeforeEach public void init() throws IOException { //given - final String request = "POST /user/create HTTP/1.1\r\n" - + "Host: localhost:8080\r\n" - + "Connection: keep-alive\r\n" + final String request = "POST /user/create HTTP/1.1\n" + + "Host: localhost:8080\n" + + "Connection: keep-alive\n" + "Content-Length: 46\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Accept: */*\n" @@ -38,14 +37,14 @@ public void init() throws IOException { @Test @DisplayName("HTTP요청에서 요청라인(HTTP메서드와 경로)를 파싱한다.") - public void getHttpMethodFromRequest() throws Exception { + public void getHttpMethodFromRequest() { assertThat(httpRequest.getMethod()).isEqualTo("POST"); assertThat(httpRequest.getPath()).isEqualTo("/user/create"); } @Test @DisplayName("HTTP요청에서 헤더정보를 파싱한다.") - public void getHttpHeaderInfosFromRequest() throws Exception { + public void getHttpHeaderInfosFromRequest() { assertThat(httpRequest.get("Host")).isEqualTo("localhost:8080"); assertThat(httpRequest.get("Connection")).isEqualTo("keep-alive"); assertThat(httpRequest.get("Content-Length")).isEqualTo("46"); @@ -55,7 +54,7 @@ public void getHttpHeaderInfosFromRequest() throws Exception { @Test @DisplayName("HTTP요청에서 쿠키정보를 파싱한다.") - public void getHttpCookieInfosFromRequest() throws Exception { + public void getHttpCookieInfosFromRequest() { final Map cookies = httpRequest.getCookies(); assertThat(cookies).isNotNull(); assertThat(cookies.get("isLogined")).isEqualTo("false"); @@ -64,7 +63,7 @@ public void getHttpCookieInfosFromRequest() throws Exception { @Test @DisplayName("HTTP요청에서 바디정보를 파싱한다.") - public void getHttpBodyInfosFromRequest() throws Exception { + public void getHttpBodyInfosFromRequest() { final Map body = httpRequest.getParsedBody(); assertThat(body).isNotNull(); assertThat(body.get("userId")).isEqualTo("puru"); From 9b8400443fab960fd5bc73b4115c2b7b6e0cdd59 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 09:32:58 +0900 Subject: [PATCH 53/65] =?UTF-8?q?uuid=20=EC=83=9D=EC=84=B1=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/util/UUIDTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/java/util/UUIDTest.java diff --git a/src/test/java/util/UUIDTest.java b/src/test/java/util/UUIDTest.java new file mode 100644 index 000000000..08239fd1c --- /dev/null +++ b/src/test/java/util/UUIDTest.java @@ -0,0 +1,12 @@ +package util; + +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +public class UUIDTest { + @Test + public void uuid() { + System.out.println("UUID.randomUUID() = " + UUID.randomUUID()); + } +} From 972385429f8a796a27100a6912f9f7e23fea8e96 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 15:23:36 +0900 Subject: [PATCH 54/65] =?UTF-8?q?=EC=BF=A0=ED=82=A4=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=EC=84=9C=20=EC=84=B8=EC=85=98?= =?UTF-8?q?=ED=82=A4=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/model/HttpResponse.java | 7 +++++++ src/main/java/webserver/RequestHandler.java | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/controller/model/HttpResponse.java index d7233e7c9..e04f81035 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/controller/model/HttpResponse.java @@ -12,6 +12,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.UUID; import static java.util.stream.Collectors.joining; @@ -33,6 +34,12 @@ public static Builder builder() { return new Builder(); } + public HttpResponse addCookie(String key, UUID uuid) { + final String cookieAsString = key + "=" + uuid; + headers.merge("Set-Cookie", cookieAsString, (existedValue, newValue) -> existedValue + ";" + cookieAsString); + return this; + } + public void write(OutputStream out) { DataOutputStream dos = new DataOutputStream(out); writeHeader(dos); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index a389fa09b..303a97421 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -11,6 +11,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import java.util.Map; +import java.util.UUID; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -31,6 +33,12 @@ public void run() { final HttpRequest httpRequest = HttpRequest.from(in); final Controller controller = ControllerConstructor.getOf(httpRequest); final HttpResponse httpResponse = controller.process(httpRequest); + + final Map cookies = httpRequest.getCookies(); + if (cookies == null || cookies.get("JSESSIONID") == null) { + httpResponse.addCookie("JSESSIONID", UUID.randomUUID()); + } + httpResponse.write(out); } catch (IOException | IllegalAccessException e) { log.error(e.getMessage()); From c3f19f68851620e7c3005ae4e4c313ca893ddf6f Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 15:24:24 +0900 Subject: [PATCH 55/65] =?UTF-8?q?controller.model=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20webserver=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=ED=95=98=EC=9C=84=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/AbstractController.java | 4 ++-- src/main/java/controller/Controller.java | 4 ++-- src/main/java/controller/ControllerConstructor.java | 2 +- src/main/java/controller/DefaultController.java | 8 ++------ src/main/java/controller/UserCreateController.java | 6 ++---- src/main/java/controller/UserListController.java | 6 ++---- src/main/java/controller/UserLoginController.java | 4 ++-- src/main/java/webserver/RequestHandler.java | 4 ++-- .../java/{controller => webserver}/model/HttpRequest.java | 2 +- .../{controller => webserver}/model/HttpResponse.java | 2 +- src/test/java/webserver/HttpRequestTest.java | 2 +- 11 files changed, 18 insertions(+), 26 deletions(-) rename src/main/java/{controller => webserver}/model/HttpRequest.java (99%) rename src/main/java/{controller => webserver}/model/HttpResponse.java (99%) diff --git a/src/main/java/controller/AbstractController.java b/src/main/java/controller/AbstractController.java index 54da8ab61..c186c2baf 100644 --- a/src/main/java/controller/AbstractController.java +++ b/src/main/java/controller/AbstractController.java @@ -1,7 +1,7 @@ package controller; -import controller.model.HttpRequest; -import controller.model.HttpResponse; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; import model.HttpMethod; import java.io.IOException; diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 34114f7c6..70169e297 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,7 +1,7 @@ package controller; -import controller.model.HttpRequest; -import controller.model.HttpResponse; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; import java.io.IOException; diff --git a/src/main/java/controller/ControllerConstructor.java b/src/main/java/controller/ControllerConstructor.java index 325212403..0bd0a1dc5 100644 --- a/src/main/java/controller/ControllerConstructor.java +++ b/src/main/java/controller/ControllerConstructor.java @@ -1,6 +1,6 @@ package controller; -import controller.model.HttpRequest; +import webserver.model.HttpRequest; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java index fa3885728..9487088e8 100644 --- a/src/main/java/controller/DefaultController.java +++ b/src/main/java/controller/DefaultController.java @@ -1,13 +1,9 @@ package controller; -import controller.model.HttpRequest; -import controller.model.HttpResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; -import java.io.File; import java.io.IOException; -import java.nio.file.Files; class DefaultController extends AbstractController { private static final Controller instance = new DefaultController(); diff --git a/src/main/java/controller/UserCreateController.java b/src/main/java/controller/UserCreateController.java index bb1c91a88..5dc521752 100644 --- a/src/main/java/controller/UserCreateController.java +++ b/src/main/java/controller/UserCreateController.java @@ -1,16 +1,14 @@ package controller; -import controller.model.HttpRequest; +import webserver.model.HttpRequest; import db.DataBase; -import controller.model.HttpResponse; +import webserver.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; -import static util.HttpRequestUtils.parseQueryString; - class UserCreateController extends AbstractController { private static final Controller instance = new UserCreateController(); private static final Logger log = LoggerFactory.getLogger(UserCreateController.class); diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index bec2fe92a..76a25d78d 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,8 +1,8 @@ package controller; -import controller.model.HttpRequest; +import webserver.model.HttpRequest; import db.DataBase; -import controller.model.HttpResponse; +import webserver.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,8 +11,6 @@ import java.util.Collection; import java.util.Map; -import static util.HttpRequestUtils.parseCookies; - class UserListController extends AbstractController { private static final Controller instance = new UserListController(); private static final Logger log = LoggerFactory.getLogger(UserListController.class); diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index 1472c2f17..c1e31607e 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -1,8 +1,8 @@ package controller; -import controller.model.HttpRequest; +import webserver.model.HttpRequest; import db.DataBase; -import controller.model.HttpResponse; +import webserver.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 303a97421..41aa7abac 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,8 +2,8 @@ import controller.Controller; import controller.ControllerConstructor; -import controller.model.HttpRequest; -import controller.model.HttpResponse; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/controller/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java similarity index 99% rename from src/main/java/controller/model/HttpRequest.java rename to src/main/java/webserver/model/HttpRequest.java index 8cb8aded7..bdf6aaffd 100644 --- a/src/main/java/controller/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -1,4 +1,4 @@ -package controller.model; +package webserver.model; import util.HttpRequestUtils; import util.IOUtils; diff --git a/src/main/java/controller/model/HttpResponse.java b/src/main/java/webserver/model/HttpResponse.java similarity index 99% rename from src/main/java/controller/model/HttpResponse.java rename to src/main/java/webserver/model/HttpResponse.java index e04f81035..91d14607b 100644 --- a/src/main/java/controller/model/HttpResponse.java +++ b/src/main/java/webserver/model/HttpResponse.java @@ -1,4 +1,4 @@ -package controller.model; +package webserver.model; import model.MediaType; import org.slf4j.Logger; diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java index 757914701..b2653c092 100644 --- a/src/test/java/webserver/HttpRequestTest.java +++ b/src/test/java/webserver/HttpRequestTest.java @@ -1,6 +1,6 @@ package webserver; -import controller.model.HttpRequest; +import webserver.model.HttpRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 3b0ec62503ab1a1cb2a69e40385378f35a7206a3 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 15:56:09 +0900 Subject: [PATCH 56/65] =?UTF-8?q?HttpCookie=20=EC=9D=BC=EA=B8=89=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/UserListController.java | 3 +- src/main/java/webserver/RequestHandler.java | 3 +- src/main/java/webserver/model/HttpCookie.java | 17 +++++++++ .../java/webserver/model/HttpRequest.java | 4 +- src/test/java/webserver/HttpCookieTest.java | 37 +++++++++++++++++++ src/test/java/webserver/HttpRequestTest.java | 3 +- 6 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/main/java/webserver/model/HttpCookie.java create mode 100644 src/test/java/webserver/HttpCookieTest.java diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 76a25d78d..97771fc40 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,5 +1,6 @@ package controller; +import webserver.model.HttpCookie; import webserver.model.HttpRequest; import db.DataBase; import webserver.model.HttpResponse; @@ -45,7 +46,7 @@ protected HttpResponse doGet(HttpRequest request) throws IOException { private boolean isLogined(HttpRequest request) { try { - final Map cookies = request.getCookies(); + final HttpCookie cookies = request.getCookies(); return Boolean.parseBoolean(cookies.get("logined")); } catch (NullPointerException e) { log.info("invalid cookie"); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 41aa7abac..e05cdb9e8 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,6 +2,7 @@ import controller.Controller; import controller.ControllerConstructor; +import webserver.model.HttpCookie; import webserver.model.HttpRequest; import webserver.model.HttpResponse; import org.slf4j.Logger; @@ -34,7 +35,7 @@ public void run() { final Controller controller = ControllerConstructor.getOf(httpRequest); final HttpResponse httpResponse = controller.process(httpRequest); - final Map cookies = httpRequest.getCookies(); + final HttpCookie cookies = httpRequest.getCookies(); if (cookies == null || cookies.get("JSESSIONID") == null) { httpResponse.addCookie("JSESSIONID", UUID.randomUUID()); } diff --git a/src/main/java/webserver/model/HttpCookie.java b/src/main/java/webserver/model/HttpCookie.java new file mode 100644 index 000000000..ba4a3e7b8 --- /dev/null +++ b/src/main/java/webserver/model/HttpCookie.java @@ -0,0 +1,17 @@ +package webserver.model; + +import java.util.Map; + +import static util.HttpRequestUtils.parseCookies; + +public class HttpCookie { + private final Map cookies; + + public HttpCookie(String cookieAsString) { + this.cookies = parseCookies(cookieAsString); + } + + public String get(String key) { + return cookies.get(key); + } +} diff --git a/src/main/java/webserver/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java index bdf6aaffd..aac2c11ef 100644 --- a/src/main/java/webserver/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -80,8 +80,8 @@ public String getMethod() { return requestInfo.get("Method"); } - public Map getCookies() { - return parseCookies(requestInfo.get("Cookie")); + public HttpCookie getCookies() { + return new HttpCookie(requestInfo.get("Cookie")); } public Map getParsedBody() { diff --git a/src/test/java/webserver/HttpCookieTest.java b/src/test/java/webserver/HttpCookieTest.java new file mode 100644 index 000000000..545b2331b --- /dev/null +++ b/src/test/java/webserver/HttpCookieTest.java @@ -0,0 +1,37 @@ +package webserver; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import webserver.model.HttpCookie; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +public class HttpCookieTest { + @Test + @DisplayName("문자열 쿠키값으로 HttpCookie로 파싱하기") + public void createHttpCookie() { + //given + String cookieAsString = "key1=value1;key2=value2"; + + //when + final HttpCookie httpCookie = new HttpCookie(cookieAsString); + + //then + assertThat(httpCookie.get("key1")).isEqualTo("value1"); + assertThat(httpCookie.get("key2")).isEqualTo("value2"); + assertThat(httpCookie.get("key3")).isEqualTo(null); + } + + @Test + @DisplayName("빈 문자열 쿠키값으로 HttpCookie로 파싱하면 객체만 반환되고 아무 값도 담지 않는다.") + public void createHttpCookieByNull() { + //given + String cookieAsString = null; + + //when + final HttpCookie httpCookie = new HttpCookie(cookieAsString); + + //then + assertThat(httpCookie).isNotNull(); + } +} diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java index b2653c092..75dcfbf4e 100644 --- a/src/test/java/webserver/HttpRequestTest.java +++ b/src/test/java/webserver/HttpRequestTest.java @@ -1,5 +1,6 @@ package webserver; +import webserver.model.HttpCookie; import webserver.model.HttpRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -55,7 +56,7 @@ public void getHttpHeaderInfosFromRequest() { @Test @DisplayName("HTTP요청에서 쿠키정보를 파싱한다.") public void getHttpCookieInfosFromRequest() { - final Map cookies = httpRequest.getCookies(); + final HttpCookie cookies = httpRequest.getCookies(); assertThat(cookies).isNotNull(); assertThat(cookies.get("isLogined")).isEqualTo("false"); assertThat(cookies.get("cookie2")).isEqualTo("value2"); From 33d640c7837a60f1b689bf79089663349aeb6fc0 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 16:08:05 +0900 Subject: [PATCH 57/65] =?UTF-8?q?=EB=AC=B4=EC=9D=98=EB=AF=B8=ED=95=9C=20nu?= =?UTF-8?q?ll=EC=B2=B4=ED=81=AC=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index e05cdb9e8..fb5400ff1 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -36,7 +36,7 @@ public void run() { final HttpResponse httpResponse = controller.process(httpRequest); final HttpCookie cookies = httpRequest.getCookies(); - if (cookies == null || cookies.get("JSESSIONID") == null) { + if (cookies.get("JSESSIONID") == null) { httpResponse.addCookie("JSESSIONID", UUID.randomUUID()); } From 985b01713fe8d4670c445518b8ea1d1b191b2ff1 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 16:20:30 +0900 Subject: [PATCH 58/65] =?UTF-8?q?UUID=EB=A5=BC=20id=EB=A1=9C=20=ED=95=98?= =?UTF-8?q?=EB=8A=94=20httpSession=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/webserver/model/HttpSession.java | 26 ++++++++++++++++ .../java/webserver/model/HttpSessions.java | 30 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/main/java/webserver/model/HttpSession.java create mode 100644 src/main/java/webserver/model/HttpSessions.java diff --git a/src/main/java/webserver/model/HttpSession.java b/src/main/java/webserver/model/HttpSession.java new file mode 100644 index 000000000..9a05a8834 --- /dev/null +++ b/src/main/java/webserver/model/HttpSession.java @@ -0,0 +1,26 @@ +package webserver.model; + +import java.util.HashMap; +import java.util.Map; + +public class HttpSession { + private final Map value; + private final String id; + + public HttpSession(String id) { + this.value = new HashMap<>(); + this.id = id; + } + + public void set(String key, Object value) { + this.value.put(key, value); + } + + public Object get(String key) { + return value.get(key); + } + + public void remove(String key) { + value.remove(key); + } +} diff --git a/src/main/java/webserver/model/HttpSessions.java b/src/main/java/webserver/model/HttpSessions.java new file mode 100644 index 000000000..2eae68386 --- /dev/null +++ b/src/main/java/webserver/model/HttpSessions.java @@ -0,0 +1,30 @@ +package webserver.model; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +public class HttpSessions { + private static final Map sessions = new HashMap<>(); + + public static void set(String key, HttpSession session) { + sessions.put(key, session); + } + + public static HttpSession get(String key) { + HttpSession httpSession = sessions.get(key); + + if (Objects.isNull(httpSession)) { + final String id = UUID.randomUUID().toString(); + httpSession = new HttpSession(id); + set(id, httpSession); + } + + return httpSession; + } + + public static void remove(String key) { + sessions.remove(key); + } +} From a931009d4af80c070a6de9cb5b46dacf15bd1e90 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 17:32:05 +0900 Subject: [PATCH 59/65] =?UTF-8?q?getCookies=EC=8B=9C=EC=97=90=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20=EB=A7=A4=EB=B2=88=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/model/HttpRequest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/webserver/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java index aac2c11ef..91cdc2f72 100644 --- a/src/main/java/webserver/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -15,6 +15,7 @@ public class HttpRequest { private final Map requestInfo; + private HttpCookie httpCookie; private HttpRequest(InputStream in) throws IOException { requestInfo = new HashMap<>(); @@ -81,7 +82,11 @@ public String getMethod() { } public HttpCookie getCookies() { - return new HttpCookie(requestInfo.get("Cookie")); + if (Objects.isNull(httpCookie)) { + httpCookie = new HttpCookie(requestInfo.get("Cookie")); + } + + return httpCookie; } public Map getParsedBody() { From 88c1f1a51ffd01ce21869e6b8823fd3b86b5e86f Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 17:32:38 +0900 Subject: [PATCH 60/65] =?UTF-8?q?HttpRequest=EC=97=90=EC=84=9C=20HttpSessi?= =?UTF-8?q?on=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20getter=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/model/HttpRequest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/webserver/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java index 91cdc2f72..013123565 100644 --- a/src/main/java/webserver/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -89,6 +89,14 @@ public HttpCookie getCookies() { return httpCookie; } + public HttpSession getSession() { + final String jsessionid = httpCookie.get("JSESSIONID"); + if (jsessionid == null) { + return null; + } + return HttpSessions.get(jsessionid); + } + public Map getParsedBody() { return parseQueryString(requestInfo.get("body")); } From cd27a6df84b1c267d68d6af2d19caffc6c38b7d3 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 21:17:27 +0900 Subject: [PATCH 61/65] =?UTF-8?q?"JSESSIONID"=20=EB=A7=A4=EC=A7=81?= =?UTF-8?q?=EB=84=98=EB=B2=84=20=EC=83=81=EC=88=98=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 16 ++++++++++------ src/main/java/webserver/model/HttpRequest.java | 6 +++--- src/main/java/webserver/model/HttpSession.java | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index fb5400ff1..48aa4ac2d 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -7,12 +7,14 @@ import webserver.model.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import webserver.model.HttpSession; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Map; +import java.util.Objects; import java.util.UUID; public class RequestHandler extends Thread { @@ -34,15 +36,17 @@ public void run() { final HttpRequest httpRequest = HttpRequest.from(in); final Controller controller = ControllerConstructor.getOf(httpRequest); final HttpResponse httpResponse = controller.process(httpRequest); - - final HttpCookie cookies = httpRequest.getCookies(); - if (cookies.get("JSESSIONID") == null) { - httpResponse.addCookie("JSESSIONID", UUID.randomUUID()); - } - + checkSessionId(httpRequest, httpResponse); httpResponse.write(out); } catch (IOException | IllegalAccessException e) { log.error(e.getMessage()); } } + + private void checkSessionId(HttpRequest httpRequest, HttpResponse httpResponse) { + final HttpCookie cookies = httpRequest.getCookies(); + if (Objects.isNull(cookies.get(HttpSession.SESSION_ID_KEY))) { + httpResponse.addCookie(HttpSession.SESSION_ID_KEY, UUID.randomUUID()); + } + } } diff --git a/src/main/java/webserver/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java index 013123565..445585b88 100644 --- a/src/main/java/webserver/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -90,9 +90,9 @@ public HttpCookie getCookies() { } public HttpSession getSession() { - final String jsessionid = httpCookie.get("JSESSIONID"); - if (jsessionid == null) { - return null; + final String jsessionid = httpCookie.get(HttpSession.SESSION_ID_KEY); + if (Objects.isNull(jsessionid)) { + throw new IllegalStateException("Session ID dose not exist."); } return HttpSessions.get(jsessionid); } diff --git a/src/main/java/webserver/model/HttpSession.java b/src/main/java/webserver/model/HttpSession.java index 9a05a8834..0b0f698a8 100644 --- a/src/main/java/webserver/model/HttpSession.java +++ b/src/main/java/webserver/model/HttpSession.java @@ -4,6 +4,7 @@ import java.util.Map; public class HttpSession { + public static final String SESSION_ID_KEY = "JSESSIONID"; private final Map value; private final String id; From 8f6b99ff6b9c46dee9e463ef511463be54e65dda Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 21:23:17 +0900 Subject: [PATCH 62/65] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20=EC=84=B8=EC=85=98?= =?UTF-8?q?=EC=97=90=20user=20=EC=A0=95=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserLoginController.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/controller/UserLoginController.java b/src/main/java/controller/UserLoginController.java index c1e31607e..5e6f38830 100644 --- a/src/main/java/controller/UserLoginController.java +++ b/src/main/java/controller/UserLoginController.java @@ -1,11 +1,12 @@ package controller; -import webserver.model.HttpRequest; import db.DataBase; -import webserver.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; +import webserver.model.HttpSession; import java.io.IOException; import java.util.Map; @@ -24,10 +25,12 @@ public static Controller getInstance() { @Override protected HttpResponse doPost(HttpRequest request) throws IOException { final Map content = request.getParsedBody(); + final HttpSession session = request.getSession(); final User user = DataBase.findUserById(content.get("userId")); if (isLoginSuccess(content, user)) { log.debug("Login success: {}", user.getName()); + session.set("user", user); return HttpResponse.builder() .status(302) .redirect("/") From 0ccaf27106d33590d91908e63a98e4b19faababc Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 22:09:27 +0900 Subject: [PATCH 63/65] =?UTF-8?q?httpCookie=EB=A5=BC=20getCookies()=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=84=9C=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/model/HttpRequest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/webserver/model/HttpRequest.java b/src/main/java/webserver/model/HttpRequest.java index 445585b88..1d7bf352c 100644 --- a/src/main/java/webserver/model/HttpRequest.java +++ b/src/main/java/webserver/model/HttpRequest.java @@ -11,7 +11,8 @@ import java.util.Map; import java.util.Objects; -import static util.HttpRequestUtils.*; +import static util.HttpRequestUtils.parseHeader; +import static util.HttpRequestUtils.parseQueryString; public class HttpRequest { private final Map requestInfo; @@ -90,7 +91,8 @@ public HttpCookie getCookies() { } public HttpSession getSession() { - final String jsessionid = httpCookie.get(HttpSession.SESSION_ID_KEY); + final HttpCookie cookies = getCookies(); + final String jsessionid = cookies.get(HttpSession.SESSION_ID_KEY); if (Objects.isNull(jsessionid)) { throw new IllegalStateException("Session ID dose not exist."); } From e4e42d298dd3ef35a1a544c08e267ee29f18d1b2 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 22:10:08 +0900 Subject: [PATCH 64/65] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=EC=B2=B4=ED=81=AC=EB=A5=BC=20=EC=84=B8=EC=85=98?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/UserListController.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java index 97771fc40..afb4425fc 100644 --- a/src/main/java/controller/UserListController.java +++ b/src/main/java/controller/UserListController.java @@ -1,16 +1,15 @@ package controller; -import webserver.model.HttpCookie; -import webserver.model.HttpRequest; import db.DataBase; -import webserver.model.HttpResponse; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import webserver.model.HttpRequest; +import webserver.model.HttpResponse; +import webserver.model.HttpSession; import java.io.IOException; import java.util.Collection; -import java.util.Map; class UserListController extends AbstractController { private static final Controller instance = new UserListController(); @@ -24,9 +23,7 @@ public static Controller getInstance() { @Override protected HttpResponse doGet(HttpRequest request) throws IOException { - boolean logined = isLogined(request); - - if (logined) { + if (isLogined(request)) { log.info("Login user"); final byte[] body = getUserListAsBytes(); return HttpResponse.builder() @@ -45,13 +42,9 @@ protected HttpResponse doGet(HttpRequest request) throws IOException { } private boolean isLogined(HttpRequest request) { - try { - final HttpCookie cookies = request.getCookies(); - return Boolean.parseBoolean(cookies.get("logined")); - } catch (NullPointerException e) { - log.info("invalid cookie"); - return false; - } + final HttpSession session = request.getSession(); + final Object user = session.get("user"); + return user != null; } private byte[] getUserListAsBytes() { From 450b7f6b159d11773c52525748e7c148ed97bb10 Mon Sep 17 00:00:00 2001 From: siyoon Date: Wed, 15 Jul 2020 22:10:57 +0900 Subject: [PATCH 65/65] =?UTF-8?q?bug:=20UUID=20=EC=9D=B8=EC=9E=90=EB=A1=9C?= =?UTF-8?q?=20=EB=B0=9B=EC=95=84=EC=98=A8=20=EA=B2=83=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/model/HttpSessions.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/webserver/model/HttpSessions.java b/src/main/java/webserver/model/HttpSessions.java index 2eae68386..ba21d16e2 100644 --- a/src/main/java/webserver/model/HttpSessions.java +++ b/src/main/java/webserver/model/HttpSessions.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.UUID; public class HttpSessions { private static final Map sessions = new HashMap<>(); @@ -12,13 +11,12 @@ public static void set(String key, HttpSession session) { sessions.put(key, session); } - public static HttpSession get(String key) { - HttpSession httpSession = sessions.get(key); + public static HttpSession get(String sessionId) { + HttpSession httpSession = sessions.get(sessionId); if (Objects.isNull(httpSession)) { - final String id = UUID.randomUUID().toString(); - httpSession = new HttpSession(id); - set(id, httpSession); + httpSession = new HttpSession(sessionId); + set(sessionId, httpSession); } return httpSession;