From b4b8690e17d2fd63dd6d42932df025f7b9f8871b Mon Sep 17 00:00:00 2001 From: MinKyoungSoo Date: Mon, 10 Apr 2017 21:20:33 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=9D=BC=EB=8B=A8=20=EB=8B=A8=EC=9D=BC=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=8F=8C=EC=95=84?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=A1=9C=EC=A7=81=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/webserver/RequestHandler.java | 119 +++++++++++++++++++- webapp/user/form.html | 2 +- 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 90195ec4e..852d43fb9 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,13 +1,25 @@ package webserver; +import java.io.BufferedReader; import java.io.DataOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import db.DataBase; +import model.User; 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); @@ -23,16 +35,87 @@ public void run() { connection.getPort()); try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { + BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); + + Map headers = getHeaders(br); + + String http_method = headers.get("Http_Method"); + String target_url = headers.get("Target_Url"); + // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); - response200Header(dos, body.length); + byte[] body = new byte[0]; + + if(target_url.equals("/user/create")) { + Map params = HttpRequestUtils.parseQueryString(IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length")))); + + User user = new User( + params.get("userId"), + params.get("password"), + params.get("name"), + params.get("email") + ); + + DataBase.addUser(user); + + response302Header(dos, "../../index.html"); + } else if (http_method.equals("POST") && target_url.equals("/user/login")) { + Map params = HttpRequestUtils.parseQueryString(IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length")))); + + User user = DataBase.findUserById(params.get("userId")); + + if(user.getPassword().equals(params.get("password"))) { + response302HeaderForCookie(dos, "../../index.html","logined=true"); + } else { + response302HeaderForCookie(dos, "./login_failed.html","logined=false"); + } + + } else if(target_url.equals("/user/list")) { + if(headers.get("Cookie").contains("logined=true")) { + response302Header(dos, "./list.html"); + } else { + response302Header(dos, "./login.html"); + } + } else { + body = Files.readAllBytes(new File("./webapp" + target_url).toPath()); + + if(target_url.contains(".css")) { + response200HeaderForCss(dos, body.length); + } else { + response200Header(dos, body.length); + } + } + responseBody(dos, body); } catch (IOException e) { log.error(e.getMessage()); } } + private Map getHeaders(BufferedReader br) throws IOException { + String line = br.readLine(); + + if(line == null) { + return null; + } + + Map headers = new HashMap<>(); + headers.put("Http_Method", line.split(" ")[0]); + headers.put("Target_Url", line.split(" ")[1]); + log.debug("Http_Method : {}", line.split(" ")[0]); + log.debug("Target_Url : {}", line.split(" ")[1]); + + while (!"".equals(line)) { + line = br.readLine(); + if(!"".equals(line)) { + headers.put(HttpRequestUtils.parseHeader(line).getKey(),HttpRequestUtils.parseHeader(line).getValue()); + log.debug("{} : {}", HttpRequestUtils.parseHeader(line).getKey(), HttpRequestUtils.parseHeader(line).getValue()); + } + } + + return headers; + } + private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { try { dos.writeBytes("HTTP/1.1 200 OK \r\n"); @@ -44,6 +127,38 @@ private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { } } + private void response302Header(DataOutputStream dos, String redirectUrl) { + try { + dos.writeBytes("HTTP/1.1 302 Found\r\n"); + dos.writeBytes(String.format("Location: %s\r\n", redirectUrl)); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void response302HeaderForCookie(DataOutputStream dos, String redirectUrl, String cookie) { + try { + dos.writeBytes("HTTP/1.1 302 Found\r\n"); + dos.writeBytes(String.format("Location: %s\r\n", redirectUrl)); + dos.writeBytes("Set-Cookie: " + cookie + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void response200HeaderForCss(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/css;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); diff --git a/webapp/user/form.html b/webapp/user/form.html index 96fe1bd3a..ac2249628 100644 --- a/webapp/user/form.html +++ b/webapp/user/form.html @@ -75,7 +75,7 @@
-
+
From 31daacb8eaa58771c993faa9337b2f1a1ea2b1da Mon Sep 17 00:00:00 2001 From: MinKyoungSoo Date: Thu, 13 Apr 2017 19:34:18 +0900 Subject: [PATCH 2/3] =?UTF-8?q?HttpRequest=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/model/User.java | 4 ++ src/main/java/webserver/HttpRequest.java | 50 +++++++++++++++ src/main/java/webserver/RequestHandler.java | 71 ++++++++++----------- 3 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 src/main/java/webserver/HttpRequest.java diff --git a/src/main/java/model/User.java b/src/main/java/model/User.java index b7abb7304..2ff841c2d 100644 --- a/src/main/java/model/User.java +++ b/src/main/java/model/User.java @@ -28,6 +28,10 @@ public String getName() { public String getEmail() { return email; } + + public static User build(String userId, String password, String name, String email) { + return new User(userId, password, name, email); + } @Override public String toString() { diff --git a/src/main/java/webserver/HttpRequest.java b/src/main/java/webserver/HttpRequest.java new file mode 100644 index 000000000..65c2a9d66 --- /dev/null +++ b/src/main/java/webserver/HttpRequest.java @@ -0,0 +1,50 @@ +package webserver; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class HttpRequest { + + private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + Map requestHeaders = new HashMap<>(); + + public HttpRequest(BufferedReader br) throws Exception { + String line = br.readLine(); + + if(line != null) { + requestHeaders.put("Http_Method", line.split(" ")[0]); + requestHeaders.put("Target_Url", line.split(" ")[1]); + log.debug("Http_Method : {}", line.split(" ")[0]); + log.debug("Target_Url : {}", line.split(" ")[1]); + + while (!"".equals(line)) { + line = br.readLine(); + if(!"".equals(line)) { + requestHeaders.put(HttpRequestUtils.parseHeader(line).getKey(),HttpRequestUtils.parseHeader(line).getValue()); + log.debug("{} : {}", HttpRequestUtils.parseHeader(line).getKey(), HttpRequestUtils.parseHeader(line).getValue()); + } + } + } else { + throw new Exception("헤더정보를 만들수 없습니다."); + } + } + + public String getHeader(String headerType) { + return requestHeaders.get(headerType); + } + + public String getHttpMethod() { + return requestHeaders.get("Http_Method"); + } + + public String getPath() { + return requestHeaders.get("Target_Url"); + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 852d43fb9..50818267a 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -37,41 +37,29 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); - Map headers = getHeaders(br); + HttpRequest httpRequest = new HttpRequest(br); - String http_method = headers.get("Http_Method"); - String target_url = headers.get("Target_Url"); + String http_method = httpRequest.getHttpMethod(); + String target_url = httpRequest.getPath(); // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. DataOutputStream dos = new DataOutputStream(out); byte[] body = new byte[0]; if(target_url.equals("/user/create")) { - Map params = HttpRequestUtils.parseQueryString(IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length")))); + addUserToDataBase(newUserFromParams(getPostData(br, Integer.parseInt(httpRequest.getHeader("Content-Length"))))); - User user = new User( - params.get("userId"), - params.get("password"), - params.get("name"), - params.get("email") - ); - - DataBase.addUser(user); - response302Header(dos, "../../index.html"); } else if (http_method.equals("POST") && target_url.equals("/user/login")) { - Map params = HttpRequestUtils.parseQueryString(IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length")))); - - User user = DataBase.findUserById(params.get("userId")); - - if(user.getPassword().equals(params.get("password"))) { + Map postData = getPostData(br, Integer.parseInt(httpRequest.getHeader("Content-Length"))); + if(isCorrectPassword(postData, findUserFromDataBase(postData.get("userId")))) { response302HeaderForCookie(dos, "../../index.html","logined=true"); } else { response302HeaderForCookie(dos, "./login_failed.html","logined=false"); } } else if(target_url.equals("/user/list")) { - if(headers.get("Cookie").contains("logined=true")) { + if(isLogined(httpRequest.getHeader("Cookie"))) { response302Header(dos, "./list.html"); } else { response302Header(dos, "./login.html"); @@ -87,33 +75,38 @@ public void run() { } responseBody(dos, body); - } catch (IOException e) { + } catch (Exception e) { log.error(e.getMessage()); } } - private Map getHeaders(BufferedReader br) throws IOException { - String line = br.readLine(); + private boolean isCorrectPassword(Map params, User user) { + return user.getPassword().equals(params.get("password")); + } - if(line == null) { - return null; - } + private boolean isLogined(String cookie) { + return cookie.contains("logined=true"); + } - Map headers = new HashMap<>(); - headers.put("Http_Method", line.split(" ")[0]); - headers.put("Target_Url", line.split(" ")[1]); - log.debug("Http_Method : {}", line.split(" ")[0]); - log.debug("Target_Url : {}", line.split(" ")[1]); - - while (!"".equals(line)) { - line = br.readLine(); - if(!"".equals(line)) { - headers.put(HttpRequestUtils.parseHeader(line).getKey(),HttpRequestUtils.parseHeader(line).getValue()); - log.debug("{} : {}", HttpRequestUtils.parseHeader(line).getKey(), HttpRequestUtils.parseHeader(line).getValue()); - } - } + private void addUserToDataBase(User user) { + DataBase.addUser(user); + } + + private User findUserFromDataBase(String userId) { + return DataBase.findUserById(userId); + } + + private User newUserFromParams(Map params) { + return User.build( + params.get("userId"), + params.get("password"), + params.get("name"), + params.get("email") + ); + } - return headers; + private Map getPostData(BufferedReader br, int contentLength) throws IOException { + return HttpRequestUtils.parseQueryString(IOUtils.readData(br, contentLength)); } private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { From 317234d2ef5bb88e2abe224f9093b2a8f9cae3ad Mon Sep 17 00:00:00 2001 From: MinKyoungSoo Date: Thu, 13 Apr 2017 21:36:18 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=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 --- src/main/java/webserver/HttpRequest.java | 65 +++++++++++++------ .../java/webserver/HttpRequestHeader.java | 18 +++++ src/main/java/webserver/HttpRequestLine.java | 8 +++ src/main/java/webserver/RequestHandler.java | 14 ++-- .../java/webserver/HttpRequestHeaderTest.java | 15 +++++ .../java/webserver/HttpRequestLineTest.java | 13 ++++ src/test/java/webserver/HttpRequestTest.java | 16 +++++ 7 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 src/main/java/webserver/HttpRequestHeader.java create mode 100644 src/main/java/webserver/HttpRequestLine.java create mode 100644 src/test/java/webserver/HttpRequestHeaderTest.java create mode 100644 src/test/java/webserver/HttpRequestLineTest.java create mode 100644 src/test/java/webserver/HttpRequestTest.java diff --git a/src/main/java/webserver/HttpRequest.java b/src/main/java/webserver/HttpRequest.java index 65c2a9d66..b19d9a220 100644 --- a/src/main/java/webserver/HttpRequest.java +++ b/src/main/java/webserver/HttpRequest.java @@ -3,48 +3,75 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.Optional; public class HttpRequest { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); - Map requestHeaders = new HashMap<>(); + String httpMethod; + String urlPath; + + HttpRequestHeader httpRequestHeader = new HttpRequestHeader(); + Map requestBody = new HashMap<>(); + + public HttpRequest(InputStream in) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); + getRequestLine(br); + getHeadersFromReader(br); + getBodyFromReader(br); + } - public HttpRequest(BufferedReader br) throws Exception { + private void getRequestLine(BufferedReader br) throws Exception { String line = br.readLine(); - if(line != null) { - requestHeaders.put("Http_Method", line.split(" ")[0]); - requestHeaders.put("Target_Url", line.split(" ")[1]); - log.debug("Http_Method : {}", line.split(" ")[0]); - log.debug("Target_Url : {}", line.split(" ")[1]); - - while (!"".equals(line)) { - line = br.readLine(); - if(!"".equals(line)) { - requestHeaders.put(HttpRequestUtils.parseHeader(line).getKey(),HttpRequestUtils.parseHeader(line).getValue()); - log.debug("{} : {}", HttpRequestUtils.parseHeader(line).getKey(), HttpRequestUtils.parseHeader(line).getValue()); - } - } - } else { + if(line == null) { throw new Exception("헤더정보를 만들수 없습니다."); } + + this.httpMethod = HttpRequestLine.getPath(line.split(" ")[0]); + this.urlPath = HttpRequestLine.getPath(line.split(" ")[1]); + } + + private void getHeadersFromReader(BufferedReader br) throws IOException { + String line; + while (!"".equals(line = br.readLine())) { + httpRequestHeader.add(line); + } } + private void getBodyFromReader(BufferedReader br) throws IOException { + if (Optional.ofNullable(this.getHeader("Content-Length")).isPresent()) { + setRequestBody(br, Integer.parseInt(this.getHeader("Content-Length"))); + } + } + + private void setRequestBody(BufferedReader br, int contentLength) throws IOException { + this.requestBody = HttpRequestUtils.parseQueryString(IOUtils.readData(br, contentLength)); + } + public String getHeader(String headerType) { - return requestHeaders.get(headerType); + return httpRequestHeader.getHeader(headerType); } public String getHttpMethod() { - return requestHeaders.get("Http_Method"); + return this.httpMethod; } public String getPath() { - return requestHeaders.get("Target_Url"); + return this.urlPath; + } + + public Map getRequestBodies() { + return requestBody; } + } diff --git a/src/main/java/webserver/HttpRequestHeader.java b/src/main/java/webserver/HttpRequestHeader.java new file mode 100644 index 000000000..7e32d60c7 --- /dev/null +++ b/src/main/java/webserver/HttpRequestHeader.java @@ -0,0 +1,18 @@ +package webserver; + +import util.HttpRequestUtils; + +import java.util.HashMap; +import java.util.Map; + +public class HttpRequestHeader { + Map requestHeaders = new HashMap<>(); + + public void add(String headerLine) { + requestHeaders.put(HttpRequestUtils.parseHeader(headerLine).getKey(),HttpRequestUtils.parseHeader(headerLine).getValue()); + } + + public String getHeader(String key) { + return this.requestHeaders.get(key); + } +} diff --git a/src/main/java/webserver/HttpRequestLine.java b/src/main/java/webserver/HttpRequestLine.java new file mode 100644 index 000000000..3f253d408 --- /dev/null +++ b/src/main/java/webserver/HttpRequestLine.java @@ -0,0 +1,8 @@ +package webserver; + +public class HttpRequestLine { + + public static String getPath(String requestLine) { + return requestLine.split(" ")[1]; + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 50818267a..4ae248cb6 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -35,9 +35,8 @@ public void run() { connection.getPort()); try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); - HttpRequest httpRequest = new HttpRequest(br); + HttpRequest httpRequest = new HttpRequest(in); String http_method = httpRequest.getHttpMethod(); String target_url = httpRequest.getPath(); @@ -47,12 +46,11 @@ public void run() { byte[] body = new byte[0]; if(target_url.equals("/user/create")) { - addUserToDataBase(newUserFromParams(getPostData(br, Integer.parseInt(httpRequest.getHeader("Content-Length"))))); - + addUserToDataBase(newUserFromParams(httpRequest.getRequestBodies())); response302Header(dos, "../../index.html"); } else if (http_method.equals("POST") && target_url.equals("/user/login")) { - Map postData = getPostData(br, Integer.parseInt(httpRequest.getHeader("Content-Length"))); - if(isCorrectPassword(postData, findUserFromDataBase(postData.get("userId")))) { + Map userData = httpRequest.getRequestBodies(); + if(isCorrectPassword(userData, findUserFromDataBase(userData.get("userId")))) { response302HeaderForCookie(dos, "../../index.html","logined=true"); } else { response302HeaderForCookie(dos, "./login_failed.html","logined=false"); @@ -105,10 +103,6 @@ private User newUserFromParams(Map params) { ); } - private Map getPostData(BufferedReader br, int contentLength) throws IOException { - return HttpRequestUtils.parseQueryString(IOUtils.readData(br, contentLength)); - } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { try { dos.writeBytes("HTTP/1.1 200 OK \r\n"); diff --git a/src/test/java/webserver/HttpRequestHeaderTest.java b/src/test/java/webserver/HttpRequestHeaderTest.java new file mode 100644 index 000000000..10a59083a --- /dev/null +++ b/src/test/java/webserver/HttpRequestHeaderTest.java @@ -0,0 +1,15 @@ +package webserver; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class HttpRequestHeaderTest { + + @Test + public void getHeader() { + HttpRequestHeader httpRequestHeader = new HttpRequestHeader(); + httpRequestHeader.add("Connection : keep-alive"); + assertEquals("keep-alive", httpRequestHeader.getHeader("Connection")); + } +} diff --git a/src/test/java/webserver/HttpRequestLineTest.java b/src/test/java/webserver/HttpRequestLineTest.java new file mode 100644 index 000000000..35ab122b3 --- /dev/null +++ b/src/test/java/webserver/HttpRequestLineTest.java @@ -0,0 +1,13 @@ +package webserver; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class HttpRequestLineTest { + + @Test + public void getPath() { + assertEquals("./index.html", HttpRequestLine.getPath("GET ./index.html")); + } +} diff --git a/src/test/java/webserver/HttpRequestTest.java b/src/test/java/webserver/HttpRequestTest.java new file mode 100644 index 000000000..8bc9359a5 --- /dev/null +++ b/src/test/java/webserver/HttpRequestTest.java @@ -0,0 +1,16 @@ +package webserver; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class HttpRequestTest { + + + private String testDirectory = "./src/main/resources"; + + @Test + public void 헤더를_통해_URI를_가져온다() { + + } +} \ No newline at end of file