From ad7d250c1d369f3d8ccdd51c00b08a1703547d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:21:19 +0900 Subject: [PATCH 1/9] =?UTF-8?q?Modify=20-=20WebServer=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주석 위치 변경 --- src/main/java/webserver/WebServer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/webserver/WebServer.java b/src/main/java/webserver/WebServer.java index 91f4a0fbc..a06d2bebb 100644 --- a/src/main/java/webserver/WebServer.java +++ b/src/main/java/webserver/WebServer.java @@ -19,7 +19,6 @@ public static void main(String args[]) throws Exception { } // 서버소켓을 생성한다. 웹서버는 기본적으로 8080번 포트를 사용한다. - try (ServerSocket listenSocket = new ServerSocket(port)) { log.info("Web Application Server started {} port.", port); From 200387abfdc147129412b7f3d70d32f1df809e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:30:52 +0900 Subject: [PATCH 2/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit index.html 파일을 응답하도록 로직 추가 --- src/main/java/webserver/RequestHandler.java | 26 ++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 90195ec4e..5fddad33b 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,10 +1,8 @@ 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,13 +17,25 @@ public RequestHandler(Socket connectionSocket) { } public void run() { - log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), - connection.getPort()); try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. + BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); + String line = br.readLine(); + log.debug("===== request line : {} =====", line); // 요청 라인 + + if (line == null) { + return; + } + + String[] tokens = line.split(" "); + + while (!line.equals("")) { + line = br.readLine(); + log.debug("header : {}", line); + } + DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); + byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath()); response200Header(dos, body.length); responseBody(dos, body); } catch (IOException e) { From 1685fada1976335898fbb5e140615ac247d9cae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:35:56 +0900 Subject: [PATCH 3/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET 방식으로 회원가입을 요청한 사용자의 정보 출력 --- src/main/java/webserver/RequestHandler.java | 29 ++++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 5fddad33b..71df32f7e 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -3,9 +3,12 @@ import java.io.*; import java.net.Socket; import java.nio.file.Files; +import java.util.Map; +import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -34,10 +37,28 @@ public void run() { log.debug("header : {}", line); } - DataOutputStream dos = new DataOutputStream(out); - byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath()); - response200Header(dos, body.length); - responseBody(dos, body); + String url = tokens[1]; + + if (url.startsWith("/user/create")) { + int index = url.indexOf("?"); + String queryString = url.substring(index + 1); + Map params = HttpRequestUtils.parseQueryString(queryString); + + User user = new User( + params.get("userId"), + params.get("password"), + params.get("name"), + params.get("email") + ); + + log.debug("user : {}", user); + } else { + DataOutputStream dos = new DataOutputStream(out); + byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath()); + response200Header(dos, body.length); + responseBody(dos, body); + } + } catch (IOException e) { log.error(e.getMessage()); } From 22c929a716cd2a68a0e2e22997bf87cc5c2840c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:38:33 +0900 Subject: [PATCH 4/9] Modify #1 - form.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POST 방식의 회원가입 요청을 위해 form 태그의 method 속성을 post로 변경 --- webapp/user/form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 60a4bbea560c0c12400c0b89cdd246420f78db1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:43:21 +0900 Subject: [PATCH 5/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POST 방식으로 회원가입을 요청한 사용자의 정보를 출력 --- src/main/java/webserver/RequestHandler.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 71df32f7e..7bf904c90 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -9,6 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import util.HttpRequestUtils; +import util.IOUtils; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -31,18 +32,21 @@ public void run() { } String[] tokens = line.split(" "); - + int contentLength = 0; while (!line.equals("")) { line = br.readLine(); log.debug("header : {}", line); + + if (line.contains("Content-Length")) { + contentLength = getContentLength(line); + } } String url = tokens[1]; - if (url.startsWith("/user/create")) { - int index = url.indexOf("?"); - String queryString = url.substring(index + 1); - Map params = HttpRequestUtils.parseQueryString(queryString); + if (url.equals("/user/create")) { + String body = IOUtils.readData(br, contentLength); + Map params = HttpRequestUtils.parseQueryString(body); User user = new User( params.get("userId"), @@ -64,6 +68,12 @@ public void run() { } } + private int getContentLength(String line) { + String[] tokens = line.split(":"); + + return Integer.parseInt(tokens[1].trim()); + } + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { try { dos.writeBytes("HTTP/1.1 200 OK \r\n"); From b4fdd694600577ae13fc05e4c32ab45232a8b6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 15:48:43 +0900 Subject: [PATCH 6/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 회원가입 완료 후 /index.html 경로로 이동하도록 302 status code 적용 --- src/main/java/webserver/RequestHandler.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 7bf904c90..dc754ae10 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -56,6 +56,9 @@ public void run() { ); log.debug("user : {}", user); + + DataOutputStream dos = new DataOutputStream(out); + response302Header(dos, "/index.html"); } else { DataOutputStream dos = new DataOutputStream(out); byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath()); @@ -68,6 +71,16 @@ public void run() { } } + 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()); + } + } + private int getContentLength(String line) { String[] tokens = line.split(":"); From b635f2ce530141378317ec9b598a401a72ae5bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 16:29:37 +0900 Subject: [PATCH 7/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 회원가입을 한 사용자가 로그인을 수행할 수 있도록 로직 추가 --- src/main/java/webserver/RequestHandler.java | 44 ++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index dc754ae10..09fccb750 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -5,6 +5,7 @@ import java.nio.file.Files; import java.util.Map; +import db.DataBase; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,16 +55,31 @@ public void run() { params.get("name"), params.get("email") ); - + DataBase.addUser(user); log.debug("user : {}", user); DataOutputStream dos = new DataOutputStream(out); response302Header(dos, "/index.html"); + } else if (url.equals("/user/login")) { + String body = IOUtils.readData(br, contentLength); + Map params = HttpRequestUtils.parseQueryString(body); + + User user = DataBase.findUserById(params.get("userId")); + + if (user == null) { + responseResource(out, "/user/login_failed.html"); + return; + } + + if (user.getPassword().equals(params.get("password"))) { + DataOutputStream dos = new DataOutputStream(out); + response302LoginSuccessHeader(dos); + } else { + responseResource(out, "/user/login_failed.html"); + } + } else { - DataOutputStream dos = new DataOutputStream(out); - byte[] body = Files.readAllBytes(new File("./webapp" + tokens[1]).toPath()); - response200Header(dos, body.length); - responseBody(dos, body); + responseResource(out, url); } } catch (IOException e) { @@ -71,6 +87,24 @@ public void run() { } } + private void responseResource(OutputStream out, String url) throws IOException { + DataOutputStream dos = new DataOutputStream(out); + byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath()); + response200Header(dos, body.length); + responseBody(dos, body); + } + + private void response302LoginSuccessHeader(DataOutputStream dos) { + try { + dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); + dos.writeBytes("Set-Cookie: logined=true \r\n"); + dos.writeBytes("Location: /index.html \r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + private void response302Header(DataOutputStream dos, String url) { try { dos.writeBytes("HTTP/1.1 302 Redirect \r\n"); From f89538e2a46db4b401ede335547507ebc4d8e66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 16:43:32 +0900 Subject: [PATCH 8/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= 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, 42 insertions(+) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 09fccb750..ffb06eed2 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,7 +2,9 @@ import java.io.*; import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.Collection; import java.util.Map; import db.DataBase; @@ -12,6 +14,7 @@ import util.HttpRequestUtils; import util.IOUtils; + public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -34,6 +37,7 @@ public void run() { String[] tokens = line.split(" "); int contentLength = 0; + boolean logined = false; while (!line.equals("")) { line = br.readLine(); log.debug("header : {}", line); @@ -41,6 +45,10 @@ public void run() { if (line.contains("Content-Length")) { contentLength = getContentLength(line); } + + if (line.contains("Cookie")) { + logined = isLogin(line); + } } String url = tokens[1]; @@ -78,6 +86,28 @@ public void run() { responseResource(out, "/user/login_failed.html"); } + } else if (url.equals("/user/list")) { + if (!logined) { + responseResource(out, "/user/login.html"); + return; + } + + Collection users = DataBase.findAll(); + StringBuilder sb = new StringBuilder(); + sb.append(""); + for (User user : users) { + sb.append(""); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append(""); + } + sb.append("
" + user.getUserId() + "" + user.getName() + "" + user.getEmail() + "
"); + + byte[] body = sb.toString().getBytes(StandardCharsets.UTF_8); + DataOutputStream dos = new DataOutputStream(out); + response200Header(dos, body.length); + responseBody(dos, body); } else { responseResource(out, url); } @@ -87,6 +117,18 @@ public void run() { } } + private boolean isLogin(String line) { + String[] tokens = line.split(":"); + Map cookies = HttpRequestUtils.parseCookies(tokens[1].trim()); + String value = cookies.get("logined"); + + if (value == null) { + return false; + } + + return Boolean.parseBoolean(value); + } + private void responseResource(OutputStream out, String url) throws IOException { DataOutputStream dos = new DataOutputStream(out); byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath()); From 110e043d31c90d5155b8bbd7eab29727ab6ddd38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EB=B9=88=EC=98=81?= Date: Tue, 18 Oct 2022 17:16:28 +0900 Subject: [PATCH 9/9] =?UTF-8?q?Modify=20#1=20-=20RequestHandler=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS 요청에 응답하는 로직 추가 --- src/main/java/webserver/RequestHandler.java | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index ffb06eed2..2d9beae51 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -108,6 +108,11 @@ public void run() { DataOutputStream dos = new DataOutputStream(out); response200Header(dos, body.length); responseBody(dos, body); + } else if (url.endsWith(".css")) { + DataOutputStream dos = new DataOutputStream(out); + byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath()); + response200CssHeader(dos, body.length); + responseBody(dos, body); } else { responseResource(out, url); } @@ -117,6 +122,17 @@ public void run() { } } + private void response200CssHeader(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/css \r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + " \r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + private boolean isLogin(String line) { String[] tokens = line.split(":"); Map cookies = HttpRequestUtils.parseCookies(tokens[1].trim()); @@ -166,8 +182,8 @@ private int getContentLength(String line) { 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("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());