From fed02f6f5f4308400e55c160d9495cad010f5bfb Mon Sep 17 00:00:00 2001 From: Gyeongho Yang Date: Thu, 5 Sep 2024 11:11:09 +0900 Subject: [PATCH 01/73] fix: remove implementation logback-classic on gradle (#501) --- study/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/study/build.gradle b/study/build.gradle index 5c69542f84..87a1f0313c 100644 --- a/study/build.gradle +++ b/study/build.gradle @@ -19,7 +19,6 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' - implementation 'ch.qos.logback:logback-classic:1.5.7' implementation 'org.apache.commons:commons-lang3:3.14.0' implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1' implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.4.1' From 7e9135698878932274ddc1f523ba817ed9c56c70 Mon Sep 17 00:00:00 2001 From: Gyeongho Yang Date: Thu, 5 Sep 2024 13:51:07 +0900 Subject: [PATCH 02/73] fix: add threads min-spare configuration on properties (#502) --- study/src/main/resources/application.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 4e8655a962..e3503a5fb9 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -6,4 +6,5 @@ server: accept-count: 1 max-connections: 1 threads: + min-spare: 2 max: 2 From 7ed4d23a04c2e09319d4bdd09fe95164686832b9 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sun, 8 Sep 2024 18:12:06 +0900 Subject: [PATCH 03/73] =?UTF-8?q?refactor:=20favicon.ico=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/resources/static/favicon.ico | Bin 0 -> 1150 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tomcat/src/main/resources/static/favicon.ico diff --git a/tomcat/src/main/resources/static/favicon.ico b/tomcat/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..815a3ab175abdbe994c17d68f429482c0e2db96d GIT binary patch literal 1150 zcmbu8O-=$q5QPghZVU--T(flHDZ~?a0mIH4aR9u52ViA9jw{_L;`haQNlOMYV39|4 zSJkVZ?w+a(g|K4n*qmj6ZE8hitD-2-J`FZzUa<*VEEGy8LJ0{VK{#WzQK`CvT*N_xpW`}o_v zJi$*N^2HE-JI@=O8=xG*H%HFZ97<}d+ZyS6TmOfjyE&%+aF_Jy%--XW^UM9c6MqX7 zXAL*|zWGyg$osLMoL_1l@_xfV_WN-Tzd8AHH%R7m?YzBmx5E4Y7T^M00>xL_LYqEg IjD;ij2eJ`+K>z>% literal 0 HcmV?d00001 From 078af63bf4cf6c0e0b5f53faf111e718ff8729bd Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sun, 8 Sep 2024 18:12:21 +0900 Subject: [PATCH 04/73] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http11/ContentType.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java index cd36e4a10c..24b510942b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java @@ -8,24 +8,25 @@ public enum ContentType { JS("application/javascript;charset=utf-8", "js"), HTML("text/html;charset=utf-8", "html"), PNG("image/png", "png"), - JPG("image/jpeg", "jpeg") + JPG("image/jpeg", "jpeg"), + ICO("image/x-icon", "ico") ; private final String contentType; - private final String extention; + private final String extension; - ContentType(String contentType, String extention) { + ContentType(String contentType, String extension) { this.contentType = contentType; - this.extention = extention; + this.extension = extension; } public String getContentType() { return contentType; } - public static ContentType getContentType(String extention) { + public static ContentType getContentType(String extension) { return Arrays.stream(values()) - .filter(contentType1 -> contentType1.extention.equals(extention)) + .filter(contentType1 -> contentType1.extension.equals(extension)) .findAny() .orElseThrow(); } From 25e67eb0802d8afb163792fee780bd0b6d76e4fb Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sun, 8 Sep 2024 18:18:35 +0900 Subject: [PATCH 05/73] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/apache/coyote/http11/RequestMapping.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java index fa012d5ca8..78ddcdc394 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java @@ -14,7 +14,6 @@ public class RequestMapping { public RequestMapping() { controllers.put("/login", new LoginController()); controllers.put("/register", new RegisterController()); - controllers.put("page", new PageController()); } public Controller getController(String path) { From 8e570a720c894305df2fa2d236f15bbe3bd0fdad Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 12:45:33 +0900 Subject: [PATCH 06/73] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20url?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20null=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/http11/HttpStatusCode.java | 3 ++- .../main/java/org/apache/coyote/http11/RequestMapping.java | 4 ++-- .../{PageController.java => DefaultController.java} | 7 +++++-- 3 files changed, 9 insertions(+), 5 deletions(-) rename tomcat/src/main/java/org/apache/coyote/http11/controller/{PageController.java => DefaultController.java} (88%) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java index a51eac9edf..e9c98e7e3d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java @@ -3,7 +3,8 @@ public enum HttpStatusCode { OK(200, "OK"), - FOUND(302, "Found") + FOUND(302, "Found"), + NOT_FOUND(404, "Not Found") ; private final int code; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java index 78ddcdc394..5771c0f956 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java @@ -4,7 +4,7 @@ import java.util.Map; import org.apache.coyote.http11.controller.Controller; import org.apache.coyote.http11.controller.LoginController; -import org.apache.coyote.http11.controller.PageController; +import org.apache.coyote.http11.controller.DefaultController; import org.apache.coyote.http11.controller.RegisterController; public class RequestMapping { @@ -21,6 +21,6 @@ public Controller getController(String path) { return controllers.get(path); } - return new PageController(); + return new DefaultController(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/PageController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java similarity index 88% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/PageController.java rename to tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index cda0b2f59a..fe6ab83533 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/PageController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -12,11 +12,11 @@ import org.apache.coyote.http11.httpresponse.HttpResponseHeader; import org.apache.coyote.http11.httpresponse.HttpStatusLine; -public class PageController extends AbstractController { +public class DefaultController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - return null; + throw new RuntimeException(); } @Override @@ -30,6 +30,9 @@ protected HttpResponse doGet(HttpRequest httpRequest) { } String fileName = "static" + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); + if (resourceUrl == null) { + resourceUrl = getClass().getClassLoader().getResource("static/404.html"); + } Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); From 3b1799db5f5e3cb11ebcf9ec851e845c23d19d2e Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 16:56:52 +0900 Subject: [PATCH 07/73] =?UTF-8?q?fix:=20input=EA=B0=92=EC=9D=B4=20?= =?UTF-8?q?=EB=8D=9C=20=EB=93=A4=EC=96=B4=EC=99=94=EC=9D=84=20=EC=8B=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../techcourse/db/InMemoryUserRepository.java | 4 ++++ .../org/apache/coyote/http11/HttpMethod.java | 14 ++++------- .../http11/controller/DefaultController.java | 3 +-- .../http11/controller/LoginController.java | 10 +++++--- .../http11/controller/RegisterController.java | 11 +++++++-- .../http11/httpresponse/HttpResponse.java | 24 +++++-------------- .../httpresponse/HttpResponseHeader.java | 16 +++++++++++++ .../http11/httpresponse/HttpStatusLine.java | 5 ++++ 8 files changed, 52 insertions(+), 35 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/db/InMemoryUserRepository.java b/tomcat/src/main/java/com/techcourse/db/InMemoryUserRepository.java index b041a264ea..67f2be3c77 100644 --- a/tomcat/src/main/java/com/techcourse/db/InMemoryUserRepository.java +++ b/tomcat/src/main/java/com/techcourse/db/InMemoryUserRepository.java @@ -23,5 +23,9 @@ public static Optional findByAccount(String account) { return Optional.ofNullable(database.get(account)); } + public static boolean containsByAccount(String account) { + return database.containsKey(account); + } + private InMemoryUserRepository() {} } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java index 4cb9976c42..6a2e610f9b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java @@ -4,24 +4,18 @@ public enum HttpMethod { - GET("GET"), - POST("POST") + GET, + POST ; - private final String name; - - HttpMethod(String name) { - this.name = name; - } - public static HttpMethod getHttpMethod(String name) { return Arrays.stream(values()) - .filter(httpMethod -> httpMethod.name.equals(name)) + .filter(httpMethod -> httpMethod.name().equals(name)) .findAny() .orElseThrow(); } public boolean isMethod(String name) { - return this.name.equals(name); + return name().equals(name); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index fe6ab83533..2d2a165d80 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -4,7 +4,6 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; -import org.apache.coyote.http11.ContentType; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -36,7 +35,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", ContentType.getContentType(path.split("\\.")[1]).getContentType()); + httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 62d0b29b6f..a4816c859e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -7,7 +7,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.UUID; -import org.apache.coyote.http11.ContentType; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; @@ -28,6 +27,11 @@ public class LoginController extends AbstractController { protected HttpResponse doPost(HttpRequest httpRequest) { String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); + for (String t : token) { + if (t.split("=").length < 2) { + throw new RuntimeException("변수가 부족합니다"); + } + } String account = token[0].split("=")[1]; String password = token[1].split("=")[1]; @@ -59,7 +63,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { String[] cookies = httpRequest.getValue("Cookie").split("; "); String cookie = ""; for (String c : cookies) { - if (c.contains("JSESSIONID")) { + if (c.contains("JSESSIONID") && c.split("=").length >= 2) { cookie = c.split("=")[1]; } } @@ -79,7 +83,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", ContentType.HTML.getContentType()); + httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 736aa4d852..bf587d8c9e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -6,7 +6,6 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; -import org.apache.coyote.http11.ContentType; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -20,7 +19,15 @@ public class RegisterController extends AbstractController { protected HttpResponse doPost(HttpRequest httpRequest) { String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); + for (String t : token) { + if (t.split("=").length < 2) { + throw new RuntimeException("변수가 부족합니다"); + } + } String account = token[0].split("=")[1]; + if (InMemoryUserRepository.containsByAccount(account)) { + throw new RuntimeException("이미 존재하는 account입니다"); + } String email = token[1].split("=")[1]; String password = token[2].split("=")[1]; User user = new User(account, password, email); @@ -43,7 +50,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", ContentType.HTML.getContentType()); + httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 2960b502c7..49d77dc3db 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -1,7 +1,5 @@ package org.apache.coyote.http11.httpresponse; -import java.util.Map; - public class HttpResponse { private final HttpStatusLine httpStatusLine; @@ -23,31 +21,21 @@ public HttpResponse(HttpStatusLine httpStatusLine, HttpResponseHeader httpRespon } public byte[] getBytes() { - String statusLine = httpStatusLine.getVersion() + " " + httpStatusLine.getHttpStatusCode().getCode() + " " - + httpStatusLine.getHttpStatusCode().getMessage(); - Map headers = httpResponseHeader.getHeaders(); - StringBuilder sb = new StringBuilder(); - int size = headers.keySet().size(); - int i = 1; - for (String key : headers.keySet()) { - if (i < size) { - sb.append(key).append(": ").append(headers.get(key)).append(" \r\n"); - size++; - } else { - sb.append(key).append(": ").append(headers.get(key)); - } - } + String statusLine = httpStatusLine.getString(); + + String responseHeader = httpResponseHeader.getString(); + if (httpResponseBody != null) { String responseBody = httpResponseBody.getBody(); String join = String.join("\r\n", statusLine, - sb.toString(), + responseHeader, responseBody); return join.getBytes(); } String join = String.join("\r\n", statusLine, - sb.toString()); + responseHeader); return join.getBytes(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index e350a1b84a..22ac414de4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -15,6 +15,22 @@ public void addHeaders(String key, String value) { headers.put(key, value); } + public String getString() { + StringBuilder sb = new StringBuilder(); + int size = headers.keySet().size(); + int i = 1; + for (String key : headers.keySet()) { + if (i < size) { + sb.append(key).append(": ").append(headers.get(key)).append(" \r\n"); + size++; + } else { + sb.append(key).append(": ").append(headers.get(key)); + } + } + + return sb.toString(); + } + public Map getHeaders() { return headers; } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index 4eaf9eba69..5e4e97937a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -12,6 +12,11 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { this.httpStatusCode = httpStatusCode; } + public String getString() { + return version + " " + httpStatusCode.getCode() + " " + + httpStatusCode.getMessage(); + } + public String getVersion() { return version; } From f986e256ef8a4fc475fe4c905f318433f9f953d7 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 20:56:11 +0900 Subject: [PATCH 08/73] =?UTF-8?q?refactor:=20HttpResponse=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20builder=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/HttpHeaderName.java | 20 ++++++++ .../http11/controller/DefaultController.java | 12 ++--- .../http11/controller/LoginController.java | 31 ++++++------ .../http11/controller/RegisterController.java | 18 +++---- .../http11/httpresponse/HttpResponse.java | 50 +++++++++++++++++-- .../httpresponse/HttpResponseHeader.java | 18 +++---- 6 files changed, 102 insertions(+), 47 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java new file mode 100644 index 0000000000..25a205f8c8 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java @@ -0,0 +1,20 @@ +package org.apache.coyote.http11; + +public enum HttpHeaderName { + + CONTENT_TYPE("Content-Type"), + SET_COOKIE("Set-Cookie"), + CONTENT_LENGTH("Content-Length"), + LOCATION("Location") + ; + + private final String name; + + HttpHeaderName(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index 2d2a165d80..159a83537b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -7,8 +7,6 @@ import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpResponseBody; -import org.apache.coyote.http11.httpresponse.HttpResponseHeader; import org.apache.coyote.http11.httpresponse.HttpStatusLine; public class DefaultController extends AbstractController { @@ -34,12 +32,12 @@ protected HttpResponse doGet(HttpRequest httpRequest) { } Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); - httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); - HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); - return new HttpResponse(httpStatusLine, httpResponseHeader, httpResponseBody); + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); } catch (URISyntaxException | IOException e) { throw new RuntimeException(e); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index a4816c859e..c695bf5909 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -11,8 +11,7 @@ import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpResponseBody; -import org.apache.coyote.http11.httpresponse.HttpResponseHeader; +import org.apache.coyote.http11.httpresponse.HttpResponse.Builder; import org.apache.coyote.http11.httpresponse.HttpStatusLine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,18 +39,18 @@ protected HttpResponse doPost(HttpRequest httpRequest) { UUID uuid = UUID.randomUUID(); HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); + Builder builder = new Builder(httpStatusLine); if (user.checkPassword(password)) { session.save(uuid.toString(), user); - httpResponseHeader.addHeaders("Set-Cookie", "JSESSIONID=" + uuid); - httpResponseHeader.addHeaders("Location", "/index.html"); + builder.setCookie("JSESSIONID=" + uuid); + builder.location("/index.html"); log.info(user.toString()); } else { - httpResponseHeader.addHeaders("Location", "/401.html"); + builder.location("/401.html"); log.error("비밀번호 불일치"); } - return new HttpResponse(httpStatusLine, httpResponseHeader); + return builder.build(); } @Override @@ -71,10 +70,10 @@ protected HttpResponse doGet(HttpRequest httpRequest) { User user = session.getUser(cookie); log.info(user.toString()); httpStatusLine = new HttpStatusLine(httpStatusLine.getVersion(), HttpStatusCode.FOUND); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Set-Cookie", "JSESSIONID=" + cookie); - httpResponseHeader.addHeaders("Location", "/index.html"); - return new HttpResponse(httpStatusLine, httpResponseHeader); + return new HttpResponse.Builder(httpStatusLine) + .setCookie("JSESSIONID=" + cookie) + .location("/index.html") + .build(); } } @@ -82,12 +81,12 @@ protected HttpResponse doGet(HttpRequest httpRequest) { var resourceUrl = getClass().getClassLoader().getResource(fileName); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); - httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); - HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); - return new HttpResponse(httpStatusLine, httpResponseHeader, httpResponseBody); + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); } catch (URISyntaxException | IOException e) { throw new RuntimeException(e); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index bf587d8c9e..175f4af659 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -9,8 +9,6 @@ import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpResponseBody; -import org.apache.coyote.http11.httpresponse.HttpResponseHeader; import org.apache.coyote.http11.httpresponse.HttpStatusLine; public class RegisterController extends AbstractController { @@ -34,10 +32,10 @@ protected HttpResponse doPost(HttpRequest httpRequest) { InMemoryUserRepository.save(user); HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Location", "/index.html"); - return new HttpResponse(httpStatusLine, httpResponseHeader); + return new HttpResponse.Builder(httpStatusLine) + .location("/index.html") + .build(); } @Override @@ -49,12 +47,12 @@ protected HttpResponse doGet(HttpRequest httpRequest) { var resourceUrl = getClass().getClassLoader().getResource(fileName); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - HttpResponseHeader httpResponseHeader = new HttpResponseHeader(); - httpResponseHeader.addHeaders("Content-Type", Files.probeContentType(filePath) + ";charset=utf-8"); - httpResponseHeader.addHeaders("Content-Length", String.valueOf(responseBody.getBytes().length)); - HttpResponseBody httpResponseBody = new HttpResponseBody(responseBody); - return new HttpResponse(httpStatusLine, httpResponseHeader, httpResponseBody); + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); } catch (URISyntaxException | IOException e) { throw new RuntimeException(e); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 49d77dc3db..92bceac710 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -1,12 +1,16 @@ package org.apache.coyote.http11.httpresponse; +import java.util.HashMap; +import java.util.Map; +import org.apache.coyote.http11.HttpHeaderName; + public class HttpResponse { private final HttpStatusLine httpStatusLine; private final HttpResponseHeader httpResponseHeader; private final HttpResponseBody httpResponseBody; - public HttpResponse( + private HttpResponse( HttpStatusLine httpStatusLine, HttpResponseHeader httpResponseHeader, HttpResponseBody httpResponseBody @@ -16,10 +20,6 @@ public HttpResponse( this.httpResponseBody = httpResponseBody; } - public HttpResponse(HttpStatusLine httpStatusLine, HttpResponseHeader httpResponseHeader) { - this(httpStatusLine, httpResponseHeader, null); - } - public byte[] getBytes() { String statusLine = httpStatusLine.getString(); @@ -50,4 +50,44 @@ public HttpResponseHeader getHttpResponseHeader() { public HttpResponseBody getHttpResponseBody() { return httpResponseBody; } + + public static class Builder { + private final HttpStatusLine httpStatusLine; + private final Map headers; + private HttpResponseBody httpResponseBody; + + public Builder(HttpStatusLine httpStatusLine) { + this.httpStatusLine = httpStatusLine; + this.headers = new HashMap<>(); + } + + public Builder location(String location) { + headers.put(HttpHeaderName.LOCATION, location); + return this; + } + + public Builder contentType(String contentType) { + headers.put(HttpHeaderName.CONTENT_TYPE, contentType); + return this; + } + + public Builder contentLength(String contentLength) { + headers.put(HttpHeaderName.CONTENT_LENGTH, contentLength); + return this; + } + + public Builder setCookie(String setCookie) { + headers.put(HttpHeaderName.SET_COOKIE, setCookie); + return this; + } + + public Builder responseBody(String responseBody) { + this.httpResponseBody = new HttpResponseBody(responseBody); + return this; + } + + public HttpResponse build() { + return new HttpResponse(httpStatusLine, new HttpResponseHeader(headers), httpResponseBody); + } + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index 22ac414de4..c9cc1522ea 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -1,17 +1,17 @@ package org.apache.coyote.http11.httpresponse; -import java.util.HashMap; import java.util.Map; +import org.apache.coyote.http11.HttpHeaderName; public class HttpResponseHeader { - private final Map headers; + private final Map headers; - public HttpResponseHeader() { - this.headers = new HashMap<>(); + public HttpResponseHeader(Map headers) { + this.headers = headers; } - public void addHeaders(String key, String value) { + public void addHeaders(HttpHeaderName key, String value) { headers.put(key, value); } @@ -19,19 +19,19 @@ public String getString() { StringBuilder sb = new StringBuilder(); int size = headers.keySet().size(); int i = 1; - for (String key : headers.keySet()) { + for (HttpHeaderName key : headers.keySet()) { if (i < size) { - sb.append(key).append(": ").append(headers.get(key)).append(" \r\n"); + sb.append(key.getName()).append(": ").append(headers.get(key)).append(" \r\n"); size++; } else { - sb.append(key).append(": ").append(headers.get(key)); + sb.append(key.getName()).append(": ").append(headers.get(key)); } } return sb.toString(); } - public Map getHeaders() { + public Map getHeaders() { return headers; } } From dda9c176f9cf3bf6a360330d1880128d064db04a Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 20:57:32 +0900 Subject: [PATCH 09/73] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/ContentType.java | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/http11/ContentType.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java deleted file mode 100644 index 24b510942b..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.apache.coyote.http11; - -import java.util.Arrays; - -public enum ContentType { - - CSS("text/css;charset=utf-8", "css"), - JS("application/javascript;charset=utf-8", "js"), - HTML("text/html;charset=utf-8", "html"), - PNG("image/png", "png"), - JPG("image/jpeg", "jpeg"), - ICO("image/x-icon", "ico") - ; - - private final String contentType; - private final String extension; - - ContentType(String contentType, String extension) { - this.contentType = contentType; - this.extension = extension; - } - - public String getContentType() { - return contentType; - } - - public static ContentType getContentType(String extension) { - return Arrays.stream(values()) - .filter(contentType1 -> contentType1.extension.equals(extension)) - .findAny() - .orElseThrow(); - } -} From c53b87ac1ef309f367a1ecc7e472af1762062db7 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 21:00:55 +0900 Subject: [PATCH 10/73] =?UTF-8?q?refactor:=20=EC=97=86=EB=8A=94=20url?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=83=81=ED=83=9C=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/controller/DefaultController.java | 1 + .../org/apache/coyote/http11/httprequest/HttpRequest.java | 8 -------- .../apache/coyote/http11/httprequest/HttpRequestBody.java | 7 ------- .../coyote/http11/httprequest/HttpRequestHeader.java | 7 ------- .../coyote/http11/httpresponse/HttpResponseHeader.java | 4 ---- 5 files changed, 1 insertion(+), 26 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index 159a83537b..425faf3f38 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -28,6 +28,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { String fileName = "static" + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); if (resourceUrl == null) { + httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.NOT_FOUND); resourceUrl = getClass().getClassLoader().getResource("static/404.html"); } Path filePath = Path.of(resourceUrl.toURI()); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index 1e614078b8..fd22135bcb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -57,12 +57,4 @@ public HttpRequestHeader getHttpRequestHeader() { public HttpRequestBody getHttpRequestBody() { return httpRequestBody; } - - @Override - public String toString() { - return "HttpRequest{\n" + - "httpRequestHeader=" + httpRequestHeader + - ",\n httpRequestBody=" + httpRequestBody + - "\n}"; - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java index 6c303051c2..7927bc9abb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java @@ -11,11 +11,4 @@ public HttpRequestBody(String body) { public String getBody() { return body; } - - @Override - public String toString() { - return "HttpRequestBody{\n" + - "body='" + body + '\'' + - "\n}"; - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java index bf29b0cdc4..1145e6459a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java @@ -17,11 +17,4 @@ public boolean containsKey(String key) { public String getValue(String key) { return headers.get(key); } - - @Override - public String toString() { - return "HttpRequestHeader{" + - ", \nheaders=" + headers + - '}'; - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index c9cc1522ea..bc934d13d4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -11,10 +11,6 @@ public HttpResponseHeader(Map headers) { this.headers = headers; } - public void addHeaders(HttpHeaderName key, String value) { - headers.put(key, value); - } - public String getString() { StringBuilder sb = new StringBuilder(); int size = headers.keySet().size(); From b24f95f863403188ae6033652beb25d75f3ae226 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 21:21:54 +0900 Subject: [PATCH 11/73] =?UTF-8?q?refactor:=20Cookie=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/HttpCookie.java | 25 +++++++++++++++ .../coyote/http11/HttpCookieConvertor.java | 15 +++++++++ .../org/apache/coyote/http11/HttpMethod.java | 2 +- .../http11/controller/LoginController.java | 31 +++++++++---------- .../http11/controller/RegisterController.java | 5 +-- 5 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java new file mode 100644 index 0000000000..2ff402bc9d --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java @@ -0,0 +1,25 @@ +package org.apache.coyote.http11; + +import java.util.HashMap; +import java.util.Map; + +public class HttpCookie { + + private final Map cookies; + + public HttpCookie() { + this.cookies = new HashMap<>(); + } + + public void addCookie(String key, String value) { + cookies.put(key, value); + } + + public boolean containsKey(String key) { + return cookies.containsKey(key); + } + + public String getValue(String key) { + return cookies.get(key); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java new file mode 100644 index 0000000000..9f8eb528ad --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java @@ -0,0 +1,15 @@ +package org.apache.coyote.http11; + +public class HttpCookieConvertor { + + public static HttpCookie convertHttpCookie(String cookie) { + HttpCookie httpCookie = new HttpCookie(); + String[] cookies = cookie.split("; "); + for (String c : cookies) { + if (c.split("=").length >= 2) { + httpCookie.addCookie(c.split("=")[0], c.split("=")[1]); + } + } + return httpCookie; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java index 6a2e610f9b..ba36e58a45 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java @@ -10,7 +10,7 @@ public enum HttpMethod { public static HttpMethod getHttpMethod(String name) { return Arrays.stream(values()) - .filter(httpMethod -> httpMethod.name().equals(name)) + .filter(httpMethod -> httpMethod.isMethod(name)) .findAny() .orElseThrow(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index c695bf5909..3890613db0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -7,6 +7,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.UUID; +import org.apache.coyote.http11.HttpCookie; +import org.apache.coyote.http11.HttpCookieConvertor; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; @@ -19,6 +21,7 @@ public class LoginController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); + private static final String LOGIN_PATH = "static/login.html"; private final Session session = Session.getInstance(); @@ -59,26 +62,22 @@ protected HttpResponse doGet(HttpRequest httpRequest) { HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); if (httpRequest.containsKey("Cookie")) { - String[] cookies = httpRequest.getValue("Cookie").split("; "); - String cookie = ""; - for (String c : cookies) { - if (c.contains("JSESSIONID") && c.split("=").length >= 2) { - cookie = c.split("=")[1]; + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue("Cookie")); + if (httpCookie.containsKey("JSESSIONID")) { + String jsessionid = httpCookie.getValue("JSESSIONID"); + if (session.containsUser(jsessionid)) { + User user = session.getUser(jsessionid); + log.info(user.toString()); + httpStatusLine = new HttpStatusLine(httpStatusLine.getVersion(), HttpStatusCode.FOUND); + return new HttpResponse.Builder(httpStatusLine) + .setCookie("JSESSIONID=" + jsessionid) + .location("/index.html") + .build(); } } - if (session.containsUser(cookie)) { - User user = session.getUser(cookie); - log.info(user.toString()); - httpStatusLine = new HttpStatusLine(httpStatusLine.getVersion(), HttpStatusCode.FOUND); - return new HttpResponse.Builder(httpStatusLine) - .setCookie("JSESSIONID=" + cookie) - .location("/index.html") - .build(); - } } - String fileName = "static/login.html"; - var resourceUrl = getClass().getClassLoader().getResource(fileName); + var resourceUrl = getClass().getClassLoader().getResource(LOGIN_PATH); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 175f4af659..505a052c65 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -13,6 +13,8 @@ public class RegisterController extends AbstractController { + private static final String REGISTER_PATH = "static/register.html"; + @Override protected HttpResponse doPost(HttpRequest httpRequest) { String requestBody = httpRequest.getBody(); @@ -43,8 +45,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { try { HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); - String fileName = "static/register.html"; - var resourceUrl = getClass().getClassLoader().getResource(fileName); + var resourceUrl = getClass().getClassLoader().getResource(REGISTER_PATH); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); From 8672b31a38d66561d70062d8b95c1ea8eae79c45 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 21:38:41 +0900 Subject: [PATCH 12/73] =?UTF-8?q?refactor:=20depth=20=EA=B0=90=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/controller/LoginController.java | 29 +++++++++++-------- .../http11/controller/RegisterController.java | 22 ++++++++++---- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 3890613db0..68a92cd30b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -6,6 +6,7 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.UUID; import org.apache.coyote.http11.HttpCookie; import org.apache.coyote.http11.HttpCookieConvertor; @@ -13,7 +14,6 @@ import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpResponse.Builder; import org.apache.coyote.http11.httpresponse.HttpStatusLine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,10 +29,11 @@ public class LoginController extends AbstractController { protected HttpResponse doPost(HttpRequest httpRequest) { String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); - for (String t : token) { - if (t.split("=").length < 2) { - throw new RuntimeException("변수가 부족합니다"); - } + if (checkToken(token)) { + log.error("일부 항목이 누락되었습니다."); + return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + .location("/login") + .build(); } String account = token[0].split("=")[1]; String password = token[1].split("=")[1]; @@ -42,18 +43,22 @@ protected HttpResponse doPost(HttpRequest httpRequest) { UUID uuid = UUID.randomUUID(); HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); - Builder builder = new Builder(httpStatusLine); if (user.checkPassword(password)) { session.save(uuid.toString(), user); - builder.setCookie("JSESSIONID=" + uuid); - builder.location("/index.html"); log.info(user.toString()); - } else { - builder.location("/401.html"); - log.error("비밀번호 불일치"); + return new HttpResponse.Builder(httpStatusLine) + .setCookie("JSESSIONID=" + uuid) + .location("/index.html") + .build(); } + log.error("비밀번호 불일치"); + return new HttpResponse.Builder(httpStatusLine) + .location("/401.html") + .build(); + } - return builder.build(); + private boolean checkToken(String[] token) { + return Arrays.stream(token).anyMatch(t -> t.split("=").length < 2); } @Override diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 505a052c65..f1973f4fc7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -6,27 +6,35 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.apache.coyote.http11.httpresponse.HttpStatusLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class RegisterController extends AbstractController { + private static final Logger log = LoggerFactory.getLogger(RegisterController.class); private static final String REGISTER_PATH = "static/register.html"; @Override protected HttpResponse doPost(HttpRequest httpRequest) { String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); - for (String t : token) { - if (t.split("=").length < 2) { - throw new RuntimeException("변수가 부족합니다"); - } + if (checkToken(token)) { + log.error("일부 항목이 누락되었습니다."); + return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + .location("/register") + .build(); } String account = token[0].split("=")[1]; if (InMemoryUserRepository.containsByAccount(account)) { - throw new RuntimeException("이미 존재하는 account입니다"); + log.error("이미 존재하는 account입니다"); + return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + .location("/register") + .build(); } String email = token[1].split("=")[1]; String password = token[2].split("=")[1]; @@ -40,6 +48,10 @@ protected HttpResponse doPost(HttpRequest httpRequest) { .build(); } + private boolean checkToken(String[] token) { + return Arrays.stream(token).anyMatch(t -> t.split("=").length < 2); + } + @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { From 61ff56cd298cac2a0d99f73b9a7695d89976ee9f Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 22:24:25 +0900 Subject: [PATCH 13/73] =?UTF-8?q?refactor:=20=EC=93=B0=EB=A0=88=EB=93=9C?= =?UTF-8?q?=20=EC=95=88=EC=A0=84=EC=84=B1=20=EB=B3=B4=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/java/org/apache/coyote/http11/Session.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Session.java b/tomcat/src/main/java/org/apache/coyote/http11/Session.java index 424b9cf6f9..7557d8c3ba 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Session.java @@ -1,9 +1,9 @@ package org.apache.coyote.http11; import com.techcourse.model.User; -import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; public class Session { @@ -11,7 +11,7 @@ public class Session { private final Map userMap; private Session() { - this.userMap = new HashMap<>(); + this.userMap = new ConcurrentHashMap<>(); } public static Session getInstance() { From 74fce635be99893d0620c787e51ea465b3d348fd Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 22:24:36 +0900 Subject: [PATCH 14/73] =?UTF-8?q?refactor:=20=EC=93=B0=EB=A0=88=EB=93=9C?= =?UTF-8?q?=ED=92=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/catalina/connector/Connector.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java index 3b2c4dda7c..ffa86b6f34 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -1,5 +1,7 @@ package org.apache.catalina.connector; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.apache.coyote.http11.Http11Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,16 +17,19 @@ public class Connector implements Runnable { private static final int DEFAULT_PORT = 8080; private static final int DEFAULT_ACCEPT_COUNT = 100; + private static final int DEFAULT_MAX_THREADS = 250; private final ServerSocket serverSocket; + private final ExecutorService executorService; private boolean stopped; public Connector() { - this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + this(DEFAULT_PORT, DEFAULT_MAX_THREADS, DEFAULT_ACCEPT_COUNT); } - public Connector(final int port, final int acceptCount) { + public Connector(final int port, final int acceptCount, final int maxThreads) { this.serverSocket = createServerSocket(port, acceptCount); + this.executorService = Executors.newFixedThreadPool(maxThreads); this.stopped = false; } @@ -67,7 +72,7 @@ private void process(final Socket connection) { return; } var processor = new Http11Processor(connection); - new Thread(processor).start(); + executorService.execute(processor); } public void stop() { From 75f9655c1ff456044f764d1daade775836686fdb Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 22:46:53 +0900 Subject: [PATCH 15/73] =?UTF-8?q?refactor:=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20url=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EC=B2=98=EB=A6=AC=20=EC=B1=85=EC=9E=84=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/RequestMapping.java | 5 ++- .../http11/controller/DefaultController.java | 5 +-- .../http11/controller/NotFoundController.java | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java index 5771c0f956..f892c46a27 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java @@ -5,6 +5,7 @@ import org.apache.coyote.http11.controller.Controller; import org.apache.coyote.http11.controller.LoginController; import org.apache.coyote.http11.controller.DefaultController; +import org.apache.coyote.http11.controller.NotFoundController; import org.apache.coyote.http11.controller.RegisterController; public class RequestMapping { @@ -20,7 +21,9 @@ public Controller getController(String path) { if (controllers.containsKey(path)) { return controllers.get(path); } - + if (getClass().getClassLoader().getResource("static" + path) == null) { + return new NotFoundController(); + } return new DefaultController(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index 425faf3f38..d9fb1c2b3d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -27,10 +27,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { } String fileName = "static" + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); - if (resourceUrl == null) { - httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.NOT_FOUND); - resourceUrl = getClass().getClassLoader().getResource("static/404.html"); - } + Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java new file mode 100644 index 0000000000..5dc13a9d3b --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java @@ -0,0 +1,37 @@ +package org.apache.coyote.http11.controller; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.coyote.http11.HttpStatusCode; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httpresponse.HttpResponse; +import org.apache.coyote.http11.httpresponse.HttpStatusLine; + +public class NotFoundController extends AbstractController { + + @Override + protected HttpResponse doPost(HttpRequest httpRequest) { + throw new RuntimeException(); + } + + @Override + protected HttpResponse doGet(HttpRequest httpRequest) { + try { + String fileName = "static/404.html"; + var resourceUrl = getClass().getClassLoader().getResource(fileName); + HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.NOT_FOUND); + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); + } catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } + } +} From 4ae9b6358b33aa10d6a0749683655062ba5150ad Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 22:47:55 +0900 Subject: [PATCH 16/73] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/http11/Http11Processor.java | 1 + .../org/apache/coyote/http11/controller/LoginController.java | 4 ++-- .../apache/coyote/http11/{ => controller}/RequestMapping.java | 2 +- .../apache/coyote/http11/{ => httprequest}/HttpCookie.java | 2 +- .../coyote/http11/{ => httprequest}/HttpCookieConvertor.java | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) rename tomcat/src/main/java/org/apache/coyote/http11/{ => controller}/RequestMapping.java (95%) rename tomcat/src/main/java/org/apache/coyote/http11/{ => httprequest}/HttpCookie.java (91%) rename tomcat/src/main/java/org/apache/coyote/http11/{ => httprequest}/HttpCookieConvertor.java (89%) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index d1486f2416..cf9ccfadc7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -7,6 +7,7 @@ import java.net.Socket; import org.apache.coyote.Processor; import org.apache.coyote.http11.controller.Controller; +import org.apache.coyote.http11.controller.RequestMapping; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 68a92cd30b..6919f43ada 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -8,8 +8,8 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.UUID; -import org.apache.coyote.http11.HttpCookie; -import org.apache.coyote.http11.HttpCookieConvertor; +import org.apache.coyote.http11.httprequest.HttpCookie; +import org.apache.coyote.http11.httprequest.HttpCookieConvertor; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java similarity index 95% rename from tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java rename to tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index f892c46a27..85040d0cb7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.controller; import java.util.HashMap; import java.util.Map; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java similarity index 91% rename from tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java rename to tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java index 2ff402bc9d..b70d778f91 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.httprequest; import java.util.HashMap; import java.util.Map; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java similarity index 89% rename from tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java rename to tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java index 9f8eb528ad..b3cbc82964 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpCookieConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.httprequest; public class HttpCookieConvertor { From 9bff59a798a2aa589eee916bc49208eb99893e5a Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 9 Sep 2024 22:49:08 +0900 Subject: [PATCH 17/73] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/controller/RequestMapping.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index 85040d0cb7..cf45d59c97 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -2,11 +2,6 @@ import java.util.HashMap; import java.util.Map; -import org.apache.coyote.http11.controller.Controller; -import org.apache.coyote.http11.controller.LoginController; -import org.apache.coyote.http11.controller.DefaultController; -import org.apache.coyote.http11.controller.NotFoundController; -import org.apache.coyote.http11.controller.RegisterController; public class RequestMapping { From b3ae80d1d4279c4ec06e37b8b6d8f6134a073a11 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 09:22:30 +0900 Subject: [PATCH 18/73] =?UTF-8?q?test:=20=ED=95=99=EC=8A=B5=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 --- .../java/thread/stage0/SynchronizationTest.java | 7 +++---- .../test/java/thread/stage0/ThreadPoolsTest.java | 15 +++++++-------- .../http11/controller/RegisterController.java | 9 +++++---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/study/src/test/java/thread/stage0/SynchronizationTest.java b/study/src/test/java/thread/stage0/SynchronizationTest.java index 0333c18e3b..59afce5646 100644 --- a/study/src/test/java/thread/stage0/SynchronizationTest.java +++ b/study/src/test/java/thread/stage0/SynchronizationTest.java @@ -1,12 +1,11 @@ package thread.stage0; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; /** * 다중 스레드 환경에서 두 개 이상의 스레드가 변경 가능한(mutable) 공유 데이터를 동시에 업데이트하면 경쟁 조건(race condition)이 발생한다. @@ -41,7 +40,7 @@ private static final class SynchronizedMethods { private int sum = 0; - public void calculate() { + public synchronized void calculate() { setSum(getSum() + 1); } diff --git a/study/src/test/java/thread/stage0/ThreadPoolsTest.java b/study/src/test/java/thread/stage0/ThreadPoolsTest.java index 238611ebfe..c3ecd5c80c 100644 --- a/study/src/test/java/thread/stage0/ThreadPoolsTest.java +++ b/study/src/test/java/thread/stage0/ThreadPoolsTest.java @@ -1,13 +1,12 @@ package thread.stage0; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.assertj.core.api.Assertions.assertThat; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * 스레드 풀은 무엇이고 어떻게 동작할까? @@ -31,8 +30,8 @@ void testNewFixedThreadPool() { executor.submit(logWithSleep("hello fixed thread pools")); // 올바른 값으로 바꿔서 테스트를 통과시키자. - final int expectedPoolSize = 0; - final int expectedQueueSize = 0; + final int expectedPoolSize = 2; + final int expectedQueueSize = 1; assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize()); assertThat(expectedQueueSize).isEqualTo(executor.getQueue().size()); @@ -46,7 +45,7 @@ void testNewCachedThreadPool() { executor.submit(logWithSleep("hello cached thread pools")); // 올바른 값으로 바꿔서 테스트를 통과시키자. - final int expectedPoolSize = 0; + final int expectedPoolSize = 3; final int expectedQueueSize = 0; assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize()); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index f1973f4fc7..01da24ee54 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -21,28 +21,29 @@ public class RegisterController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { + HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); if (checkToken(token)) { log.error("일부 항목이 누락되었습니다."); - return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + return new HttpResponse.Builder(httpStatusLine) .location("/register") .build(); } + String account = token[0].split("=")[1]; if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); - return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + return new HttpResponse.Builder(httpStatusLine) .location("/register") .build(); } + String email = token[1].split("=")[1]; String password = token[2].split("=")[1]; User user = new User(account, password, email); InMemoryUserRepository.save(user); - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); - return new HttpResponse.Builder(httpStatusLine) .location("/index.html") .build(); From a522403ce623f0c5d5bd43f149d34e046877ffa1 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 09:54:08 +0900 Subject: [PATCH 19/73] =?UTF-8?q?refactor:=20depth=20=EA=B0=90=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/controller/LoginController.java | 50 +++++++++++-------- .../httprequest/HttpCookieConvertor.java | 20 +++++--- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 6919f43ada..82109dacf5 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -64,35 +64,43 @@ private boolean checkToken(String[] token) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); + if (!httpRequest.containsKey("Cookie")) { + return redirectLoginPage(httpRequest); + } - if (httpRequest.containsKey("Cookie")) { - HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue("Cookie")); - if (httpCookie.containsKey("JSESSIONID")) { - String jsessionid = httpCookie.getValue("JSESSIONID"); - if (session.containsUser(jsessionid)) { - User user = session.getUser(jsessionid); - log.info(user.toString()); - httpStatusLine = new HttpStatusLine(httpStatusLine.getVersion(), HttpStatusCode.FOUND); - return new HttpResponse.Builder(httpStatusLine) - .setCookie("JSESSIONID=" + jsessionid) - .location("/index.html") - .build(); - } - } + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue("Cookie")); + if (!httpCookie.containsKey("JSESSIONID")) { + return redirectLoginPage(httpRequest); } - var resourceUrl = getClass().getClassLoader().getResource(LOGIN_PATH); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); + String jsessionid = httpCookie.getValue("JSESSIONID"); + if (!session.containsUser(jsessionid)) { + return redirectLoginPage(httpRequest); + } + User user = session.getUser(jsessionid); + log.info(user.toString()); + HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); return new HttpResponse.Builder(httpStatusLine) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) + .setCookie("JSESSIONID=" + jsessionid) + .location("/index.html") .build(); } catch (URISyntaxException | IOException e) { throw new RuntimeException(e); } } + + private HttpResponse redirectLoginPage(HttpRequest httpRequest) throws URISyntaxException, IOException { + HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); + + var resourceUrl = getClass().getClassLoader().getResource(LOGIN_PATH); + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java index b3cbc82964..e36cf767ac 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java @@ -1,15 +1,21 @@ package org.apache.coyote.http11.httprequest; +import java.util.Arrays; + public class HttpCookieConvertor { - public static HttpCookie convertHttpCookie(String cookie) { + public static HttpCookie convertHttpCookie(String rowCookie) { HttpCookie httpCookie = new HttpCookie(); - String[] cookies = cookie.split("; "); - for (String c : cookies) { - if (c.split("=").length >= 2) { - httpCookie.addCookie(c.split("=")[0], c.split("=")[1]); - } - } + String[] cookieTokens = rowCookie.split("; "); + Arrays.stream(cookieTokens) + .filter(HttpCookieConvertor::filterCookie) + .map(cookieToken -> cookieToken.split("=")) + .forEach(cookie -> httpCookie.addCookie(cookie[0], cookie[1])); + return httpCookie; } + + private static boolean filterCookie(String cookie) { + return cookie.split("=").length >= 2; + } } From 32738721fb3caee558d51945fc8bb171fbe7e150 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 10:10:03 +0900 Subject: [PATCH 20/73] =?UTF-8?q?refactor:=20=ED=8A=B9=EC=A0=95=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=B2=98=EB=A6=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/HttpStatusCode.java | 1 + .../config/UnauthorizedInterceptor.java | 22 +++++++++++ .../http11/controller/RequestMapping.java | 7 ++++ .../controller/UnauthorizedController.java | 37 +++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java index e9c98e7e3d..1d41586ef4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatusCode.java @@ -4,6 +4,7 @@ public enum HttpStatusCode { OK(200, "OK"), FOUND(302, "Found"), + UNAUTHORIZED(401, "Unauthorized"), NOT_FOUND(404, "Not Found") ; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java new file mode 100644 index 0000000000..c6340e31b4 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java @@ -0,0 +1,22 @@ +package org.apache.coyote.http11.config; + +import java.util.HashSet; +import java.util.Set; + +public class UnauthorizedInterceptor { + + private final Set unauthorizedPaths = new HashSet<>(); + + public UnauthorizedInterceptor() { + unauthorizedPaths.add("/401"); + unauthorizedPaths.add("/404"); + unauthorizedPaths.add("/500"); + unauthorizedPaths.add("/401.html"); + unauthorizedPaths.add("/404.html"); + unauthorizedPaths.add("/500.html"); + } + + public boolean checkPath(String path) { + return unauthorizedPaths.contains(path); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index cf45d59c97..32dc8ec586 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -2,17 +2,24 @@ import java.util.HashMap; import java.util.Map; +import org.apache.coyote.http11.config.UnauthorizedInterceptor; public class RequestMapping { private final Map controllers = new HashMap<>(); + private final UnauthorizedInterceptor unauthorizedInterceptor; public RequestMapping() { + this.unauthorizedInterceptor = new UnauthorizedInterceptor(); controllers.put("/login", new LoginController()); controllers.put("/register", new RegisterController()); } public Controller getController(String path) { + if (unauthorizedInterceptor.checkPath(path)) { + return new UnauthorizedController(); + } + if (controllers.containsKey(path)) { return controllers.get(path); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java new file mode 100644 index 0000000000..6b29844f05 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -0,0 +1,37 @@ +package org.apache.coyote.http11.controller; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.coyote.http11.HttpStatusCode; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httpresponse.HttpResponse; +import org.apache.coyote.http11.httpresponse.HttpStatusLine; + +public class UnauthorizedController extends AbstractController { + + @Override + protected HttpResponse doPost(HttpRequest httpRequest) { + throw new RuntimeException(); + } + + @Override + protected HttpResponse doGet(HttpRequest httpRequest) { + try { + String fileName = "static/401.html"; + var resourceUrl = getClass().getClassLoader().getResource(fileName); + HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED); + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + return new HttpResponse.Builder(httpStatusLine) + .contentType(Files.probeContentType(filePath) + ";charset=utf-8") + .contentLength(String.valueOf(responseBody.getBytes().length)) + .responseBody(responseBody) + .build(); + } catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } + } +} From a4cc800c49697151cbba7af66df1b6fa9d03d5b6 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 10:14:56 +0900 Subject: [PATCH 21/73] =?UTF-8?q?refactor:=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=8B=9C=20redirect=EB=8A=94=20=EC=A0=9C?= =?UTF-8?q?=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/http11/Http11Processor.java | 2 +- .../coyote/http11/config/UnauthorizedInterceptor.java | 5 +++-- .../org/apache/coyote/http11/controller/RequestMapping.java | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index cf9ccfadc7..d854774036 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -40,7 +40,7 @@ public void process(final Socket connection) { RequestMapping requestMapping = new RequestMapping(); - Controller controller = requestMapping.getController(httpRequest.getPath()); + Controller controller = requestMapping.getController(httpRequest); HttpResponse httpResponse = controller.service(httpRequest); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java index c6340e31b4..ed49a3abf0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java @@ -2,6 +2,7 @@ import java.util.HashSet; import java.util.Set; +import org.apache.coyote.http11.httprequest.HttpRequest; public class UnauthorizedInterceptor { @@ -16,7 +17,7 @@ public UnauthorizedInterceptor() { unauthorizedPaths.add("/500.html"); } - public boolean checkPath(String path) { - return unauthorizedPaths.contains(path); + public boolean checkPath(HttpRequest httpRequest) { + return !httpRequest.containsKey("Location") && unauthorizedPaths.contains(httpRequest.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index 32dc8ec586..ecdf792490 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -3,6 +3,7 @@ import java.util.HashMap; import java.util.Map; import org.apache.coyote.http11.config.UnauthorizedInterceptor; +import org.apache.coyote.http11.httprequest.HttpRequest; public class RequestMapping { @@ -15,11 +16,12 @@ public RequestMapping() { controllers.put("/register", new RegisterController()); } - public Controller getController(String path) { - if (unauthorizedInterceptor.checkPath(path)) { + public Controller getController(HttpRequest httpRequest) { + if (unauthorizedInterceptor.checkPath(httpRequest)) { return new UnauthorizedController(); } + String path = httpRequest.getPath(); if (controllers.containsKey(path)) { return controllers.get(path); } From 5f3957e46cce74d3f4a96f72772400f775319201 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 10:32:37 +0900 Subject: [PATCH 22/73] =?UTF-8?q?refactor:=204=EB=8B=A8=EA=B3=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 --- .../apache/catalina/connector/Connector.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java index ffa86b6f34..d171bb84a8 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -1,15 +1,12 @@ package org.apache.catalina.connector; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import org.apache.coyote.http11.Http11Processor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.io.UncheckedIOException; import java.net.ServerSocket; import java.net.Socket; +import org.apache.coyote.http11.Http11Processor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Connector implements Runnable { @@ -17,19 +14,16 @@ public class Connector implements Runnable { private static final int DEFAULT_PORT = 8080; private static final int DEFAULT_ACCEPT_COUNT = 100; - private static final int DEFAULT_MAX_THREADS = 250; private final ServerSocket serverSocket; - private final ExecutorService executorService; private boolean stopped; public Connector() { - this(DEFAULT_PORT, DEFAULT_MAX_THREADS, DEFAULT_ACCEPT_COUNT); + this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); } - public Connector(final int port, final int acceptCount, final int maxThreads) { + public Connector(final int port, final int acceptCount) { this.serverSocket = createServerSocket(port, acceptCount); - this.executorService = Executors.newFixedThreadPool(maxThreads); this.stopped = false; } @@ -72,7 +66,7 @@ private void process(final Socket connection) { return; } var processor = new Http11Processor(connection); - executorService.execute(processor); + new Thread(processor).start(); } public void stop() { From 7277aa22d725318d8050514319d4dee9a6259554 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 10:37:36 +0900 Subject: [PATCH 23/73] =?UTF-8?q?refactor:=204=EB=8B=A8=EA=B3=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 --- tomcat/src/main/java/org/apache/coyote/http11/Session.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Session.java b/tomcat/src/main/java/org/apache/coyote/http11/Session.java index 7557d8c3ba..424b9cf6f9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Session.java @@ -1,9 +1,9 @@ package org.apache.coyote.http11; import com.techcourse.model.User; +import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; public class Session { @@ -11,7 +11,7 @@ public class Session { private final Map userMap; private Session() { - this.userMap = new ConcurrentHashMap<>(); + this.userMap = new HashMap<>(); } public static Session getInstance() { From 79da6055e4737f925f1003323419031696ae05bf Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 19:57:51 +0900 Subject: [PATCH 24/73] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/HttpRequestConvertor.java | 4 +++- .../coyote/http11/httprequest/HttpCookieConvertor.java | 9 ++++++--- .../coyote/http11/httprequest/HttpRequestLine.java | 4 +++- .../coyote/http11/httpresponse/HttpResponseHeader.java | 6 ++++-- .../coyote/http11/httpresponse/HttpStatusLine.java | 8 ++++++-- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index cd992e7d10..bb4c85a957 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -11,6 +11,8 @@ public class HttpRequestConvertor { + private static final String HEADER_DELIMITER = ":"; + public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) { try { String requestLine = bufferedReader.readLine(); @@ -51,7 +53,7 @@ private static Map getHeaders(BufferedReader bufferedReader) thr String line; Map headers = new HashMap<>(); while ((line = bufferedReader.readLine()) != null && !line.isEmpty()) { - String[] requestLine = line.split(":"); + String[] requestLine = line.split(HEADER_DELIMITER); headers.put(requestLine[0], parseHeaderValue(requestLine)); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java index e36cf767ac..468092ad82 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java @@ -4,18 +4,21 @@ public class HttpCookieConvertor { + private static final String COOKIE_DELIMITER = "; "; + private static final String COOKIE_TOKEN_DELIMITER = "="; + public static HttpCookie convertHttpCookie(String rowCookie) { HttpCookie httpCookie = new HttpCookie(); - String[] cookieTokens = rowCookie.split("; "); + String[] cookieTokens = rowCookie.split(COOKIE_DELIMITER); Arrays.stream(cookieTokens) .filter(HttpCookieConvertor::filterCookie) - .map(cookieToken -> cookieToken.split("=")) + .map(cookieToken -> cookieToken.split(COOKIE_TOKEN_DELIMITER)) .forEach(cookie -> httpCookie.addCookie(cookie[0], cookie[1])); return httpCookie; } private static boolean filterCookie(String cookie) { - return cookie.split("=").length >= 2; + return cookie.split(COOKIE_TOKEN_DELIMITER).length >= 2; } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index 6befc619d4..b076cb81aa 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -4,12 +4,14 @@ public class HttpRequestLine { + private static final String HEADER_DELIMITER = " "; + private final HttpMethod method; private final String path; private final String version; public HttpRequestLine(String requestLine) { - String[] headerFirstLine = requestLine.split(" "); + String[] headerFirstLine = requestLine.split(HEADER_DELIMITER); this.method = HttpMethod.getHttpMethod(headerFirstLine[0]); this.path = headerFirstLine[1]; this.version = headerFirstLine[2]; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index bc934d13d4..d89c77626a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -5,6 +5,8 @@ public class HttpResponseHeader { + private static final String HEADER_DELIMITER = ": "; + private final Map headers; public HttpResponseHeader(Map headers) { @@ -17,10 +19,10 @@ public String getString() { int i = 1; for (HttpHeaderName key : headers.keySet()) { if (i < size) { - sb.append(key.getName()).append(": ").append(headers.get(key)).append(" \r\n"); + sb.append(key.getName()).append(HEADER_DELIMITER).append(headers.get(key)).append(" \r\n"); size++; } else { - sb.append(key.getName()).append(": ").append(headers.get(key)); + sb.append(key.getName()).append(HEADER_DELIMITER).append(headers.get(key)); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index 5e4e97937a..9d56e9d097 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -13,8 +13,12 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { } public String getString() { - return version + " " + httpStatusCode.getCode() + " " - + httpStatusCode.getMessage(); + return String.join( + " ", + version, + String.valueOf(httpStatusCode.getCode()), + httpStatusCode.getMessage() + ); } public String getVersion() { From 2740606f84f6a704e901663d9b4c2072bc536f3f Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 20:55:58 +0900 Subject: [PATCH 25/73] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http11/HttpRequestConvertor.java | 4 ++-- .../apache/coyote/http11/controller/AbstractController.java | 5 +++-- .../apache/coyote/http11/controller/DefaultController.java | 4 ++-- .../org/apache/coyote/http11/controller/LoginController.java | 2 +- .../apache/coyote/http11/controller/NotFoundController.java | 4 ++-- .../apache/coyote/http11/controller/RegisterController.java | 2 +- .../coyote/http11/controller/UnauthorizedController.java | 4 ++-- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index bb4c85a957..4bb1ea2580 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -17,7 +17,7 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) { try { String requestLine = bufferedReader.readLine(); if (requestLine == null) { - throw new RuntimeException("요청이 비어 있습니다."); + throw new IllegalArgumentException("요청이 비어 있습니다."); } HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); @@ -34,7 +34,7 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) { return new HttpRequest(httpRequestLine, httpRequestHeader); } catch (IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java index e52a2508da..b77ba07afc 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java @@ -9,11 +9,12 @@ public abstract class AbstractController implements Controller { public HttpResponse service(HttpRequest httpRequest) { if (httpRequest.isMethod("GET")) { return doGet(httpRequest); - } else if (httpRequest.isMethod("POST")) { + } + if (httpRequest.isMethod("POST")) { return doPost(httpRequest); } - throw new RuntimeException(); + throw new IllegalArgumentException("유효하지 않은 메소드입니다."); } abstract protected HttpResponse doPost(HttpRequest httpRequest); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java index d9fb1c2b3d..7c2a0d1734 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java @@ -13,7 +13,7 @@ public class DefaultController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - throw new RuntimeException(); + throw new IllegalArgumentException(); } @Override @@ -37,7 +37,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { .responseBody(responseBody) .build(); } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 82109dacf5..5c5eb8142a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -86,7 +86,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { .location("/index.html") .build(); } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java index 5dc13a9d3b..304c0b0ca0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java @@ -13,7 +13,7 @@ public class NotFoundController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - throw new RuntimeException(); + throw new IllegalArgumentException("유효하지 않은 메소드 입니다."); } @Override @@ -31,7 +31,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { .responseBody(responseBody) .build(); } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 01da24ee54..6b6884f13a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -68,7 +68,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { .responseBody(responseBody) .build(); } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java index 6b29844f05..f420b4e893 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -13,7 +13,7 @@ public class UnauthorizedController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - throw new RuntimeException(); + throw new IllegalArgumentException(); } @Override @@ -31,7 +31,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { .responseBody(responseBody) .build(); } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException(e); } } } From 5de4b86d5c7c9727a3aad545a3164448d1b4ac45 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 21:56:12 +0900 Subject: [PATCH 26/73] =?UTF-8?q?refactor:=20HttpResponse=EC=9D=98=20Build?= =?UTF-8?q?er=20=ED=8C=A8=ED=84=B4=20=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/Http11Processor.java | 33 +++++++++++--- .../coyote/http11/HttpRequestConvertor.java | 30 ++++++------- .../http11/controller/DefaultController.java | 43 ------------------- .../http11/controller/LoginController.java | 32 ++++---------- .../http11/controller/NotFoundController.java | 37 ---------------- .../http11/controller/RegisterController.java | 29 ++++--------- .../http11/controller/RequestMapping.java | 7 ++- .../controller/UnauthorizedController.java | 3 +- .../http11/exception/NotFoundException.java | 8 ++++ .../http11/httpresponse/HttpResponse.java | 35 +++++++++++++++ 10 files changed, 105 insertions(+), 152 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java delete mode 100644 tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/exception/NotFoundException.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index d854774036..5e85e1f645 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -5,9 +5,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; +import java.net.URISyntaxException; import org.apache.coyote.Processor; import org.apache.coyote.http11.controller.Controller; import org.apache.coyote.http11.controller.RequestMapping; +import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; @@ -38,11 +40,7 @@ public void process(final Socket connection) { var bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); - RequestMapping requestMapping = new RequestMapping(); - - Controller controller = requestMapping.getController(httpRequest); - - HttpResponse httpResponse = controller.service(httpRequest); + HttpResponse httpResponse = getHttpResponse(httpRequest); outputStream.write(httpResponse.getBytes()); outputStream.flush(); @@ -50,4 +48,29 @@ public void process(final Socket connection) { log.error(e.getMessage(), e); } } + + private HttpResponse getHttpResponse(HttpRequest httpRequest) { + try { + if (isStaticResource(httpRequest)) { + return HttpResponse.ok(httpRequest) + .staticResource(httpRequest.getPath()) + .build(); + } + RequestMapping requestMapping = new RequestMapping(); + + Controller controller = requestMapping.getController(httpRequest); + + return controller.service(httpRequest); + } catch (NotFoundException e) { + return HttpResponse.found(httpRequest) + .location("/404.html") + .build(); + } catch (URISyntaxException | IOException e) { + throw new IllegalArgumentException(e); + } + } + + private boolean isStaticResource(HttpRequest httpRequest) { + return httpRequest.getMethod() == HttpMethod.GET && httpRequest.getPath().contains("."); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 4bb1ea2580..09941cd06c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -13,29 +13,25 @@ public class HttpRequestConvertor { private static final String HEADER_DELIMITER = ":"; - public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) { - try { - String requestLine = bufferedReader.readLine(); - if (requestLine == null) { - throw new IllegalArgumentException("요청이 비어 있습니다."); - } - - HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); + public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { + String requestLine = bufferedReader.readLine(); + if (requestLine == null) { + throw new IllegalArgumentException("요청이 비어 있습니다."); + } - Map headers = getHeaders(bufferedReader); + HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); - HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); + Map headers = getHeaders(bufferedReader); - if (httpRequestHeader.containsKey("Content-Length")) { - HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); + HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); - return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); - } + if (httpRequestHeader.containsKey("Content-Length")) { + HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); - return new HttpRequest(httpRequestLine, httpRequestHeader); - } catch (IOException e) { - throw new IllegalArgumentException(e); + return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); } + + return new HttpRequest(httpRequestLine, httpRequestHeader); } private static HttpRequestBody getHttpRequestBody( diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java deleted file mode 100644 index 7c2a0d1734..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/DefaultController.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.apache.coyote.http11.controller; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.coyote.http11.HttpStatusCode; -import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpStatusLine; - -public class DefaultController extends AbstractController { - - @Override - protected HttpResponse doPost(HttpRequest httpRequest) { - throw new IllegalArgumentException(); - } - - @Override - protected HttpResponse doGet(HttpRequest httpRequest) { - try { - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); - - String path = httpRequest.getPath(); - if (!httpRequest.getPath().contains(".")) { - path += ".html"; - } - String fileName = "static" + path; - var resourceUrl = getClass().getClassLoader().getResource(fileName); - - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - return new HttpResponse.Builder(httpStatusLine) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) - .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); - } - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 5c5eb8142a..35729822b8 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -4,24 +4,20 @@ import com.techcourse.model.User; import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.UUID; +import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpCookie; import org.apache.coyote.http11.httprequest.HttpCookieConvertor; -import org.apache.coyote.http11.HttpStatusCode; -import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpStatusLine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoginController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); - private static final String LOGIN_PATH = "static/login.html"; + private static final String LOGIN_PATH = "/login.html"; private final Session session = Session.getInstance(); @@ -31,7 +27,7 @@ protected HttpResponse doPost(HttpRequest httpRequest) { String[] token = requestBody.split("&"); if (checkToken(token)) { log.error("일부 항목이 누락되었습니다."); - return new HttpResponse.Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)) + return HttpResponse.found(httpRequest) .location("/login") .build(); } @@ -42,17 +38,16 @@ protected HttpResponse doPost(HttpRequest httpRequest) { .orElseThrow(); UUID uuid = UUID.randomUUID(); - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); if (user.checkPassword(password)) { session.save(uuid.toString(), user); log.info(user.toString()); - return new HttpResponse.Builder(httpStatusLine) + return HttpResponse.found(httpRequest) .setCookie("JSESSIONID=" + uuid) .location("/index.html") .build(); } log.error("비밀번호 불일치"); - return new HttpResponse.Builder(httpStatusLine) + return HttpResponse.found(httpRequest) .location("/401.html") .build(); } @@ -80,8 +75,7 @@ protected HttpResponse doGet(HttpRequest httpRequest) { User user = session.getUser(jsessionid); log.info(user.toString()); - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); - return new HttpResponse.Builder(httpStatusLine) + return HttpResponse.found(httpRequest) .setCookie("JSESSIONID=" + jsessionid) .location("/index.html") .build(); @@ -90,17 +84,9 @@ protected HttpResponse doGet(HttpRequest httpRequest) { } } - private HttpResponse redirectLoginPage(HttpRequest httpRequest) throws URISyntaxException, IOException { - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); - - var resourceUrl = getClass().getClassLoader().getResource(LOGIN_PATH); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - return new HttpResponse.Builder(httpStatusLine) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) + private HttpResponse redirectLoginPage(HttpRequest httpRequest) throws IOException, URISyntaxException { + return HttpResponse.ok(httpRequest) + .staticResource(LOGIN_PATH) .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java deleted file mode 100644 index 304c0b0ca0..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/NotFoundController.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.apache.coyote.http11.controller; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.coyote.http11.HttpStatusCode; -import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpStatusLine; - -public class NotFoundController extends AbstractController { - - @Override - protected HttpResponse doPost(HttpRequest httpRequest) { - throw new IllegalArgumentException("유효하지 않은 메소드 입니다."); - } - - @Override - protected HttpResponse doGet(HttpRequest httpRequest) { - try { - String fileName = "static/404.html"; - var resourceUrl = getClass().getClassLoader().getResource(fileName); - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.NOT_FOUND); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - return new HttpResponse.Builder(httpStatusLine) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) - .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); - } - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 6b6884f13a..b9da555798 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -4,38 +4,33 @@ import com.techcourse.model.User; import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; -import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpStatusLine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RegisterController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(RegisterController.class); - private static final String REGISTER_PATH = "static/register.html"; + private static final String REGISTER_PATH = "/register"; @Override protected HttpResponse doPost(HttpRequest httpRequest) { - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); String requestBody = httpRequest.getBody(); String[] token = requestBody.split("&"); if (checkToken(token)) { log.error("일부 항목이 누락되었습니다."); - return new HttpResponse.Builder(httpStatusLine) - .location("/register") + return HttpResponse.found(httpRequest) + .location(REGISTER_PATH) .build(); } String account = token[0].split("=")[1]; if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); - return new HttpResponse.Builder(httpStatusLine) - .location("/register") + return HttpResponse.found(httpRequest) + .location(REGISTER_PATH) .build(); } @@ -44,7 +39,7 @@ protected HttpResponse doPost(HttpRequest httpRequest) { User user = new User(account, password, email); InMemoryUserRepository.save(user); - return new HttpResponse.Builder(httpStatusLine) + return HttpResponse.found(httpRequest) .location("/index.html") .build(); } @@ -56,16 +51,8 @@ private boolean checkToken(String[] token) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); - - var resourceUrl = getClass().getClassLoader().getResource(REGISTER_PATH); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - return new HttpResponse.Builder(httpStatusLine) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) + return HttpResponse.ok(httpRequest) + .staticResource(httpRequest.getPath()) .build(); } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index ecdf792490..1b1a4e3162 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -3,6 +3,7 @@ import java.util.HashMap; import java.util.Map; import org.apache.coyote.http11.config.UnauthorizedInterceptor; +import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.httprequest.HttpRequest; public class RequestMapping { @@ -25,9 +26,7 @@ public Controller getController(HttpRequest httpRequest) { if (controllers.containsKey(path)) { return controllers.get(path); } - if (getClass().getClassLoader().getResource("static" + path) == null) { - return new NotFoundController(); - } - return new DefaultController(); + + throw new NotFoundException("존재하지 않는 경로입니다."); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java index f420b4e893..28309c6c05 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -21,11 +21,10 @@ protected HttpResponse doGet(HttpRequest httpRequest) { try { String fileName = "static/401.html"; var resourceUrl = getClass().getClassLoader().getResource(fileName); - HttpStatusLine httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - return new HttpResponse.Builder(httpStatusLine) + return HttpResponse.unauthorized(httpRequest) .contentType(Files.probeContentType(filePath) + ";charset=utf-8") .contentLength(String.valueOf(responseBody.getBytes().length)) .responseBody(responseBody) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/exception/NotFoundException.java b/tomcat/src/main/java/org/apache/coyote/http11/exception/NotFoundException.java new file mode 100644 index 0000000000..441c69b4a6 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/exception/NotFoundException.java @@ -0,0 +1,8 @@ +package org.apache.coyote.http11.exception; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 92bceac710..b6a232a43f 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -1,8 +1,15 @@ package org.apache.coyote.http11.httpresponse; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import org.apache.coyote.http11.HttpHeaderName; +import org.apache.coyote.http11.HttpStatusCode; +import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.httprequest.HttpRequest; public class HttpResponse { @@ -20,6 +27,18 @@ private HttpResponse( this.httpResponseBody = httpResponseBody; } + public static Builder ok(HttpRequest httpRequest) { + return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK)); + } + + public static Builder found(HttpRequest httpRequest) { + return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)); + } + + public static Builder unauthorized(HttpRequest httpRequest) { + return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED)); + } + public byte[] getBytes() { String statusLine = httpStatusLine.getString(); @@ -81,6 +100,22 @@ public Builder setCookie(String setCookie) { return this; } + public Builder staticResource(String path) throws IOException, URISyntaxException { + String fileName = "static" + path; + var resourceUrl = getClass().getClassLoader().getResource(fileName); + if (resourceUrl == null) { + throw new NotFoundException("존재하지 않는 경로입니다."); + } + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + contentType(Files.probeContentType(filePath) + ";charset=utf-8"); + contentLength(String.valueOf(responseBody.getBytes().length)); + this.httpResponseBody = new HttpResponseBody(responseBody); + + return this; + } + public Builder responseBody(String responseBody) { this.httpResponseBody = new HttpResponseBody(responseBody); return this; From 76debc677a832fc459021c79fcc51003386c3911 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 22:10:38 +0900 Subject: [PATCH 27/73] =?UTF-8?q?refactor:=20IO=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/controller/LoginController.java | 4 ++-- .../http11/controller/UnauthorizedController.java | 13 +------------ .../coyote/http11/httpresponse/HttpResponse.java | 3 +++ 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 35729822b8..b5a6e55461 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -17,7 +17,7 @@ public class LoginController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); - private static final String LOGIN_PATH = "/login.html"; + private static final String LOGIN_PATH = "/login"; private final Session session = Session.getInstance(); @@ -28,7 +28,7 @@ protected HttpResponse doPost(HttpRequest httpRequest) { if (checkToken(token)) { log.error("일부 항목이 누락되었습니다."); return HttpResponse.found(httpRequest) - .location("/login") + .location(LOGIN_PATH) .build(); } String account = token[0].split("=")[1]; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java index 28309c6c05..86335b1f89 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -2,12 +2,8 @@ import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; -import org.apache.coyote.http11.httpresponse.HttpStatusLine; public class UnauthorizedController extends AbstractController { @@ -19,15 +15,8 @@ protected HttpResponse doPost(HttpRequest httpRequest) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { - String fileName = "static/401.html"; - var resourceUrl = getClass().getClassLoader().getResource(fileName); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - return HttpResponse.unauthorized(httpRequest) - .contentType(Files.probeContentType(filePath) + ";charset=utf-8") - .contentLength(String.valueOf(responseBody.getBytes().length)) - .responseBody(responseBody) + .staticResource("/401.html") .build(); } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index b6a232a43f..ee3f5c87b7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -101,6 +101,9 @@ public Builder setCookie(String setCookie) { } public Builder staticResource(String path) throws IOException, URISyntaxException { + if (!path.contains(".")) { + path += ".html"; + } String fileName = "static" + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); if (resourceUrl == null) { From 365c1bf52da2f541f494b0b7216f7ccf69d4989c Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 22:19:38 +0900 Subject: [PATCH 28/73] =?UTF-8?q?refactor:=20HttpHeaderName=EC=9D=84=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=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 --- .../org/apache/coyote/http11/ContentType.java | 17 +++++++++++++++++ .../apache/coyote/http11/Http11Processor.java | 3 ++- .../apache/coyote/http11/HttpHeaderName.java | 3 ++- .../coyote/http11/HttpRequestConvertor.java | 4 ++-- .../http11/config/UnauthorizedInterceptor.java | 3 ++- .../http11/controller/LoginController.java | 5 +++-- .../coyote/http11/httprequest/HttpRequest.java | 9 +++++++++ .../http11/httprequest/HttpRequestHeader.java | 9 +++++++++ .../http11/httpresponse/HttpResponse.java | 3 ++- 9 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/ContentType.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java new file mode 100644 index 0000000000..756c70dd9d --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java @@ -0,0 +1,17 @@ +package org.apache.coyote.http11; + +public enum ContentType { + + UTF_8(";charset=utf-8") + ; + + private final String charset; + + ContentType(String charset) { + this.charset = charset; + } + + public String getCharset() { + return charset; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 5e85e1f645..5142525bc5 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -18,6 +18,7 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); + private static final String NOT_FOUND_PATH = "/404.html"; private final Socket connection; @@ -63,7 +64,7 @@ private HttpResponse getHttpResponse(HttpRequest httpRequest) { return controller.service(httpRequest); } catch (NotFoundException e) { return HttpResponse.found(httpRequest) - .location("/404.html") + .location(NOT_FOUND_PATH) .build(); } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java index 25a205f8c8..e5f505ac08 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpHeaderName.java @@ -5,7 +5,8 @@ public enum HttpHeaderName { CONTENT_TYPE("Content-Type"), SET_COOKIE("Set-Cookie"), CONTENT_LENGTH("Content-Length"), - LOCATION("Location") + LOCATION("Location"), + COOKIE("Cookie") ; private final String name; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 09941cd06c..cf6fe1ffc9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -25,7 +25,7 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); - if (httpRequestHeader.containsKey("Content-Length")) { + if (httpRequestHeader.containsKey(HttpHeaderName.CONTENT_LENGTH)) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); @@ -38,7 +38,7 @@ private static HttpRequestBody getHttpRequestBody( BufferedReader bufferedReader, HttpRequestHeader httpRequestHeader ) throws IOException { - int contentLength = Integer.parseInt(httpRequestHeader.getValue("Content-Length")); + int contentLength = Integer.parseInt(httpRequestHeader.getValue(HttpHeaderName.CONTENT_LENGTH)); char[] buffer = new char[contentLength]; bufferedReader.read(buffer, 0, contentLength); String body = new String(buffer); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java index ed49a3abf0..b65daf1d82 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java @@ -2,6 +2,7 @@ import java.util.HashSet; import java.util.Set; +import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.httprequest.HttpRequest; public class UnauthorizedInterceptor { @@ -18,6 +19,6 @@ public UnauthorizedInterceptor() { } public boolean checkPath(HttpRequest httpRequest) { - return !httpRequest.containsKey("Location") && unauthorizedPaths.contains(httpRequest.getPath()); + return !httpRequest.containsKey(HttpHeaderName.LOCATION) && unauthorizedPaths.contains(httpRequest.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index b5a6e55461..f5846e9a81 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -6,6 +6,7 @@ import java.net.URISyntaxException; import java.util.Arrays; import java.util.UUID; +import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.Session; import org.apache.coyote.http11.httprequest.HttpCookie; import org.apache.coyote.http11.httprequest.HttpCookieConvertor; @@ -59,11 +60,11 @@ private boolean checkToken(String[] token) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { - if (!httpRequest.containsKey("Cookie")) { + if (!httpRequest.containsKey(HttpHeaderName.COOKIE)) { return redirectLoginPage(httpRequest); } - HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue("Cookie")); + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue(HttpHeaderName.COOKIE)); if (!httpCookie.containsKey("JSESSIONID")) { return redirectLoginPage(httpRequest); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index fd22135bcb..efb30d9981 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -1,5 +1,6 @@ package org.apache.coyote.http11.httprequest; +import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpMethod; public class HttpRequest { @@ -30,10 +31,18 @@ public boolean containsKey(String key) { return httpRequestHeader.containsKey(key); } + public boolean containsKey(HttpHeaderName httpHeaderName) { + return httpRequestHeader.containsKey(httpHeaderName); + } + public String getValue(String key) { return httpRequestHeader.getValue(key); } + public String getValue(HttpHeaderName httpHeaderName) { + return httpRequestHeader.getValue(httpHeaderName); + } + public HttpMethod getMethod() { return httpRequestLine.getMethod(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java index 1145e6459a..c98e0caa6c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java @@ -1,6 +1,7 @@ package org.apache.coyote.http11.httprequest; import java.util.Map; +import org.apache.coyote.http11.HttpHeaderName; public class HttpRequestHeader { @@ -14,7 +15,15 @@ public boolean containsKey(String key) { return headers.containsKey(key); } + public boolean containsKey(HttpHeaderName httpHeaderName) { + return headers.containsKey(httpHeaderName.getName()); + } + public String getValue(String key) { return headers.get(key); } + + public String getValue(HttpHeaderName httpHeaderName) { + return headers.get(httpHeaderName.getName()); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index ee3f5c87b7..e63c5126e2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -6,6 +6,7 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; +import org.apache.coyote.http11.ContentType; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.exception.NotFoundException; @@ -112,7 +113,7 @@ public Builder staticResource(String path) throws IOException, URISyntaxExceptio Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - contentType(Files.probeContentType(filePath) + ";charset=utf-8"); + contentType(Files.probeContentType(filePath) + ContentType.UTF_8.getCharset()); contentLength(String.valueOf(responseBody.getBytes().length)); this.httpResponseBody = new HttpResponseBody(responseBody); From 7c78ae2d9c689038e261e40be59df9a248abc593 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Tue, 10 Sep 2024 22:23:00 +0900 Subject: [PATCH 29/73] =?UTF-8?q?refactor:=20HttpMethod=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=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 --- .../src/main/java/org/apache/coyote/http11/HttpMethod.java | 6 +++--- .../apache/coyote/http11/controller/AbstractController.java | 5 +++-- .../org/apache/coyote/http11/httprequest/HttpRequest.java | 4 ++-- .../apache/coyote/http11/httprequest/HttpRequestLine.java | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java index ba36e58a45..12676b3e71 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java @@ -10,12 +10,12 @@ public enum HttpMethod { public static HttpMethod getHttpMethod(String name) { return Arrays.stream(values()) - .filter(httpMethod -> httpMethod.isMethod(name)) + .filter(httpMethod -> httpMethod.name().equals(name)) .findAny() .orElseThrow(); } - public boolean isMethod(String name) { - return name().equals(name); + public boolean isMethod(HttpMethod method) { + return this.equals(method); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java index b77ba07afc..9ef89b1514 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java @@ -1,5 +1,6 @@ package org.apache.coyote.http11.controller; +import org.apache.coyote.http11.HttpMethod; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -7,10 +8,10 @@ public abstract class AbstractController implements Controller { @Override public HttpResponse service(HttpRequest httpRequest) { - if (httpRequest.isMethod("GET")) { + if (httpRequest.isMethod(HttpMethod.GET)) { return doGet(httpRequest); } - if (httpRequest.isMethod("POST")) { + if (httpRequest.isMethod(HttpMethod.POST)) { return doPost(httpRequest); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index efb30d9981..503c395437 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -19,8 +19,8 @@ public HttpRequest(HttpRequestLine httpRequestLine, HttpRequestHeader httpReques this(httpRequestLine, httpRequestHeader, null); } - public boolean isMethod(String name) { - return httpRequestLine.isMethod(name); + public boolean isMethod(HttpMethod method) { + return httpRequestLine.isMethod(method); } public boolean isPath(String path) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index b076cb81aa..4377722f14 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -17,8 +17,8 @@ public HttpRequestLine(String requestLine) { this.version = headerFirstLine[2]; } - public boolean isMethod(String name) { - return method.isMethod(name); + public boolean isMethod(HttpMethod method) { + return method.isMethod(method); } public boolean isPath(String path) { From 7c5471345c84bb92313274c87417c5635dc9c892 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 13:37:07 +0900 Subject: [PATCH 30/73] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/Http11Processor.java | 3 +- .../coyote/http11/HttpRequestConvertor.java | 3 -- .../http11/httpresponse/HttpResponse.java | 33 ++++++++++--------- .../http11/httpresponse/HttpStatusLine.java | 4 ++- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 5142525bc5..96bd7ac067 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -19,6 +19,7 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private static final String NOT_FOUND_PATH = "/404.html"; + private static final String CHECKED_STATIC_RESOURCE = "."; private final Socket connection; @@ -72,6 +73,6 @@ private HttpResponse getHttpResponse(HttpRequest httpRequest) { } private boolean isStaticResource(HttpRequest httpRequest) { - return httpRequest.getMethod() == HttpMethod.GET && httpRequest.getPath().contains("."); + return httpRequest.getMethod() == HttpMethod.GET && httpRequest.getPath().contains(CHECKED_STATIC_RESOURCE); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index cf6fe1ffc9..96902651ae 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -20,14 +20,11 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro } HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); - Map headers = getHeaders(bufferedReader); - HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); if (httpRequestHeader.containsKey(HttpHeaderName.CONTENT_LENGTH)) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); - return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index e63c5126e2..b2a5ba9108 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -14,6 +14,7 @@ public class HttpResponse { + private static final String RESPONSE_DELIMITER = "\r\n"; private final HttpStatusLine httpStatusLine; private final HttpResponseHeader httpResponseHeader; private final HttpResponseBody httpResponseBody; @@ -28,16 +29,16 @@ private HttpResponse( this.httpResponseBody = httpResponseBody; } - public static Builder ok(HttpRequest httpRequest) { - return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK)); + public static HttpResponseBuilder ok(HttpRequest httpRequest) { + return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK)); } - public static Builder found(HttpRequest httpRequest) { - return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)); + public static HttpResponseBuilder found(HttpRequest httpRequest) { + return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)); } - public static Builder unauthorized(HttpRequest httpRequest) { - return new Builder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED)); + public static HttpResponseBuilder unauthorized(HttpRequest httpRequest) { + return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED)); } public byte[] getBytes() { @@ -47,13 +48,13 @@ public byte[] getBytes() { if (httpResponseBody != null) { String responseBody = httpResponseBody.getBody(); - String join = String.join("\r\n", + String join = String.join(RESPONSE_DELIMITER, statusLine, responseHeader, responseBody); return join.getBytes(); } - String join = String.join("\r\n", + String join = String.join(RESPONSE_DELIMITER, statusLine, responseHeader); return join.getBytes(); @@ -71,37 +72,37 @@ public HttpResponseBody getHttpResponseBody() { return httpResponseBody; } - public static class Builder { + public static class HttpResponseBuilder { private final HttpStatusLine httpStatusLine; private final Map headers; private HttpResponseBody httpResponseBody; - public Builder(HttpStatusLine httpStatusLine) { + public HttpResponseBuilder(HttpStatusLine httpStatusLine) { this.httpStatusLine = httpStatusLine; this.headers = new HashMap<>(); } - public Builder location(String location) { + public HttpResponseBuilder location(String location) { headers.put(HttpHeaderName.LOCATION, location); return this; } - public Builder contentType(String contentType) { + public HttpResponseBuilder contentType(String contentType) { headers.put(HttpHeaderName.CONTENT_TYPE, contentType); return this; } - public Builder contentLength(String contentLength) { + public HttpResponseBuilder contentLength(String contentLength) { headers.put(HttpHeaderName.CONTENT_LENGTH, contentLength); return this; } - public Builder setCookie(String setCookie) { + public HttpResponseBuilder setCookie(String setCookie) { headers.put(HttpHeaderName.SET_COOKIE, setCookie); return this; } - public Builder staticResource(String path) throws IOException, URISyntaxException { + public HttpResponseBuilder staticResource(String path) throws IOException, URISyntaxException { if (!path.contains(".")) { path += ".html"; } @@ -120,7 +121,7 @@ public Builder staticResource(String path) throws IOException, URISyntaxExceptio return this; } - public Builder responseBody(String responseBody) { + public HttpResponseBuilder responseBody(String responseBody) { this.httpResponseBody = new HttpResponseBody(responseBody); return this; } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index 9d56e9d097..2751db0c82 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -4,6 +4,8 @@ public class HttpStatusLine { + private static final String STATUS_LINE_DELIMITER = " "; + private final String version; private final HttpStatusCode httpStatusCode; @@ -14,7 +16,7 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { public String getString() { return String.join( - " ", + STATUS_LINE_DELIMITER, version, String.valueOf(httpStatusCode.getCode()), httpStatusCode.getMessage() From c9082d1b6f8a2e02c7022ddf99e4a90e24e3f655 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 14:12:11 +0900 Subject: [PATCH 31/73] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=EC=9D=B4=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/httprequest/HttpRequestLine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index 4377722f14..57c5c309bf 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -18,7 +18,7 @@ public HttpRequestLine(String requestLine) { } public boolean isMethod(HttpMethod method) { - return method.isMethod(method); + return this.method.isMethod(method); } public boolean isPath(String path) { From 2320bd1a5e6407439415ae932612d97faa1c3225 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 14:37:38 +0900 Subject: [PATCH 32/73] =?UTF-8?q?refactor:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EC=97=90=EC=84=9C=20Body=EB=A5=BC=20=EC=A7=81?= =?UTF-8?q?=EC=A0=91=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/HttpRequestConvertor.java | 38 +++++++++++++------ .../config/UnauthorizedInterceptor.java | 2 +- .../http11/controller/LoginController.java | 16 ++------ .../http11/controller/RegisterController.java | 14 ++----- .../http11/httprequest/HttpRequest.java | 27 ++++++++----- .../http11/httprequest/HttpRequestBody.java | 16 ++++++-- .../http11/httprequest/HttpRequestHeader.java | 8 ++-- 7 files changed, 69 insertions(+), 52 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 96902651ae..21153821a0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -23,7 +23,9 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro Map headers = getHeaders(bufferedReader); HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); - if (httpRequestHeader.containsKey(HttpHeaderName.CONTENT_LENGTH)) { + if (httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) + && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals("application/x-www-form-urlencoded") + ) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); } @@ -31,17 +33,6 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro return new HttpRequest(httpRequestLine, httpRequestHeader); } - private static HttpRequestBody getHttpRequestBody( - BufferedReader bufferedReader, - HttpRequestHeader httpRequestHeader - ) throws IOException { - int contentLength = Integer.parseInt(httpRequestHeader.getValue(HttpHeaderName.CONTENT_LENGTH)); - char[] buffer = new char[contentLength]; - bufferedReader.read(buffer, 0, contentLength); - String body = new String(buffer); - return new HttpRequestBody(body); - } - private static Map getHeaders(BufferedReader bufferedReader) throws IOException { String line; Map headers = new HashMap<>(); @@ -61,4 +52,27 @@ private static String parseHeaderValue(String[] requestLine) { return sb.toString(); } + + private static HttpRequestBody getHttpRequestBody( + BufferedReader bufferedReader, + HttpRequestHeader httpRequestHeader + ) throws IOException { + int contentLength = Integer.parseInt(httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_LENGTH)); + char[] buffer = new char[contentLength]; + bufferedReader.read(buffer, 0, contentLength); + String requestBody = new String(buffer); + Map body = extractBody(requestBody); + return new HttpRequestBody(body); + } + + private static Map extractBody(String requestBody) { + Map body = new HashMap<>(); + String[] tokens = requestBody.split("&"); + for (String token : tokens) { + String key = token.split("=")[0]; + String value = token.split("=")[1]; + body.put(key, value); + } + return body; + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java index b65daf1d82..a066d72609 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java @@ -19,6 +19,6 @@ public UnauthorizedInterceptor() { } public boolean checkPath(HttpRequest httpRequest) { - return !httpRequest.containsKey(HttpHeaderName.LOCATION) && unauthorizedPaths.contains(httpRequest.getPath()); + return !httpRequest.containsHeader(HttpHeaderName.LOCATION) && unauthorizedPaths.contains(httpRequest.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index f5846e9a81..eacf01cd04 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -24,16 +24,8 @@ public class LoginController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - String requestBody = httpRequest.getBody(); - String[] token = requestBody.split("&"); - if (checkToken(token)) { - log.error("일부 항목이 누락되었습니다."); - return HttpResponse.found(httpRequest) - .location(LOGIN_PATH) - .build(); - } - String account = token[0].split("=")[1]; - String password = token[1].split("=")[1]; + String account = httpRequest.getBodyValue("account"); + String password = httpRequest.getBodyValue("password"); User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(); @@ -60,11 +52,11 @@ private boolean checkToken(String[] token) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { - if (!httpRequest.containsKey(HttpHeaderName.COOKIE)) { + if (!httpRequest.containsHeader(HttpHeaderName.COOKIE)) { return redirectLoginPage(httpRequest); } - HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getValue(HttpHeaderName.COOKIE)); + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getHeaderValue(HttpHeaderName.COOKIE)); if (!httpCookie.containsKey("JSESSIONID")) { return redirectLoginPage(httpRequest); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index b9da555798..9500cad2bb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -17,16 +17,10 @@ public class RegisterController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { - String requestBody = httpRequest.getBody(); - String[] token = requestBody.split("&"); - if (checkToken(token)) { - log.error("일부 항목이 누락되었습니다."); - return HttpResponse.found(httpRequest) - .location(REGISTER_PATH) - .build(); - } + String account = httpRequest.getBodyValue("account"); + String password = httpRequest.getBodyValue("password"); + String email = httpRequest.getBodyValue("email"); - String account = token[0].split("=")[1]; if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); return HttpResponse.found(httpRequest) @@ -34,8 +28,6 @@ protected HttpResponse doPost(HttpRequest httpRequest) { .build(); } - String email = token[1].split("=")[1]; - String password = token[2].split("=")[1]; User user = new User(account, password, email); InMemoryUserRepository.save(user); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index 503c395437..52b1aa69fa 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -1,5 +1,6 @@ package org.apache.coyote.http11.httprequest; +import java.util.Map; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpMethod; @@ -27,20 +28,28 @@ public boolean isPath(String path) { return httpRequestLine.isPath(path); } - public boolean containsKey(String key) { - return httpRequestHeader.containsKey(key); + public boolean containsHeader(String key) { + return httpRequestHeader.containsHeader(key); } - public boolean containsKey(HttpHeaderName httpHeaderName) { - return httpRequestHeader.containsKey(httpHeaderName); + public boolean containsHeader(HttpHeaderName httpHeaderName) { + return httpRequestHeader.containsHeader(httpHeaderName); } - public String getValue(String key) { - return httpRequestHeader.getValue(key); + public String getHeaderValue(String key) { + return httpRequestHeader.getHeaderValue(key); } - public String getValue(HttpHeaderName httpHeaderName) { - return httpRequestHeader.getValue(httpHeaderName); + public String getHeaderValue(HttpHeaderName httpHeaderName) { + return httpRequestHeader.getHeaderValue(httpHeaderName); + } + + public boolean containsBody(String key) { + return httpRequestBody.containsBody(key); + } + + public String getBodyValue(String key) { + return httpRequestBody.getBodyValue(key); } public HttpMethod getMethod() { @@ -55,7 +64,7 @@ public String getVersion() { return httpRequestLine.getVersion(); } - public String getBody() { + public Map getBody() { return httpRequestBody.getBody(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java index 7927bc9abb..6b7d6cb94e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestBody.java @@ -1,14 +1,24 @@ package org.apache.coyote.http11.httprequest; +import java.util.Map; + public class HttpRequestBody { - private final String body; + private final Map body; - public HttpRequestBody(String body) { + public HttpRequestBody(Map body) { this.body = body; } - public String getBody() { + public boolean containsBody(String key) { + return body.containsKey(key); + } + + public String getBodyValue(String key) { + return body.get(key); + } + + public Map getBody() { return body; } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java index c98e0caa6c..371d0f6d5d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java @@ -11,19 +11,19 @@ public HttpRequestHeader(Map headers) { this.headers = headers; } - public boolean containsKey(String key) { + public boolean containsHeader(String key) { return headers.containsKey(key); } - public boolean containsKey(HttpHeaderName httpHeaderName) { + public boolean containsHeader(HttpHeaderName httpHeaderName) { return headers.containsKey(httpHeaderName.getName()); } - public String getValue(String key) { + public String getHeaderValue(String key) { return headers.get(key); } - public String getValue(HttpHeaderName httpHeaderName) { + public String getHeaderValue(HttpHeaderName httpHeaderName) { return headers.get(httpHeaderName.getName()); } } From 0bd1a984372b364c215a13b79e079bde331edfe7 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 14:44:22 +0900 Subject: [PATCH 33/73] =?UTF-8?q?refactor:=20body=20=ED=8C=8C=EC=8B=B1=20?= =?UTF-8?q?=EC=8B=9C=20=ED=95=84=ED=84=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/HttpRequestConvertor.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 21153821a0..6183e6596c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -2,8 +2,10 @@ import java.io.BufferedReader; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httprequest.HttpRequestBody; import org.apache.coyote.http11.httprequest.HttpRequestHeader; @@ -66,13 +68,13 @@ private static HttpRequestBody getHttpRequestBody( } private static Map extractBody(String requestBody) { - Map body = new HashMap<>(); String[] tokens = requestBody.split("&"); - for (String token : tokens) { - String key = token.split("=")[0]; - String value = token.split("=")[1]; - body.put(key, value); - } - return body; + return Arrays.stream(tokens) + .filter(token -> token.split("=").length >= 2) + .map(token -> token.split("=")) + .collect(Collectors.toMap( + token -> token[0], + token -> token[1] + )); } } From 027ff0c2732dcb78b01805235b4e8789fb18941f Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 15:08:11 +0900 Subject: [PATCH 34/73] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/HttpRequestConvertor.java | 21 +++++++++----- .../http11/controller/LoginController.java | 29 ++++++++++--------- .../http11/controller/RegisterController.java | 17 +++++------ .../controller/UnauthorizedController.java | 4 ++- .../coyote/http11/httprequest/HttpCookie.java | 4 +-- .../httprequest/HttpCookieConvertor.java | 7 +++-- .../http11/httprequest/HttpRequestLine.java | 9 ++++-- .../http11/httpresponse/HttpResponse.java | 16 ++++++---- .../httpresponse/HttpResponseHeader.java | 14 ++++++--- 9 files changed, 73 insertions(+), 48 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 6183e6596c..99aa8dfbb1 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -14,6 +14,13 @@ public class HttpRequestConvertor { private static final String HEADER_DELIMITER = ":"; + private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String BODY_DELIMITER = "&"; + private static final String TUPLE_DELIMITER = "="; + private static final int TUPLE_MIN_LENGTH = 2; + private static final int TUPLE_KEY_INDEX = 0; + private static final int TUPLE_VALUE_INDEX = 1; + private static final int HEADER_KEY_INDEX = 0; public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); @@ -26,7 +33,7 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); if (httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) - && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals("application/x-www-form-urlencoded") + && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals(BODY_FORM_CONTENT_TYPE) ) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); @@ -40,7 +47,7 @@ private static Map getHeaders(BufferedReader bufferedReader) thr Map headers = new HashMap<>(); while ((line = bufferedReader.readLine()) != null && !line.isEmpty()) { String[] requestLine = line.split(HEADER_DELIMITER); - headers.put(requestLine[0], parseHeaderValue(requestLine)); + headers.put(requestLine[HEADER_KEY_INDEX], parseHeaderValue(requestLine)); } return headers; @@ -68,13 +75,13 @@ private static HttpRequestBody getHttpRequestBody( } private static Map extractBody(String requestBody) { - String[] tokens = requestBody.split("&"); + String[] tokens = requestBody.split(BODY_DELIMITER); return Arrays.stream(tokens) - .filter(token -> token.split("=").length >= 2) - .map(token -> token.split("=")) + .filter(token -> token.split(TUPLE_DELIMITER).length >= TUPLE_MIN_LENGTH) + .map(token -> token.split(TUPLE_DELIMITER)) .collect(Collectors.toMap( - token -> token[0], - token -> token[1] + token -> token[TUPLE_KEY_INDEX], + token -> token[TUPLE_VALUE_INDEX] )); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index eacf01cd04..8e84157927 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -4,7 +4,6 @@ import com.techcourse.model.User; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; import java.util.UUID; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.Session; @@ -19,13 +18,19 @@ public class LoginController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); private static final String LOGIN_PATH = "/login"; + private static final String ACCOUNT = "account"; + private static final String PASSWORD = "password"; + private static final String INDEX_PATH = "/index.html"; + private static final String UNAUTHORIZED_PATH = "/401.html"; + private static final String JSESSIONID = "JSESSIONID"; + private static final String COOKIE_DELIMITER = "JSESSIONID"; private final Session session = Session.getInstance(); @Override protected HttpResponse doPost(HttpRequest httpRequest) { - String account = httpRequest.getBodyValue("account"); - String password = httpRequest.getBodyValue("password"); + String account = httpRequest.getBodyValue(ACCOUNT); + String password = httpRequest.getBodyValue(PASSWORD); User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(); @@ -35,20 +40,16 @@ protected HttpResponse doPost(HttpRequest httpRequest) { session.save(uuid.toString(), user); log.info(user.toString()); return HttpResponse.found(httpRequest) - .setCookie("JSESSIONID=" + uuid) - .location("/index.html") + .setCookie(JSESSIONID + COOKIE_DELIMITER + uuid) + .location(INDEX_PATH) .build(); } log.error("비밀번호 불일치"); return HttpResponse.found(httpRequest) - .location("/401.html") + .location(UNAUTHORIZED_PATH) .build(); } - private boolean checkToken(String[] token) { - return Arrays.stream(token).anyMatch(t -> t.split("=").length < 2); - } - @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { @@ -57,11 +58,11 @@ protected HttpResponse doGet(HttpRequest httpRequest) { } HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getHeaderValue(HttpHeaderName.COOKIE)); - if (!httpCookie.containsKey("JSESSIONID")) { + if (!httpCookie.containsCookie(JSESSIONID)) { return redirectLoginPage(httpRequest); } - String jsessionid = httpCookie.getValue("JSESSIONID"); + String jsessionid = httpCookie.getCookieValue(JSESSIONID); if (!session.containsUser(jsessionid)) { return redirectLoginPage(httpRequest); } @@ -69,8 +70,8 @@ protected HttpResponse doGet(HttpRequest httpRequest) { User user = session.getUser(jsessionid); log.info(user.toString()); return HttpResponse.found(httpRequest) - .setCookie("JSESSIONID=" + jsessionid) - .location("/index.html") + .setCookie(JSESSIONID + COOKIE_DELIMITER + jsessionid) + .location(INDEX_PATH) .build(); } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 9500cad2bb..46df31961f 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -4,7 +4,6 @@ import com.techcourse.model.User; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; @@ -14,12 +13,16 @@ public class RegisterController extends AbstractController { private static final Logger log = LoggerFactory.getLogger(RegisterController.class); private static final String REGISTER_PATH = "/register"; + private static final String ACCOUNT = "account"; + private static final String PASSWORD = "password"; + private static final String EMAIL = "email"; + private static final String INDEX_PATH = "/index.html"; @Override protected HttpResponse doPost(HttpRequest httpRequest) { - String account = httpRequest.getBodyValue("account"); - String password = httpRequest.getBodyValue("password"); - String email = httpRequest.getBodyValue("email"); + String account = httpRequest.getBodyValue(ACCOUNT); + String password = httpRequest.getBodyValue(PASSWORD); + String email = httpRequest.getBodyValue(EMAIL); if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); @@ -32,14 +35,10 @@ protected HttpResponse doPost(HttpRequest httpRequest) { InMemoryUserRepository.save(user); return HttpResponse.found(httpRequest) - .location("/index.html") + .location(INDEX_PATH) .build(); } - private boolean checkToken(String[] token) { - return Arrays.stream(token).anyMatch(t -> t.split("=").length < 2); - } - @Override protected HttpResponse doGet(HttpRequest httpRequest) { try { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java index 86335b1f89..dc98d35911 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -7,6 +7,8 @@ public class UnauthorizedController extends AbstractController { + private static final String UNAUTHORIZED_PATH = "/401.html"; + @Override protected HttpResponse doPost(HttpRequest httpRequest) { throw new IllegalArgumentException(); @@ -16,7 +18,7 @@ protected HttpResponse doPost(HttpRequest httpRequest) { protected HttpResponse doGet(HttpRequest httpRequest) { try { return HttpResponse.unauthorized(httpRequest) - .staticResource("/401.html") + .staticResource(UNAUTHORIZED_PATH) .build(); } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java index b70d778f91..c9a4c5aee9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java @@ -15,11 +15,11 @@ public void addCookie(String key, String value) { cookies.put(key, value); } - public boolean containsKey(String key) { + public boolean containsCookie(String key) { return cookies.containsKey(key); } - public String getValue(String key) { + public String getCookieValue(String key) { return cookies.get(key); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java index 468092ad82..a2fcc1aee6 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookieConvertor.java @@ -6,6 +6,9 @@ public class HttpCookieConvertor { private static final String COOKIE_DELIMITER = "; "; private static final String COOKIE_TOKEN_DELIMITER = "="; + private static final int COOKIE_TOKEN_MIN_LENGTH = 2; + private static final int COOKIE_KEY_INDEX = 0; + private static final int COOKIE_VALUE_INDEX = 1; public static HttpCookie convertHttpCookie(String rowCookie) { HttpCookie httpCookie = new HttpCookie(); @@ -13,12 +16,12 @@ public static HttpCookie convertHttpCookie(String rowCookie) { Arrays.stream(cookieTokens) .filter(HttpCookieConvertor::filterCookie) .map(cookieToken -> cookieToken.split(COOKIE_TOKEN_DELIMITER)) - .forEach(cookie -> httpCookie.addCookie(cookie[0], cookie[1])); + .forEach(cookie -> httpCookie.addCookie(cookie[COOKIE_KEY_INDEX], cookie[COOKIE_VALUE_INDEX])); return httpCookie; } private static boolean filterCookie(String cookie) { - return cookie.split(COOKIE_TOKEN_DELIMITER).length >= 2; + return cookie.split(COOKIE_TOKEN_DELIMITER).length >= COOKIE_TOKEN_MIN_LENGTH; } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index 57c5c309bf..28b95eb2a4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -5,6 +5,9 @@ public class HttpRequestLine { private static final String HEADER_DELIMITER = " "; + private static final int METHOD_INDEX = 0; + private static final int PATH_INDEX = 1; + private static final int VERSION_INDEX = 2; private final HttpMethod method; private final String path; @@ -12,9 +15,9 @@ public class HttpRequestLine { public HttpRequestLine(String requestLine) { String[] headerFirstLine = requestLine.split(HEADER_DELIMITER); - this.method = HttpMethod.getHttpMethod(headerFirstLine[0]); - this.path = headerFirstLine[1]; - this.version = headerFirstLine[2]; + this.method = HttpMethod.getHttpMethod(headerFirstLine[METHOD_INDEX]); + this.path = headerFirstLine[PATH_INDEX]; + this.version = headerFirstLine[VERSION_INDEX]; } public boolean isMethod(HttpMethod method) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index b2a5ba9108..16b5ac37b2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -14,7 +14,11 @@ public class HttpResponse { - private static final String RESPONSE_DELIMITER = "\r\n"; + private static final String RESPONSE_LINE_DELIMITER = "\r\n"; + private static final String EXTENSION_DELIMITER = "."; + private static final String HTML_EXTENSION = ".html"; + private static final String STATIC_PATH = "static"; + private final HttpStatusLine httpStatusLine; private final HttpResponseHeader httpResponseHeader; private final HttpResponseBody httpResponseBody; @@ -48,13 +52,13 @@ public byte[] getBytes() { if (httpResponseBody != null) { String responseBody = httpResponseBody.getBody(); - String join = String.join(RESPONSE_DELIMITER, + String join = String.join(RESPONSE_LINE_DELIMITER, statusLine, responseHeader, responseBody); return join.getBytes(); } - String join = String.join(RESPONSE_DELIMITER, + String join = String.join(RESPONSE_LINE_DELIMITER, statusLine, responseHeader); return join.getBytes(); @@ -103,10 +107,10 @@ public HttpResponseBuilder setCookie(String setCookie) { } public HttpResponseBuilder staticResource(String path) throws IOException, URISyntaxException { - if (!path.contains(".")) { - path += ".html"; + if (!path.contains(EXTENSION_DELIMITER)) { + path += HTML_EXTENSION; } - String fileName = "static" + path; + String fileName = STATIC_PATH + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); if (resourceUrl == null) { throw new NotFoundException("존재하지 않는 경로입니다."); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index d89c77626a..a58ffe9b37 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -6,6 +6,7 @@ public class HttpResponseHeader { private static final String HEADER_DELIMITER = ": "; + private static final String RESPONSE_LINE_DELIMITER = " \r\n"; private final Map headers; @@ -14,19 +15,24 @@ public HttpResponseHeader(Map headers) { } public String getString() { - StringBuilder sb = new StringBuilder(); + StringBuilder stringBuilder = new StringBuilder(); int size = headers.keySet().size(); int i = 1; for (HttpHeaderName key : headers.keySet()) { if (i < size) { - sb.append(key.getName()).append(HEADER_DELIMITER).append(headers.get(key)).append(" \r\n"); + stringBuilder.append(key.getName()) + .append(HEADER_DELIMITER) + .append(headers.get(key)) + .append(RESPONSE_LINE_DELIMITER); size++; } else { - sb.append(key.getName()).append(HEADER_DELIMITER).append(headers.get(key)); + stringBuilder.append(key.getName()) + .append(HEADER_DELIMITER) + .append(headers.get(key)); } } - return sb.toString(); + return stringBuilder.toString(); } public Map getHeaders() { From f75822183e8e31f7b4f960e5409daa637262b434 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 15:40:39 +0900 Subject: [PATCH 35/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/{ContentType.java => CharSet.java} | 4 +- .../apache/coyote/http11/Http11Processor.java | 7 +-- .../coyote/http11/HttpRequestConvertor.java | 9 ++-- .../http11/controller/LoginController.java | 51 ++++++++----------- .../http11/controller/RegisterController.java | 27 ++++------ .../controller/UnauthorizedController.java | 12 ++--- .../http11/httpresponse/HttpResponse.java | 38 +++++++------- .../httpresponse/HttpResponseHeader.java | 8 +-- 8 files changed, 71 insertions(+), 85 deletions(-) rename tomcat/src/main/java/org/apache/coyote/http11/{ContentType.java => CharSet.java} (77%) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http11/CharSet.java similarity index 77% rename from tomcat/src/main/java/org/apache/coyote/http11/ContentType.java rename to tomcat/src/main/java/org/apache/coyote/http11/CharSet.java index 756c70dd9d..c68ff941ae 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ContentType.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/CharSet.java @@ -1,13 +1,13 @@ package org.apache.coyote.http11; -public enum ContentType { +public enum CharSet { UTF_8(";charset=utf-8") ; private final String charset; - ContentType(String charset) { + CharSet(String charset) { this.charset = charset; } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 96bd7ac067..8400f3153a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -46,12 +46,12 @@ public void process(final Socket connection) { outputStream.write(httpResponse.getBytes()); outputStream.flush(); - } catch (IOException | UncheckedServletException e) { + } catch (IOException | UncheckedServletException | URISyntaxException e) { log.error(e.getMessage(), e); } } - private HttpResponse getHttpResponse(HttpRequest httpRequest) { + private HttpResponse getHttpResponse(HttpRequest httpRequest) throws IOException, URISyntaxException { try { if (isStaticResource(httpRequest)) { return HttpResponse.ok(httpRequest) @@ -59,7 +59,6 @@ private HttpResponse getHttpResponse(HttpRequest httpRequest) { .build(); } RequestMapping requestMapping = new RequestMapping(); - Controller controller = requestMapping.getController(httpRequest); return controller.service(httpRequest); @@ -67,8 +66,6 @@ private HttpResponse getHttpResponse(HttpRequest httpRequest) { return HttpResponse.found(httpRequest) .location(NOT_FOUND_PATH) .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 99aa8dfbb1..1da2ee24ac 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -32,9 +32,7 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro Map headers = getHeaders(bufferedReader); HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); - if (httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) - && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals(BODY_FORM_CONTENT_TYPE) - ) { + if (isExistRequestBody(httpRequestHeader)) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); } @@ -84,4 +82,9 @@ private static Map extractBody(String requestBody) { token -> token[TUPLE_VALUE_INDEX] )); } + + private static boolean isExistRequestBody(HttpRequestHeader httpRequestHeader) { + return httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) + && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals(BODY_FORM_CONTENT_TYPE); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 8e84157927..e19ba31822 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -2,8 +2,6 @@ import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; -import java.io.IOException; -import java.net.URISyntaxException; import java.util.UUID; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.Session; @@ -45,42 +43,37 @@ protected HttpResponse doPost(HttpRequest httpRequest) { .build(); } log.error("비밀번호 불일치"); - return HttpResponse.found(httpRequest) - .location(UNAUTHORIZED_PATH) - .build(); + return redirectPage(httpRequest, UNAUTHORIZED_PATH); } @Override protected HttpResponse doGet(HttpRequest httpRequest) { - try { - if (!httpRequest.containsHeader(HttpHeaderName.COOKIE)) { - return redirectLoginPage(httpRequest); - } - - HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(httpRequest.getHeaderValue(HttpHeaderName.COOKIE)); - if (!httpCookie.containsCookie(JSESSIONID)) { - return redirectLoginPage(httpRequest); - } + if (!httpRequest.containsHeader(HttpHeaderName.COOKIE)) { + return redirectPage(httpRequest, LOGIN_PATH); + } - String jsessionid = httpCookie.getCookieValue(JSESSIONID); - if (!session.containsUser(jsessionid)) { - return redirectLoginPage(httpRequest); - } + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie( + httpRequest.getHeaderValue(HttpHeaderName.COOKIE)); + if (!httpCookie.containsCookie(JSESSIONID)) { + return redirectPage(httpRequest, LOGIN_PATH); + } - User user = session.getUser(jsessionid); - log.info(user.toString()); - return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + jsessionid) - .location(INDEX_PATH) - .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); + String jsessionid = httpCookie.getCookieValue(JSESSIONID); + if (!session.containsUser(jsessionid)) { + return redirectPage(httpRequest,LOGIN_PATH); } + + User user = session.getUser(jsessionid); + log.info(user.toString()); + return HttpResponse.found(httpRequest) + .setCookie(JSESSIONID + COOKIE_DELIMITER + jsessionid) + .location(INDEX_PATH) + .build(); } - private HttpResponse redirectLoginPage(HttpRequest httpRequest) throws IOException, URISyntaxException { - return HttpResponse.ok(httpRequest) - .staticResource(LOGIN_PATH) + private HttpResponse redirectPage(HttpRequest httpRequest, String path) { + return HttpResponse.found(httpRequest) + .location(path) .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 46df31961f..1cc41e43fc 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -2,8 +2,6 @@ import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; -import java.io.IOException; -import java.net.URISyntaxException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; @@ -26,27 +24,24 @@ protected HttpResponse doPost(HttpRequest httpRequest) { if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); - return HttpResponse.found(httpRequest) - .location(REGISTER_PATH) - .build(); + return redirectPage(httpRequest, REGISTER_PATH); } User user = new User(account, password, email); InMemoryUserRepository.save(user); - - return HttpResponse.found(httpRequest) - .location(INDEX_PATH) - .build(); + return redirectPage(httpRequest, INDEX_PATH); } @Override protected HttpResponse doGet(HttpRequest httpRequest) { - try { - return HttpResponse.ok(httpRequest) - .staticResource(httpRequest.getPath()) - .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); - } + return HttpResponse.ok(httpRequest) + .staticResource(httpRequest.getPath()) + .build(); + } + + private HttpResponse redirectPage(HttpRequest httpRequest, String path) { + return HttpResponse.found(httpRequest) + .location(path) + .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java index dc98d35911..6d56968db1 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java @@ -1,7 +1,5 @@ package org.apache.coyote.http11.controller; -import java.io.IOException; -import java.net.URISyntaxException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -16,12 +14,8 @@ protected HttpResponse doPost(HttpRequest httpRequest) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { - try { - return HttpResponse.unauthorized(httpRequest) - .staticResource(UNAUTHORIZED_PATH) - .build(); - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e); - } + return HttpResponse.unauthorized(httpRequest) + .staticResource(UNAUTHORIZED_PATH) + .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 16b5ac37b2..2c7a8ad501 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -6,7 +6,7 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import org.apache.coyote.http11.ContentType; +import org.apache.coyote.http11.CharSet; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.exception.NotFoundException; @@ -106,23 +106,27 @@ public HttpResponseBuilder setCookie(String setCookie) { return this; } - public HttpResponseBuilder staticResource(String path) throws IOException, URISyntaxException { - if (!path.contains(EXTENSION_DELIMITER)) { - path += HTML_EXTENSION; + public HttpResponseBuilder staticResource(String path) { + try { + if (!path.contains(EXTENSION_DELIMITER)) { + path += HTML_EXTENSION; + } + String fileName = STATIC_PATH + path; + var resourceUrl = getClass().getClassLoader().getResource(fileName); + if (resourceUrl == null) { + throw new NotFoundException("존재하지 않는 경로입니다."); + } + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + contentType(Files.probeContentType(filePath) + CharSet.UTF_8.getCharset()); + contentLength(String.valueOf(responseBody.getBytes().length)); + this.httpResponseBody = new HttpResponseBody(responseBody); + + return this; + } catch (URISyntaxException | IOException e) { + throw new IllegalArgumentException(e.getMessage() + e); } - String fileName = STATIC_PATH + path; - var resourceUrl = getClass().getClassLoader().getResource(fileName); - if (resourceUrl == null) { - throw new NotFoundException("존재하지 않는 경로입니다."); - } - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - contentType(Files.probeContentType(filePath) + ContentType.UTF_8.getCharset()); - contentLength(String.valueOf(responseBody.getBytes().length)); - this.httpResponseBody = new HttpResponseBody(responseBody); - - return this; } public HttpResponseBuilder responseBody(String responseBody) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index a58ffe9b37..3950d6f20b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -25,11 +25,11 @@ public String getString() { .append(headers.get(key)) .append(RESPONSE_LINE_DELIMITER); size++; - } else { - stringBuilder.append(key.getName()) - .append(HEADER_DELIMITER) - .append(headers.get(key)); + continue; } + stringBuilder.append(key.getName()) + .append(HEADER_DELIMITER) + .append(headers.get(key)); } return stringBuilder.toString(); From 581fdcfdd75a853d9ce528b2be267c9a681b8d61 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 18:56:00 +0900 Subject: [PATCH 36/73] =?UTF-8?q?refactor:=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/controller/LoginController.java | 8 ++++++++ .../coyote/http11/controller/RegisterController.java | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index e19ba31822..8cbf8517a0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -27,6 +27,10 @@ public class LoginController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { + if (validateUserInput(httpRequest)) { + log.error("입력하지 않은 항목이 있습니다."); + return redirectPage(httpRequest, LOGIN_PATH); + } String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); @@ -46,6 +50,10 @@ protected HttpResponse doPost(HttpRequest httpRequest) { return redirectPage(httpRequest, UNAUTHORIZED_PATH); } + private boolean validateUserInput(HttpRequest httpRequest) { + return !httpRequest.containsBody(ACCOUNT) || !httpRequest.containsBody(PASSWORD); + } + @Override protected HttpResponse doGet(HttpRequest httpRequest) { if (!httpRequest.containsHeader(HttpHeaderName.COOKIE)) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 1cc41e43fc..02dda4b914 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -18,6 +18,10 @@ public class RegisterController extends AbstractController { @Override protected HttpResponse doPost(HttpRequest httpRequest) { + if (validateUserInput(httpRequest)) { + log.error("입력하지 않은 항목이 있습니다."); + return redirectPage(httpRequest, REGISTER_PATH); + } String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); String email = httpRequest.getBodyValue(EMAIL); @@ -32,6 +36,12 @@ protected HttpResponse doPost(HttpRequest httpRequest) { return redirectPage(httpRequest, INDEX_PATH); } + private boolean validateUserInput(HttpRequest httpRequest) { + return !httpRequest.containsBody(ACCOUNT) + || !httpRequest.containsBody(PASSWORD) + || !httpRequest.containsBody(EMAIL); + } + @Override protected HttpResponse doGet(HttpRequest httpRequest) { return HttpResponse.ok(httpRequest) From e854bc8c70492ea503cdc27f66586f10cc83c6e9 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 20:36:23 +0900 Subject: [PATCH 37/73] =?UTF-8?q?refactor:=20session=EC=9D=84=20=EB=8B=A4?= =?UTF-8?q?=EB=A3=A8=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/catalina/Manager.java | 9 ++--- .../coyote/http11/HttpRequestConvertor.java | 34 ++++++++++++++++- .../org/apache/coyote/http11/Session.java | 31 +++++++-------- .../apache/coyote/http11/SessionManager.java | 29 ++++++++++++++ .../http11/controller/LoginController.java | 38 ++++++------------- .../http11/httprequest/HttpRequest.java | 20 ++++++++-- 6 files changed, 106 insertions(+), 55 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java diff --git a/tomcat/src/main/java/org/apache/catalina/Manager.java b/tomcat/src/main/java/org/apache/catalina/Manager.java index e69410f6a9..83f7a16cca 100644 --- a/tomcat/src/main/java/org/apache/catalina/Manager.java +++ b/tomcat/src/main/java/org/apache/catalina/Manager.java @@ -1,8 +1,7 @@ package org.apache.catalina; -import jakarta.servlet.http.HttpSession; - import java.io.IOException; +import org.apache.coyote.http11.Session; /** * A Manager manages the pool of Sessions that are associated with a @@ -29,7 +28,7 @@ public interface Manager { * * @param session Session to be added */ - void add(HttpSession session); + void add(Session session); /** * Return the active Session, associated with this Manager, with the @@ -45,12 +44,12 @@ public interface Manager { * @return the request session or {@code null} if a session with the * requested ID could not be found */ - HttpSession findSession(String id) throws IOException; + Session findSession(String id) throws IOException; /** * Remove this Session from the active Sessions for this Manager. * * @param session Session to be removed */ - void remove(HttpSession session); + void remove(Session session); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 1da2ee24ac..1e708d4f78 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -5,7 +5,10 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import java.util.stream.Collectors; +import org.apache.coyote.http11.httprequest.HttpCookie; +import org.apache.coyote.http11.httprequest.HttpCookieConvertor; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httprequest.HttpRequestBody; import org.apache.coyote.http11.httprequest.HttpRequestHeader; @@ -13,6 +16,7 @@ public class HttpRequestConvertor { + private static final String JSESSIONID = "JSESSIONID"; private static final String HEADER_DELIMITER = ":"; private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; private static final String BODY_DELIMITER = "&"; @@ -21,6 +25,7 @@ public class HttpRequestConvertor { private static final int TUPLE_KEY_INDEX = 0; private static final int TUPLE_VALUE_INDEX = 1; private static final int HEADER_KEY_INDEX = 0; + private static final SessionManager SESSION_MANAGER = new SessionManager(); public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); @@ -31,13 +36,14 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); Map headers = getHeaders(bufferedReader); HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); + Session session = getOrCreateSession(httpRequestHeader); if (isExistRequestBody(httpRequestHeader)) { HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); - return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody); + return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody, session); } - return new HttpRequest(httpRequestLine, httpRequestHeader); + return new HttpRequest(httpRequestLine, httpRequestHeader, session); } private static Map getHeaders(BufferedReader bufferedReader) throws IOException { @@ -60,6 +66,30 @@ private static String parseHeaderValue(String[] requestLine) { return sb.toString(); } + private static Session getOrCreateSession(HttpRequestHeader httpRequestHeader) { + if (!httpRequestHeader.containsHeader(HttpHeaderName.COOKIE)) { + return createSession(); + } + + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie( + httpRequestHeader.getHeaderValue(HttpHeaderName.COOKIE)); + if (!httpCookie.containsCookie(JSESSIONID)) { + return createSession(); + } + + String jsessionid = httpCookie.getCookieValue(JSESSIONID); + if (!SESSION_MANAGER.containsSession(jsessionid)) { + return createSession(); + } + return SESSION_MANAGER.findSession(jsessionid); + } + + private static Session createSession() { + Session session = new Session(UUID.randomUUID().toString()); + SESSION_MANAGER.add(session); + return session; + } + private static HttpRequestBody getHttpRequestBody( BufferedReader bufferedReader, HttpRequestHeader httpRequestHeader diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Session.java b/tomcat/src/main/java/org/apache/coyote/http11/Session.java index 424b9cf6f9..a66260b433 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Session.java @@ -1,36 +1,31 @@ package org.apache.coyote.http11; -import com.techcourse.model.User; import java.util.HashMap; import java.util.Map; -import java.util.Set; public class Session { - private static final Session INSTANCE = new Session(); - private final Map userMap; + private final String id; + private final Map attributes; - private Session() { - this.userMap = new HashMap<>(); + public Session(String id) { + this.id = id; + this.attributes = new HashMap<>(); } - public static Session getInstance() { - return INSTANCE; + public boolean hasAttribute(String name) { + return attributes.containsKey(name); } - public void save(String uuid, User user) { - userMap.put(uuid, user); + public Object getAttribute(String name) { + return attributes.get(name); } - public boolean containsUser(String uuid) { - return userMap.containsKey(uuid); + public void setAttribute(String name, Object value) { + attributes.put(name, value); } - public User getUser(String uuid) { - return userMap.get(uuid); - } - - public Set getKeySet() { - return userMap.keySet(); + public String getId() { + return id; } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java new file mode 100644 index 0000000000..5d9f97a8c5 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java @@ -0,0 +1,29 @@ +package org.apache.coyote.http11; + +import java.util.HashMap; +import java.util.Map; +import org.apache.catalina.Manager; + +public class SessionManager implements Manager { + + private static final Map SESSIONS = new HashMap<>(); + + @Override + public void add(Session session) { + SESSIONS.put(session.getId(), session); + } + + @Override + public Session findSession(String id) { + return SESSIONS.get(id); + } + + @Override + public void remove(Session session) { + SESSIONS.remove(session.getId()); + } + + public boolean containsSession(String id) { + return SESSIONS.containsKey(id); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 8cbf8517a0..814435dc3f 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -2,11 +2,7 @@ import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; -import java.util.UUID; -import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.Session; -import org.apache.coyote.http11.httprequest.HttpCookie; -import org.apache.coyote.http11.httprequest.HttpCookieConvertor; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; @@ -21,9 +17,8 @@ public class LoginController extends AbstractController { private static final String INDEX_PATH = "/index.html"; private static final String UNAUTHORIZED_PATH = "/401.html"; private static final String JSESSIONID = "JSESSIONID"; - private static final String COOKIE_DELIMITER = "JSESSIONID"; - - private final Session session = Session.getInstance(); + private static final String COOKIE_DELIMITER = "="; + private static final String SESSION_USER_NAME = "user"; @Override protected HttpResponse doPost(HttpRequest httpRequest) { @@ -36,13 +31,13 @@ protected HttpResponse doPost(HttpRequest httpRequest) { User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(); - UUID uuid = UUID.randomUUID(); if (user.checkPassword(password)) { - session.save(uuid.toString(), user); + Session session = httpRequest.getSession(); + session.setAttribute(SESSION_USER_NAME, user); log.info(user.toString()); return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + uuid) + .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) .location(INDEX_PATH) .build(); } @@ -56,25 +51,16 @@ private boolean validateUserInput(HttpRequest httpRequest) { @Override protected HttpResponse doGet(HttpRequest httpRequest) { - if (!httpRequest.containsHeader(HttpHeaderName.COOKIE)) { - return redirectPage(httpRequest, LOGIN_PATH); - } - - HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie( - httpRequest.getHeaderValue(HttpHeaderName.COOKIE)); - if (!httpCookie.containsCookie(JSESSIONID)) { - return redirectPage(httpRequest, LOGIN_PATH); - } - - String jsessionid = httpCookie.getCookieValue(JSESSIONID); - if (!session.containsUser(jsessionid)) { - return redirectPage(httpRequest,LOGIN_PATH); + Session session = httpRequest.getSession(); + if (!session.hasAttribute(SESSION_USER_NAME)) { + return HttpResponse.ok(httpRequest) + .staticResource(LOGIN_PATH) + .build(); } - - User user = session.getUser(jsessionid); + User user = (User) session.getAttribute(SESSION_USER_NAME); log.info(user.toString()); return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + jsessionid) + .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) .location(INDEX_PATH) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index 52b1aa69fa..d5e9a4c146 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -3,21 +3,29 @@ import java.util.Map; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpMethod; +import org.apache.coyote.http11.Session; public class HttpRequest { private final HttpRequestLine httpRequestLine; private final HttpRequestHeader httpRequestHeader; private final HttpRequestBody httpRequestBody; - - public HttpRequest(HttpRequestLine httpRequestLine, HttpRequestHeader httpRequestHeader, HttpRequestBody httpRequestBody) { + private final Session session; + + public HttpRequest( + HttpRequestLine httpRequestLine, + HttpRequestHeader httpRequestHeader, + HttpRequestBody httpRequestBody, + Session session + ) { this.httpRequestLine = httpRequestLine; this.httpRequestHeader = httpRequestHeader; this.httpRequestBody = httpRequestBody; + this.session = session; } - public HttpRequest(HttpRequestLine httpRequestLine, HttpRequestHeader httpRequestHeader) { - this(httpRequestLine, httpRequestHeader, null); + public HttpRequest(HttpRequestLine httpRequestLine, HttpRequestHeader httpRequestHeader, Session session) { + this(httpRequestLine, httpRequestHeader, null, session); } public boolean isMethod(HttpMethod method) { @@ -75,4 +83,8 @@ public HttpRequestHeader getHttpRequestHeader() { public HttpRequestBody getHttpRequestBody() { return httpRequestBody; } + + public Session getSession() { + return session; + } } From 5e51288210aa03547b0f77cdce80ec7a551983d1 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 20:43:48 +0900 Subject: [PATCH 38/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/controller/LoginController.java | 27 ++++++++++++------- .../http11/controller/RegisterController.java | 4 +++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java index 814435dc3f..69c2bfc7c7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java @@ -26,27 +26,34 @@ protected HttpResponse doPost(HttpRequest httpRequest) { log.error("입력하지 않은 항목이 있습니다."); return redirectPage(httpRequest, LOGIN_PATH); } + return acceptLogin(httpRequest); + } + + private boolean validateUserInput(HttpRequest httpRequest) { + return !httpRequest.containsBody(ACCOUNT) || !httpRequest.containsBody(PASSWORD); + } + + private HttpResponse acceptLogin(HttpRequest httpRequest) { String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(); - if (user.checkPassword(password)) { - Session session = httpRequest.getSession(); - session.setAttribute(SESSION_USER_NAME, user); - log.info(user.toString()); - return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) - .location(INDEX_PATH) - .build(); + return redirectWithCookie(httpRequest, user); } log.error("비밀번호 불일치"); return redirectPage(httpRequest, UNAUTHORIZED_PATH); } - private boolean validateUserInput(HttpRequest httpRequest) { - return !httpRequest.containsBody(ACCOUNT) || !httpRequest.containsBody(PASSWORD); + private static HttpResponse redirectWithCookie(HttpRequest httpRequest, User user) { + Session session = httpRequest.getSession(); + session.setAttribute(SESSION_USER_NAME, user); + log.info(user.toString()); + return HttpResponse.found(httpRequest) + .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) + .location(INDEX_PATH) + .build(); } @Override diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java index 02dda4b914..3b892f9021 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java @@ -22,6 +22,10 @@ protected HttpResponse doPost(HttpRequest httpRequest) { log.error("입력하지 않은 항목이 있습니다."); return redirectPage(httpRequest, REGISTER_PATH); } + return acceptRegister(httpRequest); + } + + private HttpResponse acceptRegister(HttpRequest httpRequest) { String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); String email = httpRequest.getBodyValue(EMAIL); From f933ab492bd08d8cb6549e6f1bf498c06a654b1b Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:01:19 +0900 Subject: [PATCH 39/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/HttpRequestConvertor.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java index 1e708d4f78..cee87a8117 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java @@ -29,13 +29,10 @@ public class HttpRequestConvertor { public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); - if (requestLine == null) { - throw new IllegalArgumentException("요청이 비어 있습니다."); - } - + validateRequestLine(requestLine); HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); - Map headers = getHeaders(bufferedReader); - HttpRequestHeader httpRequestHeader = new HttpRequestHeader(headers); + + HttpRequestHeader httpRequestHeader = new HttpRequestHeader(getHeaders(bufferedReader)); Session session = getOrCreateSession(httpRequestHeader); if (isExistRequestBody(httpRequestHeader)) { @@ -46,6 +43,12 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro return new HttpRequest(httpRequestLine, httpRequestHeader, session); } + private static void validateRequestLine(String requestLine) { + if (requestLine == null) { + throw new IllegalArgumentException("요청이 비어 있습니다."); + } + } + private static Map getHeaders(BufferedReader bufferedReader) throws IOException { String line; Map headers = new HashMap<>(); @@ -77,6 +80,10 @@ private static Session getOrCreateSession(HttpRequestHeader httpRequestHeader) { return createSession(); } + return getOrCreateSession(httpCookie); + } + + private static Session getOrCreateSession(HttpCookie httpCookie) { String jsessionid = httpCookie.getCookieValue(JSESSIONID); if (!SESSION_MANAGER.containsSession(jsessionid)) { return createSession(); From a7205eaf63fd4bdb8268fb97e682c34c62edb982 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:02:42 +0900 Subject: [PATCH 40/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/config/UnauthorizedInterceptor.java | 2 +- .../org/apache/coyote/http11/controller/RequestMapping.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java index a066d72609..6a32b11c54 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java @@ -18,7 +18,7 @@ public UnauthorizedInterceptor() { unauthorizedPaths.add("/500.html"); } - public boolean checkPath(HttpRequest httpRequest) { + public boolean isInterceptPath(HttpRequest httpRequest) { return !httpRequest.containsHeader(HttpHeaderName.LOCATION) && unauthorizedPaths.contains(httpRequest.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java index 1b1a4e3162..6e3976f4ff 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java @@ -18,7 +18,7 @@ public RequestMapping() { } public Controller getController(HttpRequest httpRequest) { - if (unauthorizedInterceptor.checkPath(httpRequest)) { + if (unauthorizedInterceptor.isInterceptPath(httpRequest)) { return new UnauthorizedController(); } From 36040893bf94172a707650195a0037145e2bbfda Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:04:48 +0900 Subject: [PATCH 41/73] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../techcourse}/config/UnauthorizedInterceptor.java | 2 +- .../techcourse}/controller/AbstractController.java | 2 +- .../techcourse}/controller/Controller.java | 2 +- .../techcourse}/controller/LoginController.java | 4 ++-- .../techcourse}/controller/RegisterController.java | 2 +- .../techcourse}/controller/RequestMapping.java | 4 ++-- .../controller/UnauthorizedController.java | 2 +- tomcat/src/main/java/org/apache/catalina/Manager.java | 2 +- .../org/apache/coyote/http11/Http11Processor.java | 5 +++-- .../apache/coyote/http11/httprequest/HttpRequest.java | 2 +- .../{ => httprequest}/HttpRequestConvertor.java | 11 ++++------- .../apache/coyote/http11/{ => session}/Session.java | 2 +- .../coyote/http11/{ => session}/SessionManager.java | 2 +- 13 files changed, 20 insertions(+), 22 deletions(-) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/config/UnauthorizedInterceptor.java (94%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/AbstractController.java (94%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/Controller.java (81%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/LoginController.java (97%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/RegisterController.java (98%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/RequestMapping.java (90%) rename tomcat/src/main/java/{org/apache/coyote/http11 => com/techcourse}/controller/UnauthorizedController.java (92%) rename tomcat/src/main/java/org/apache/coyote/http11/{ => httprequest}/HttpRequestConvertor.java (92%) rename tomcat/src/main/java/org/apache/coyote/http11/{ => session}/Session.java (93%) rename tomcat/src/main/java/org/apache/coyote/http11/{ => session}/SessionManager.java (93%) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java similarity index 94% rename from tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java rename to tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java index 6a32b11c54..198183d080 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11.config; +package com.techcourse.config; import java.util.HashSet; import java.util.Set; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java b/tomcat/src/main/java/com/techcourse/controller/AbstractController.java similarity index 94% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java rename to tomcat/src/main/java/com/techcourse/controller/AbstractController.java index 9ef89b1514..0d396ac0c9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/AbstractController.java +++ b/tomcat/src/main/java/com/techcourse/controller/AbstractController.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import org.apache.coyote.http11.HttpMethod; import org.apache.coyote.http11.httprequest.HttpRequest; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/Controller.java b/tomcat/src/main/java/com/techcourse/controller/Controller.java similarity index 81% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/Controller.java rename to tomcat/src/main/java/com/techcourse/controller/Controller.java index 3f2f18697a..b8ae035206 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/Controller.java +++ b/tomcat/src/main/java/com/techcourse/controller/Controller.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java similarity index 97% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java rename to tomcat/src/main/java/com/techcourse/controller/LoginController.java index 69c2bfc7c7..6534c66e6d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -1,8 +1,8 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; -import org.apache.coyote.http11.Session; +import org.apache.coyote.http11.session.Session; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java similarity index 98% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java rename to tomcat/src/main/java/com/techcourse/controller/RegisterController.java index 3b892f9021..24e91043f2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RegisterController.java +++ b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java similarity index 90% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java rename to tomcat/src/main/java/com/techcourse/controller/RequestMapping.java index 6e3976f4ff..597bb8fc7b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/RequestMapping.java +++ b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java @@ -1,8 +1,8 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import java.util.HashMap; import java.util.Map; -import org.apache.coyote.http11.config.UnauthorizedInterceptor; +import com.techcourse.config.UnauthorizedInterceptor; import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.httprequest.HttpRequest; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java b/tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java similarity index 92% rename from tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java rename to tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java index 6d56968db1..5fc9d9d845 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/controller/UnauthorizedController.java +++ b/tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11.controller; +package com.techcourse.controller; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; diff --git a/tomcat/src/main/java/org/apache/catalina/Manager.java b/tomcat/src/main/java/org/apache/catalina/Manager.java index 83f7a16cca..c07f2c5405 100644 --- a/tomcat/src/main/java/org/apache/catalina/Manager.java +++ b/tomcat/src/main/java/org/apache/catalina/Manager.java @@ -1,7 +1,7 @@ package org.apache.catalina; import java.io.IOException; -import org.apache.coyote.http11.Session; +import org.apache.coyote.http11.session.Session; /** * A Manager manages the pool of Sessions that are associated with a diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 8400f3153a..906a2a0b57 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -7,10 +7,11 @@ import java.net.Socket; import java.net.URISyntaxException; import org.apache.coyote.Processor; -import org.apache.coyote.http11.controller.Controller; -import org.apache.coyote.http11.controller.RequestMapping; +import com.techcourse.controller.Controller; +import com.techcourse.controller.RequestMapping; import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index d5e9a4c146..09b55d63a0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -3,7 +3,7 @@ import java.util.Map; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpMethod; -import org.apache.coyote.http11.Session; +import org.apache.coyote.http11.session.Session; public class HttpRequest { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java similarity index 92% rename from tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java rename to tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index cee87a8117..73ab3c087d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.httprequest; import java.io.BufferedReader; import java.io.IOException; @@ -7,12 +7,9 @@ import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; -import org.apache.coyote.http11.httprequest.HttpCookie; -import org.apache.coyote.http11.httprequest.HttpCookieConvertor; -import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httprequest.HttpRequestBody; -import org.apache.coyote.http11.httprequest.HttpRequestHeader; -import org.apache.coyote.http11.httprequest.HttpRequestLine; +import org.apache.coyote.http11.HttpHeaderName; +import org.apache.coyote.http11.session.Session; +import org.apache.coyote.http11.session.SessionManager; public class HttpRequestConvertor { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Session.java b/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java similarity index 93% rename from tomcat/src/main/java/org/apache/coyote/http11/Session.java rename to tomcat/src/main/java/org/apache/coyote/http11/session/Session.java index a66260b433..41d670a193 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.session; import java.util.HashMap; import java.util.Map; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java similarity index 93% rename from tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java rename to tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java index 5d9f97a8c5..41d7ea3068 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java @@ -1,4 +1,4 @@ -package org.apache.coyote.http11; +package org.apache.coyote.http11.session; import java.util.HashMap; import java.util.Map; From a47cab2617eb2969715a6424579a936f475ef17e Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:10:50 +0900 Subject: [PATCH 42/73] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/techcourse/controller/LoginController.java | 3 ++- tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index 6534c66e6d..3e0e3ad668 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -2,6 +2,7 @@ import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; +import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.session.Session; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -38,7 +39,7 @@ private HttpResponse acceptLogin(HttpRequest httpRequest) { String password = httpRequest.getBodyValue(PASSWORD); User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(); + .orElseThrow(() -> new NotFoundException("존재하지 않는 계정입니다")); if (user.checkPassword(password)) { return redirectWithCookie(httpRequest, user); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java index 12676b3e71..5535bfdcb1 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpMethod.java @@ -1,6 +1,7 @@ package org.apache.coyote.http11; import java.util.Arrays; +import org.apache.coyote.http11.exception.NotFoundException; public enum HttpMethod { @@ -12,7 +13,7 @@ public static HttpMethod getHttpMethod(String name) { return Arrays.stream(values()) .filter(httpMethod -> httpMethod.name().equals(name)) .findAny() - .orElseThrow(); + .orElseThrow(() -> new NotFoundException("유효하지 않은 메소드 입니다.")); } public boolean isMethod(HttpMethod method) { From d64f3b6963a42c607d8a5f75114fdb2e5344b1a7 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:26:11 +0900 Subject: [PATCH 43/73] =?UTF-8?q?refactor:=20HttpMethodTest=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/HttpMethodTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tomcat/src/test/java/org/apache/coyote/http11/HttpMethodTest.java diff --git a/tomcat/src/test/java/org/apache/coyote/http11/HttpMethodTest.java b/tomcat/src/test/java/org/apache/coyote/http11/HttpMethodTest.java new file mode 100644 index 0000000000..ddb8a3fee8 --- /dev/null +++ b/tomcat/src/test/java/org/apache/coyote/http11/HttpMethodTest.java @@ -0,0 +1,40 @@ +package org.apache.coyote.http11; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.apache.coyote.http11.exception.NotFoundException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class HttpMethodTest { + + @DisplayName("이름과 일치하는 HttpMethod를 반환한다") + @Test + void getHttpMethod() { + HttpMethod method = HttpMethod.getHttpMethod("GET"); + + HttpMethod expected = HttpMethod.GET; + + assertThat(method).isEqualTo(expected); + } + + @DisplayName("해당하는 HttpMethod가 없을 경우 예외를 발생시킨다") + @Test + void notExistHttpMethod() { + assertThatThrownBy(() -> HttpMethod.getHttpMethod("G")) + .isInstanceOf(NotFoundException.class); + } + + @DisplayName("해당 HttpMethod와 일치 여부를 반환한다.") + @Test + void isMethod() { + HttpMethod method = HttpMethod.GET; + + assertAll( + () -> assertThat(method.isMethod(HttpMethod.GET)).isTrue(), + () -> assertThat(method.isMethod(HttpMethod.POST)).isFalse() + ); + } +} From 2baf5a69f5d35614518d2974cd25d2031f594fa4 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:30:10 +0900 Subject: [PATCH 44/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/httpresponse/HttpResponse.java | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 2c7a8ad501..044c6792ac 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.net.URISyntaxException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -108,27 +109,39 @@ public HttpResponseBuilder setCookie(String setCookie) { public HttpResponseBuilder staticResource(String path) { try { - if (!path.contains(EXTENSION_DELIMITER)) { - path += HTML_EXTENSION; - } + path = settingExtension(path); String fileName = STATIC_PATH + path; var resourceUrl = getClass().getClassLoader().getResource(fileName); - if (resourceUrl == null) { - throw new NotFoundException("존재하지 않는 경로입니다."); - } + validateResourceUrl(resourceUrl); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); - contentType(Files.probeContentType(filePath) + CharSet.UTF_8.getCharset()); - contentLength(String.valueOf(responseBody.getBytes().length)); + setHttpHeader(filePath, responseBody); this.httpResponseBody = new HttpResponseBody(responseBody); - return this; } catch (URISyntaxException | IOException e) { throw new IllegalArgumentException(e.getMessage() + e); } } + private static String settingExtension(String path) { + if (!path.contains(EXTENSION_DELIMITER)) { + path += HTML_EXTENSION; + } + return path; + } + + private static void validateResourceUrl(URL resourceUrl) { + if (resourceUrl == null) { + throw new NotFoundException("존재하지 않는 경로입니다."); + } + } + + private void setHttpHeader(Path filePath, String responseBody) throws IOException { + contentType(Files.probeContentType(filePath) + CharSet.UTF_8.getCharset()); + contentLength(String.valueOf(responseBody.getBytes().length)); + } + public HttpResponseBuilder responseBody(String responseBody) { this.httpResponseBody = new HttpResponseBody(responseBody); return this; From e1fbb9f1a0b44f58b60be4a89e52dd0247e08311 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:38:21 +0900 Subject: [PATCH 45/73] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/techcourse/config/UnauthorizedInterceptor.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java index 198183d080..55060a3046 100644 --- a/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java +++ b/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java @@ -1,21 +1,15 @@ package com.techcourse.config; -import java.util.HashSet; import java.util.Set; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.httprequest.HttpRequest; public class UnauthorizedInterceptor { - private final Set unauthorizedPaths = new HashSet<>(); + private final Set unauthorizedPaths; public UnauthorizedInterceptor() { - unauthorizedPaths.add("/401"); - unauthorizedPaths.add("/404"); - unauthorizedPaths.add("/500"); - unauthorizedPaths.add("/401.html"); - unauthorizedPaths.add("/404.html"); - unauthorizedPaths.add("/500.html"); + unauthorizedPaths = Set.of("/401", "/404", "/500", "/401.html", "/404.html", "/500.html"); } public boolean isInterceptPath(HttpRequest httpRequest) { From f3255e99f6af4160e6265f6d15ea322a31681dd6 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Wed, 11 Sep 2024 21:49:46 +0900 Subject: [PATCH 46/73] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=83=81=ED=99=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/httprequest/HttpRequestConvertor.java | 4 ++++ .../org/apache/coyote/http11/httprequest/HttpRequestLine.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 73ab3c087d..258b907fcc 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -23,6 +23,7 @@ public class HttpRequestConvertor { private static final int TUPLE_VALUE_INDEX = 1; private static final int HEADER_KEY_INDEX = 0; private static final SessionManager SESSION_MANAGER = new SessionManager(); + private static final String REQUEST_LINE_DELIMITER = " "; public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); @@ -44,6 +45,9 @@ private static void validateRequestLine(String requestLine) { if (requestLine == null) { throw new IllegalArgumentException("요청이 비어 있습니다."); } + if (requestLine.split(REQUEST_LINE_DELIMITER).length < 3) { + throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다."); + } } private static Map getHeaders(BufferedReader bufferedReader) throws IOException { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index 28b95eb2a4..46d1b7d053 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -4,7 +4,7 @@ public class HttpRequestLine { - private static final String HEADER_DELIMITER = " "; + private static final String REQUEST_LINE_DELIMITER = " "; private static final int METHOD_INDEX = 0; private static final int PATH_INDEX = 1; private static final int VERSION_INDEX = 2; @@ -14,7 +14,7 @@ public class HttpRequestLine { private final String version; public HttpRequestLine(String requestLine) { - String[] headerFirstLine = requestLine.split(HEADER_DELIMITER); + String[] headerFirstLine = requestLine.split(REQUEST_LINE_DELIMITER); this.method = HttpMethod.getHttpMethod(headerFirstLine[METHOD_INDEX]); this.path = headerFirstLine[PATH_INDEX]; this.version = headerFirstLine[VERSION_INDEX]; From 5b53b772d43c99819be0af48cc5b9f30b354b5ab Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 13:05:38 +0900 Subject: [PATCH 47/73] =?UTF-8?q?test:=20RequestMappingTest,=20RegisterCon?= =?UTF-8?q?trollerTest=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginController.java | 9 +- .../techcourse/controller/RequestMapping.java | 3 +- .../controller/UnauthorizedController.java | 21 ---- .../apache/coyote/http11/Http11Processor.java | 6 + .../exception/UnauthorizedException.java | 8 ++ .../httprequest/HttpRequestConvertor.java | 1 + .../http11/httpresponse/HttpResponse.java | 2 + .../http11/httpresponse/HttpStatusLine.java | 7 +- .../config/UnauthorizedInterceptorTest.java | 50 ++++++++ .../controller/RegisterControllerTest.java | 116 ++++++++++++++++++ .../controller/RequestMappingTest.java | 74 +++++++++++ .../coyote/http11/Http11ProcessorTest.java | 22 +--- 12 files changed, 265 insertions(+), 54 deletions(-) delete mode 100644 tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/exception/UnauthorizedException.java create mode 100644 tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java create mode 100644 tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java create mode 100644 tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index 3e0e3ad668..77d26db244 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -2,10 +2,10 @@ import com.techcourse.db.InMemoryUserRepository; import com.techcourse.model.User; -import org.apache.coyote.http11.exception.NotFoundException; -import org.apache.coyote.http11.session.Session; +import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httpresponse.HttpResponse; +import org.apache.coyote.http11.session.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,7 +16,6 @@ public class LoginController extends AbstractController { private static final String ACCOUNT = "account"; private static final String PASSWORD = "password"; private static final String INDEX_PATH = "/index.html"; - private static final String UNAUTHORIZED_PATH = "/401.html"; private static final String JSESSIONID = "JSESSIONID"; private static final String COOKIE_DELIMITER = "="; private static final String SESSION_USER_NAME = "user"; @@ -39,12 +38,12 @@ private HttpResponse acceptLogin(HttpRequest httpRequest) { String password = httpRequest.getBodyValue(PASSWORD); User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(() -> new NotFoundException("존재하지 않는 계정입니다")); + .orElseThrow(() -> new UnauthorizedException("존재하지 않는 계정입니다")); if (user.checkPassword(password)) { return redirectWithCookie(httpRequest, user); } log.error("비밀번호 불일치"); - return redirectPage(httpRequest, UNAUTHORIZED_PATH); + throw new UnauthorizedException("존재하지 않는 계정입니다"); } private static HttpResponse redirectWithCookie(HttpRequest httpRequest, User user) { diff --git a/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java index 597bb8fc7b..26d2d9caa8 100644 --- a/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java +++ b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java @@ -4,6 +4,7 @@ import java.util.Map; import com.techcourse.config.UnauthorizedInterceptor; import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; public class RequestMapping { @@ -19,7 +20,7 @@ public RequestMapping() { public Controller getController(HttpRequest httpRequest) { if (unauthorizedInterceptor.isInterceptPath(httpRequest)) { - return new UnauthorizedController(); + throw new UnauthorizedException("권한이 없는 페이지로의 접근입니다"); } String path = httpRequest.getPath(); diff --git a/tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java b/tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java deleted file mode 100644 index 5fc9d9d845..0000000000 --- a/tomcat/src/main/java/com/techcourse/controller/UnauthorizedController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.techcourse.controller; - -import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httpresponse.HttpResponse; - -public class UnauthorizedController extends AbstractController { - - private static final String UNAUTHORIZED_PATH = "/401.html"; - - @Override - protected HttpResponse doPost(HttpRequest httpRequest) { - throw new IllegalArgumentException(); - } - - @Override - protected HttpResponse doGet(HttpRequest httpRequest) { - return HttpResponse.unauthorized(httpRequest) - .staticResource(UNAUTHORIZED_PATH) - .build(); - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 906a2a0b57..b5c6d85813 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -10,6 +10,7 @@ import com.techcourse.controller.Controller; import com.techcourse.controller.RequestMapping; import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.apache.coyote.http11.httpresponse.HttpResponse; @@ -20,6 +21,7 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private static final String NOT_FOUND_PATH = "/404.html"; + private static final String UNAUTHORIZED_PATH = "/401.html"; private static final String CHECKED_STATIC_RESOURCE = "."; private final Socket connection; @@ -67,6 +69,10 @@ private HttpResponse getHttpResponse(HttpRequest httpRequest) throws IOException return HttpResponse.found(httpRequest) .location(NOT_FOUND_PATH) .build(); + } catch (UnauthorizedException e) { + return HttpResponse.found(httpRequest) + .location(UNAUTHORIZED_PATH) + .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/exception/UnauthorizedException.java b/tomcat/src/main/java/org/apache/coyote/http11/exception/UnauthorizedException.java new file mode 100644 index 0000000000..96de0c8a45 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/exception/UnauthorizedException.java @@ -0,0 +1,8 @@ +package org.apache.coyote.http11.exception; + +public class UnauthorizedException extends RuntimeException { + + public UnauthorizedException(String message) { + super(message); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 258b907fcc..02816c2bff 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -106,6 +106,7 @@ private static HttpRequestBody getHttpRequestBody( char[] buffer = new char[contentLength]; bufferedReader.read(buffer, 0, contentLength); String requestBody = new String(buffer); + System.out.println(requestBody); Map body = extractBody(requestBody); return new HttpRequestBody(body); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 044c6792ac..8e24fa77fb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -57,11 +57,13 @@ public byte[] getBytes() { statusLine, responseHeader, responseBody); + System.out.println(join); return join.getBytes(); } String join = String.join(RESPONSE_LINE_DELIMITER, statusLine, responseHeader); + System.out.println(join); return join.getBytes(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index 2751db0c82..1dbcb6acb5 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -15,12 +15,7 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { } public String getString() { - return String.join( - STATUS_LINE_DELIMITER, - version, - String.valueOf(httpStatusCode.getCode()), - httpStatusCode.getMessage() - ); + return "%s %s %s ".formatted(version, httpStatusCode.getCode(), httpStatusCode.getMessage()); } public String getVersion() { diff --git a/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java b/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java new file mode 100644 index 0000000000..a6ab0ee792 --- /dev/null +++ b/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java @@ -0,0 +1,50 @@ +package com.techcourse.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class UnauthorizedInterceptorTest { + + @DisplayName("해당 path가 Unauthorized인 Path이면 true를 반환한다") + @Test + void isInterceptPath() throws IOException { + final String interceptPath = String.join("\r\n", + "GET /401 HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(interceptPath.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); + + assertThat(unauthorizedInterceptor.isInterceptPath(httpRequest)).isTrue(); + } + + @DisplayName("해당 path가 Unauthorized인 Path가 아니면 false를 반환한다") + @Test + void isNotInterceptPath() throws IOException { + final String notInterceptPath = String.join("\r\n", + "GET /index.html HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(notInterceptPath.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); + + assertThat(unauthorizedInterceptor.isInterceptPath(httpRequest)).isFalse(); + } +} diff --git a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java new file mode 100644 index 0000000000..238f588bde --- /dev/null +++ b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java @@ -0,0 +1,116 @@ +package com.techcourse.controller; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; +import org.apache.coyote.http11.httpresponse.HttpResponse; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RegisterControllerTest { + + @DisplayName("회원가입이 성공하면 /index.html 페이지로 이동한다") + @Test + void register() throws IOException { + String body = "account=f&password=12&email=bito@wooea.net"; + final String register = String.join("\r\n", + "POST /register HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(register.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RegisterController registerController = new RegisterController(); + HttpResponse httpResponse = registerController.doPost(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found ".getBytes()) + .contains("Location: /index".getBytes()); + } + + @DisplayName("일부 항목을 입력하지 않고 회원가입을 시도하면 /register 페이지로 이동한다") + @Test + void notExistUserInput() throws IOException { + String body = "account=f&password=&email=bito@wooea.net"; + final String register = String.join("\r\n", + "POST /register HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(register.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RegisterController registerController = new RegisterController(); + HttpResponse httpResponse = registerController.doPost(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found ".getBytes()) + .contains("Location: /register".getBytes()); + } + + @DisplayName("이미 회원가입이 되어있는 account로 회원가입을 시도할 경우 /register 페이지로 이동한다") + @Test + void existUserRegister() throws IOException { + String body = "account=gugu&password=1&email=bito@wooea.net"; + final String register = String.join("\r\n", + "POST /register HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(register.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RegisterController registerController = new RegisterController(); + HttpResponse httpResponse = registerController.doPost(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found ".getBytes()) + .contains("Location: /register".getBytes()); + } + + @DisplayName("GET으로 /register를 접근하면 static/register.html을 띄운다") + @Test + void doGet() throws IOException { + final String login = String.join("\r\n", + "GET /register HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + final URL resource = getClass().getClassLoader().getResource("static/register.html"); + String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); + RegisterController registerController = new RegisterController(); + HttpResponse httpResponse = registerController.doGet(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 200 OK ".getBytes()) + .contains("Content-Type: text/html;charset=utf-8 ".getBytes()) + .contains(("Content-Length: " + body.getBytes().length + " ").getBytes()) + .contains(body.getBytes()); + } +} diff --git a/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java new file mode 100644 index 0000000000..0a120d2139 --- /dev/null +++ b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java @@ -0,0 +1,74 @@ +package com.techcourse.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.exception.UnauthorizedException; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RequestMappingTest { + + @DisplayName("해당 path에 알맞은 Controller를 반환한다") + @Test + void getController() throws IOException { + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RequestMapping requestMapping = new RequestMapping(); + Controller controller = requestMapping.getController(httpRequest); + + assertThat(controller) + .isInstanceOf(LoginController.class); + } + + @DisplayName("등록되지 않은 path일 경우 예외를 발생시킨다") + @Test + void notExistPath() throws IOException { + final String login = String.join("\r\n", + "GET /lo HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RequestMapping requestMapping = new RequestMapping(); + + assertThatThrownBy(() -> requestMapping.getController(httpRequest)) + .isInstanceOf(NotFoundException.class); + } + + @DisplayName("권한이 없는 페이지로 접근할 경우 예외를 발생시킨다") + @Test + void unauthorizedPath() throws IOException { + final String login = String.join("\r\n", + "GET /500 HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + RequestMapping requestMapping = new RequestMapping(); + + assertThatThrownBy(() -> requestMapping.getController(httpRequest)) + .isInstanceOf(UnauthorizedException.class); + } +} diff --git a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java index 9d9071b6f9..56a3d9b203 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java @@ -11,26 +11,6 @@ class Http11ProcessorTest { - @Test - void process() { - // given - final var socket = new StubSocket(); - final var processor = new Http11Processor(socket); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 12 ", - "", - "Hello world!"); - - assertThat(socket.output()).isEqualTo(expected); - } - @Test void index() throws IOException { // given @@ -50,8 +30,8 @@ void index() throws IOException { // then final URL resource = getClass().getClassLoader().getResource("static/index.html"); var expected = "HTTP/1.1 200 OK \r\n" + - "Content-Type: text/html;charset=utf-8 \r\n" + "Content-Length: 5670 \r\n" + + "Content-Type: text/html;charset=utf-8 \r\n" + "\r\n"+ new String(Files.readAllBytes(new File(resource.getFile()).toPath())); From ff86414196010271bd54751a04af47e0cd6f727b Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:24:06 +0900 Subject: [PATCH 48/73] =?UTF-8?q?test:=20HttpRequestConvertorTest=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 --- .../httprequest/HttpRequestConvertor.java | 7 +- .../httprequest/HttpRequestConvertorTest.java | 145 ++++++++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 02816c2bff..2f69c2d8d8 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -43,10 +43,10 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro private static void validateRequestLine(String requestLine) { if (requestLine == null) { - throw new IllegalArgumentException("요청이 비어 있습니다."); + throw new IllegalArgumentException("요청이 비어 있습니다"); } if (requestLine.split(REQUEST_LINE_DELIMITER).length < 3) { - throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다."); + throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다"); } } @@ -65,6 +65,9 @@ private static String parseHeaderValue(String[] requestLine) { StringBuilder sb = new StringBuilder(); for (int i = 1; i < requestLine.length; i++) { sb.append(requestLine[i].strip()); + if (i != requestLine.length - 1) { + sb.append(HEADER_DELIMITER); + } } return sb.toString(); diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java new file mode 100644 index 0000000000..5078a965fd --- /dev/null +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java @@ -0,0 +1,145 @@ +package org.apache.coyote.http11.httprequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.apache.coyote.http11.HttpHeaderName; +import org.apache.coyote.http11.HttpMethod; +import org.apache.coyote.http11.session.Session; +import org.apache.coyote.http11.session.SessionManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class HttpRequestConvertorTest { + + @DisplayName("빈 값이 들어오면 예외를 발생시킨다") + @Test + void throwExceptionWhenNull() { + final String register = ""; + InputStream inputStream = new ByteArrayInputStream(register.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + assertThatThrownBy(() -> HttpRequestConvertor.convertHttpRequest(bufferedReader)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("요청이 비어 있습니다"); + } + + @DisplayName("RequestLine이 잘못 전달되면 예외를 발생시킨다") + @Test + void invalidRequestLine() { + final String login = String.join("\r\n", + "GET HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + assertThatThrownBy(() -> HttpRequestConvertor.convertHttpRequest(bufferedReader)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("RequestLine이 잘못된 요청입니다"); + } + + @DisplayName("들어온 요청을 HttpRequest로 변환한다") + @Test + void convertHttpRequest() throws IOException { + String body = "account=gugu&password=1"; + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + assertAll( + () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), + () -> assertThat(httpRequest.getPath()).isEqualTo("/login"), + () -> assertThat(httpRequest.getVersion()).isEqualTo("HTTP/1.1"), + () -> assertThat(httpRequest.getHeaderValue("Host")).isEqualTo("localhost:8080"), + () -> assertThat(httpRequest.getHeaderValue("Connection")).isEqualTo("keep-alive"), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_LENGTH)).isEqualTo(String.valueOf(body.getBytes().length)), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_TYPE)).isEqualTo("application/x-www-form-urlencoded"), + () -> assertThat(httpRequest.getBodyValue("account")).isEqualTo("gugu"), + () -> assertThat(httpRequest.getBodyValue("password")).isEqualTo("1") + ); + } + + @DisplayName("SessionManager에 저장된 세션이 쿠키로 들어오면 해당 세션을 불러온다") + @Test + void loadSession() throws IOException { + SessionManager sessionManager = new SessionManager(); + Session session = new Session("abcdefg"); + sessionManager.add(session); + String body = "account=gugu&password=1"; + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Cookie: JSESSIONID=abcdefg", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + assertAll( + () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), + () -> assertThat(httpRequest.getPath()).isEqualTo("/login"), + () -> assertThat(httpRequest.getVersion()).isEqualTo("HTTP/1.1"), + () -> assertThat(httpRequest.getHeaderValue("Host")).isEqualTo("localhost:8080"), + () -> assertThat(httpRequest.getHeaderValue("Connection")).isEqualTo("keep-alive"), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_LENGTH)).isEqualTo(String.valueOf(body.getBytes().length)), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_TYPE)).isEqualTo("application/x-www-form-urlencoded"), + () -> assertThat(httpRequest.getBodyValue("account")).isEqualTo("gugu"), + () -> assertThat(httpRequest.getBodyValue("password")).isEqualTo("1"), + () -> assertThat(httpRequest.getSession().getId()).isEqualTo("abcdefg") + ); + } + + @DisplayName("쿠키에 저장된 세션이 저장되지 않은 세션이면 새로 세션을 생성한다") + @Test + void createSession() throws IOException { + String body = "account=gugu&password=1"; + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Cookie: JSESSIONID=abcdefg", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + assertAll( + () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), + () -> assertThat(httpRequest.getPath()).isEqualTo("/login"), + () -> assertThat(httpRequest.getVersion()).isEqualTo("HTTP/1.1"), + () -> assertThat(httpRequest.getHeaderValue("Host")).isEqualTo("localhost:8080"), + () -> assertThat(httpRequest.getHeaderValue("Connection")).isEqualTo("keep-alive"), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_LENGTH)).isEqualTo(String.valueOf(body.getBytes().length)), + () -> assertThat(httpRequest.getHeaderValue(HttpHeaderName.CONTENT_TYPE)).isEqualTo("application/x-www-form-urlencoded"), + () -> assertThat(httpRequest.getBodyValue("account")).isEqualTo("gugu"), + () -> assertThat(httpRequest.getBodyValue("password")).isEqualTo("1"), + () -> assertThat(httpRequest.getSession().getId()).isNotEqualTo("abcdefg") + ); + } +} From 5a28c6804925cde6a4dbc8fbca03de5dd6438581 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:28:38 +0900 Subject: [PATCH 49/73] =?UTF-8?q?test:=20HttpCookieConvertorTest=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 --- .../httprequest/HttpCookieConvertorTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpCookieConvertorTest.java diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpCookieConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpCookieConvertorTest.java new file mode 100644 index 0000000000..5ae55b4c5f --- /dev/null +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpCookieConvertorTest.java @@ -0,0 +1,24 @@ +package org.apache.coyote.http11.httprequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class HttpCookieConvertorTest { + + @DisplayName("HttpCookie를 정확히 추출한다") + @Test + void convertHttpCookie() { + String rowCookie = "JSESSIONID=abcdefg; account=gugu; password=; uuid=mk"; + HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie(rowCookie); + + assertAll( + () -> assertThat(httpCookie.getCookieValue("JSESSIONID")).isEqualTo("abcdefg"), + () -> assertThat(httpCookie.getCookieValue("account")).isEqualTo("gugu"), + () -> assertThat(httpCookie.getCookieValue("password")).isNull(), + () -> assertThat(httpCookie.getCookieValue("uuid")).isEqualTo("mk") + ); + } +} From bd236dcaa99d525c59b42d2cc0670d0d05a1556b Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:35:12 +0900 Subject: [PATCH 50/73] =?UTF-8?q?test:=20LoginControllerTest=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginControllerTest.java | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java diff --git a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java new file mode 100644 index 0000000000..f5689874a6 --- /dev/null +++ b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java @@ -0,0 +1,166 @@ +package com.techcourse.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import org.apache.coyote.http11.exception.UnauthorizedException; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; +import org.apache.coyote.http11.httpresponse.HttpResponse; +import org.apache.coyote.http11.session.Session; +import org.apache.coyote.http11.session.SessionManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class LoginControllerTest { + + @DisplayName("회원가입 되어있는 id와 password로 로그인을 하면 쿠키를 세팅하고 index.html로 이동한다") + @Test + void login() throws IOException { + String body = "account=gugu&password=1"; + final String login = String.join("\r\n", + "POST /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + String id = httpRequest.getSession().getId(); + + LoginController loginController = new LoginController(); + HttpResponse httpResponse = loginController.doPost(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found ".getBytes()) + .contains("Location: /index.html ".getBytes()) + .contains(("Set-Cookie: JSESSIONID=" + id + " ").getBytes()); + } + + @DisplayName("id와 비밀번호가 일치하지 않으면 예외를 발생시킨다") + @Test + void notMatchAccountAndPassword() throws IOException { + String body = "account=gugu&password=2"; + final String login = String.join("\r\n", + "POST /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + LoginController loginController = new LoginController(); + + assertThatThrownBy(() -> loginController.doPost(httpRequest)) + .isInstanceOf(UnauthorizedException.class); + } + + @DisplayName("회원가입 되어있지 않은 account로 로그인을 하면 예외를 발생시킨다") + @Test + void notExistByAccount() throws IOException { + String body = "account=gugu2&password=1"; + final String login = String.join("\r\n", + "POST /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + LoginController loginController = new LoginController(); + + assertThatThrownBy(() -> loginController.doPost(httpRequest)) + .isInstanceOf(UnauthorizedException.class); + } + + @DisplayName("유저가 일부 값을 입력하지 않을 시 로그인 페이지로 이동한다") + @Test + void notExistUserInput() throws IOException { + String body = "account=&password=1"; + final String login = String.join("\r\n", + "POST /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + "Content-Length: " + body.getBytes().length + " ", + "Content-Type: application/x-www-form-urlencoded ", + "", + body); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + LoginController loginController = new LoginController(); + HttpResponse httpResponse = loginController.doPost(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found ".getBytes()) + .contains("Location: /login".getBytes()); + } + + @DisplayName("쿠키에 유저 정보를 의미하는 세션이 없으면 로그인 페이지로 이동한다") + @Test + void notExistSessionLogin() throws IOException { + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + final URL resource = getClass().getClassLoader().getResource("static/login.html"); + String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); + LoginController loginController = new LoginController(); + HttpResponse httpResponse = loginController.doGet(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 200 OK ".getBytes()) + .contains("Content-Type: text/html;charset=utf-8 ".getBytes()) + .contains(("Content-Length: " + body.getBytes().length + " ").getBytes()) + .contains(body.getBytes()); + } + + @DisplayName("쿠키에 유저 정보가 저장된 세션이 있으면 index.html 페이지로 이동한다") + @Test + void existSessionLogin() throws IOException { + SessionManager sessionManager = new SessionManager(); + Session session = new Session("abcdefg"); + sessionManager.add(session); + final String login = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Cookie: JSESSIONID=abcdefg", + "Connection: keep-alive ", + ""); + InputStream inputStream = new ByteArrayInputStream(login.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + + LoginController loginController = new LoginController(); + HttpResponse httpResponse = loginController.doGet(httpRequest); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 200 OK ".getBytes()) + .contains("Location: /login".getBytes()); + } +} From 0039a0001362f122406251317a5344d03b6ea6ae Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:55:34 +0900 Subject: [PATCH 51/73] =?UTF-8?q?test:=20HttpResponseTest=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/httpresponse/HttpResponseTest.java | 54 +++++++++++++++++++ .../test/java/support/HttpRequestMaker.java | 22 ++++++++ 2 files changed, 76 insertions(+) create mode 100644 tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java create mode 100644 tomcat/src/test/java/support/HttpRequestMaker.java diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java new file mode 100644 index 0000000000..d2f70f8259 --- /dev/null +++ b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java @@ -0,0 +1,54 @@ +package org.apache.coyote.http11.httpresponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; + +class HttpResponseTest { + + @DisplayName("잘못된 파일 경로를 입력할 경우 예외를 발생시킨다") + @Test + void invalidPath() { + final String request = String.join("\r\n", + "GET /ln HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); + + assertThatThrownBy(() -> HttpResponse.ok(httpRequest).staticResource("/ln")) + .isInstanceOf(NotFoundException.class); + } + + @DisplayName("입력한 값을 정확하게 HttpResponse로 변환한다") + @Test + void httpResponseBuilder() { + final String request = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); + + HttpResponse httpResponse = HttpResponse.found(httpRequest) + .location("/index") + .setCookie("JSESSIONID=abcde") + .contentLength("89") + .contentType("test") + .responseBody("testResponseBody") + .build(); + + assertThat(httpResponse.getBytes()) + .contains("HTTP/1.1 302 Found".getBytes()) + .contains("Location: /index".getBytes()) + .contains("Set-Cookie: JSESSIONID=abcde".getBytes()) + .contains("Content-Length: 89".getBytes()) + .contains("Content-Type: test".getBytes()) + .contains("testResponseBody".getBytes()); + } +} diff --git a/tomcat/src/test/java/support/HttpRequestMaker.java b/tomcat/src/test/java/support/HttpRequestMaker.java new file mode 100644 index 0000000000..2f9bb756a1 --- /dev/null +++ b/tomcat/src/test/java/support/HttpRequestMaker.java @@ -0,0 +1,22 @@ +package support; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.httprequest.HttpRequestConvertor; + +public class HttpRequestMaker { + + public static HttpRequest makeHttpRequest(String httpRequest) { + try { + InputStream inputStream = new ByteArrayInputStream(httpRequest.getBytes()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + return HttpRequestConvertor.convertHttpRequest(bufferedReader); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } +} From 3e6b67d542d8234c6dd97d165270a9d56d07af90 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:56:00 +0900 Subject: [PATCH 52/73] =?UTF-8?q?test:=20HttpRequestMaker=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/UnauthorizedInterceptorTest.java | 19 +++------ .../controller/LoginControllerTest.java | 40 ++++++------------- .../controller/RegisterControllerTest.java | 30 +++++--------- .../controller/RequestMappingTest.java | 29 +++++--------- .../httprequest/HttpRequestConvertorTest.java | 29 +++++--------- 5 files changed, 45 insertions(+), 102 deletions(-) diff --git a/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java b/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java index a6ab0ee792..943bef1aad 100644 --- a/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java +++ b/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java @@ -2,29 +2,22 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; class UnauthorizedInterceptorTest { @DisplayName("해당 path가 Unauthorized인 Path이면 true를 반환한다") @Test - void isInterceptPath() throws IOException { + void isInterceptPath() { final String interceptPath = String.join("\r\n", "GET /401 HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(interceptPath.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(interceptPath); UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); @@ -33,15 +26,13 @@ void isInterceptPath() throws IOException { @DisplayName("해당 path가 Unauthorized인 Path가 아니면 false를 반환한다") @Test - void isNotInterceptPath() throws IOException { + void isNotInterceptPath() { final String notInterceptPath = String.join("\r\n", "GET /index.html HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(notInterceptPath.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(notInterceptPath); UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); diff --git a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java index f5689874a6..8c3b2940bf 100644 --- a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java @@ -3,28 +3,24 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; import java.nio.file.Files; import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.apache.coyote.http11.session.Session; import org.apache.coyote.http11.session.SessionManager; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; class LoginControllerTest { @DisplayName("회원가입 되어있는 id와 password로 로그인을 하면 쿠키를 세팅하고 index.html로 이동한다") @Test - void login() throws IOException { + void login() { String body = "account=gugu&password=1"; final String login = String.join("\r\n", "POST /login HTTP/1.1 ", @@ -34,9 +30,7 @@ void login() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); String id = httpRequest.getSession().getId(); LoginController loginController = new LoginController(); @@ -50,7 +44,7 @@ void login() throws IOException { @DisplayName("id와 비밀번호가 일치하지 않으면 예외를 발생시킨다") @Test - void notMatchAccountAndPassword() throws IOException { + void notMatchAccountAndPassword() { String body = "account=gugu&password=2"; final String login = String.join("\r\n", "POST /login HTTP/1.1 ", @@ -60,9 +54,7 @@ void notMatchAccountAndPassword() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); @@ -72,7 +64,7 @@ void notMatchAccountAndPassword() throws IOException { @DisplayName("회원가입 되어있지 않은 account로 로그인을 하면 예외를 발생시킨다") @Test - void notExistByAccount() throws IOException { + void notExistByAccount() { String body = "account=gugu2&password=1"; final String login = String.join("\r\n", "POST /login HTTP/1.1 ", @@ -82,9 +74,7 @@ void notExistByAccount() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); @@ -94,7 +84,7 @@ void notExistByAccount() throws IOException { @DisplayName("유저가 일부 값을 입력하지 않을 시 로그인 페이지로 이동한다") @Test - void notExistUserInput() throws IOException { + void notExistUserInput() { String body = "account=&password=1"; final String login = String.join("\r\n", "POST /login HTTP/1.1 ", @@ -104,9 +94,7 @@ void notExistUserInput() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); HttpResponse httpResponse = loginController.doPost(httpRequest); @@ -124,9 +112,7 @@ void notExistSessionLogin() throws IOException { "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); final URL resource = getClass().getClassLoader().getResource("static/login.html"); String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); @@ -142,7 +128,7 @@ void notExistSessionLogin() throws IOException { @DisplayName("쿠키에 유저 정보가 저장된 세션이 있으면 index.html 페이지로 이동한다") @Test - void existSessionLogin() throws IOException { + void existSessionLogin() { SessionManager sessionManager = new SessionManager(); Session session = new Session("abcdefg"); sessionManager.add(session); @@ -152,9 +138,7 @@ void existSessionLogin() throws IOException { "Cookie: JSESSIONID=abcdefg", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); HttpResponse httpResponse = loginController.doGet(httpRequest); diff --git a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java index 238f588bde..b6e4d8ce76 100644 --- a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java @@ -2,25 +2,21 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; import java.nio.file.Files; import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.apache.coyote.http11.httpresponse.HttpResponse; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; class RegisterControllerTest { @DisplayName("회원가입이 성공하면 /index.html 페이지로 이동한다") @Test - void register() throws IOException { + void register() { String body = "account=f&password=12&email=bito@wooea.net"; final String register = String.join("\r\n", "POST /register HTTP/1.1 ", @@ -30,9 +26,7 @@ void register() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(register.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); RegisterController registerController = new RegisterController(); HttpResponse httpResponse = registerController.doPost(httpRequest); @@ -44,7 +38,7 @@ void register() throws IOException { @DisplayName("일부 항목을 입력하지 않고 회원가입을 시도하면 /register 페이지로 이동한다") @Test - void notExistUserInput() throws IOException { + void notExistUserInput() { String body = "account=f&password=&email=bito@wooea.net"; final String register = String.join("\r\n", "POST /register HTTP/1.1 ", @@ -54,9 +48,7 @@ void notExistUserInput() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(register.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); RegisterController registerController = new RegisterController(); HttpResponse httpResponse = registerController.doPost(httpRequest); @@ -68,7 +60,7 @@ void notExistUserInput() throws IOException { @DisplayName("이미 회원가입이 되어있는 account로 회원가입을 시도할 경우 /register 페이지로 이동한다") @Test - void existUserRegister() throws IOException { + void existUserRegister() { String body = "account=gugu&password=1&email=bito@wooea.net"; final String register = String.join("\r\n", "POST /register HTTP/1.1 ", @@ -78,9 +70,7 @@ void existUserRegister() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(register.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); RegisterController registerController = new RegisterController(); HttpResponse httpResponse = registerController.doPost(httpRequest); @@ -93,14 +83,12 @@ void existUserRegister() throws IOException { @DisplayName("GET으로 /register를 접근하면 static/register.html을 띄운다") @Test void doGet() throws IOException { - final String login = String.join("\r\n", + final String register = String.join("\r\n", "GET /register HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); final URL resource = getClass().getClassLoader().getResource("static/register.html"); String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); diff --git a/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java index 0a120d2139..efb2d3d18c 100644 --- a/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java @@ -3,31 +3,24 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; -import org.apache.coyote.http11.httprequest.HttpRequestConvertor; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; class RequestMappingTest { @DisplayName("해당 path에 알맞은 Controller를 반환한다") @Test - void getController() throws IOException { + void getController() { final String login = String.join("\r\n", "GET /login HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); RequestMapping requestMapping = new RequestMapping(); Controller controller = requestMapping.getController(httpRequest); @@ -38,15 +31,13 @@ void getController() throws IOException { @DisplayName("등록되지 않은 path일 경우 예외를 발생시킨다") @Test - void notExistPath() throws IOException { - final String login = String.join("\r\n", + void notExistPath() { + final String request = String.join("\r\n", "GET /lo HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); RequestMapping requestMapping = new RequestMapping(); @@ -56,15 +47,13 @@ void notExistPath() throws IOException { @DisplayName("권한이 없는 페이지로 접근할 경우 예외를 발생시킨다") @Test - void unauthorizedPath() throws IOException { - final String login = String.join("\r\n", + void unauthorizedPath() { + final String request = String.join("\r\n", "GET /500 HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", ""); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); RequestMapping requestMapping = new RequestMapping(); diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java index 5078a965fd..ff6140cb3f 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java @@ -6,7 +6,6 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.coyote.http11.HttpHeaderName; @@ -15,6 +14,7 @@ import org.apache.coyote.http11.session.SessionManager; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import support.HttpRequestMaker; class HttpRequestConvertorTest { @@ -48,9 +48,9 @@ void invalidRequestLine() { @DisplayName("들어온 요청을 HttpRequest로 변환한다") @Test - void convertHttpRequest() throws IOException { + void convertHttpRequest() { String body = "account=gugu&password=1"; - final String login = String.join("\r\n", + final String request = String.join("\r\n", "GET /login HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", @@ -58,10 +58,7 @@ void convertHttpRequest() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); assertAll( () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), @@ -78,12 +75,12 @@ void convertHttpRequest() throws IOException { @DisplayName("SessionManager에 저장된 세션이 쿠키로 들어오면 해당 세션을 불러온다") @Test - void loadSession() throws IOException { + void loadSession() { SessionManager sessionManager = new SessionManager(); Session session = new Session("abcdefg"); sessionManager.add(session); String body = "account=gugu&password=1"; - final String login = String.join("\r\n", + final String request = String.join("\r\n", "GET /login HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", @@ -92,10 +89,7 @@ void loadSession() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); assertAll( () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), @@ -113,9 +107,9 @@ void loadSession() throws IOException { @DisplayName("쿠키에 저장된 세션이 저장되지 않은 세션이면 새로 세션을 생성한다") @Test - void createSession() throws IOException { + void createSession() { String body = "account=gugu&password=1"; - final String login = String.join("\r\n", + final String request = String.join("\r\n", "GET /login HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", @@ -124,10 +118,7 @@ void createSession() throws IOException { "Content-Type: application/x-www-form-urlencoded ", "", body); - InputStream inputStream = new ByteArrayInputStream(login.getBytes()); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - - HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); assertAll( () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), From cd9c986f73ddd219473d3e5a87e73f07eb0a4cbf Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 14:56:57 +0900 Subject: [PATCH 53/73] =?UTF-8?q?refactor:=20=EB=94=94=EB=B2=84=EA=B9=85?= =?UTF-8?q?=EC=9A=A9=20=EC=B6=9C=EB=A0=A5=EB=AC=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/http11/httprequest/HttpRequestConvertor.java | 1 - .../org/apache/coyote/http11/httpresponse/HttpResponse.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 2f69c2d8d8..67382157ed 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -109,7 +109,6 @@ private static HttpRequestBody getHttpRequestBody( char[] buffer = new char[contentLength]; bufferedReader.read(buffer, 0, contentLength); String requestBody = new String(buffer); - System.out.println(requestBody); Map body = extractBody(requestBody); return new HttpRequestBody(body); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 8e24fa77fb..044c6792ac 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -57,13 +57,11 @@ public byte[] getBytes() { statusLine, responseHeader, responseBody); - System.out.println(join); return join.getBytes(); } String join = String.join(RESPONSE_LINE_DELIMITER, statusLine, responseHeader); - System.out.println(join); return join.getBytes(); } From dbf14baa56717f454ff7aca7984695b5bc7271fd Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 15:00:05 +0900 Subject: [PATCH 54/73] =?UTF-8?q?test:=20=EC=98=A4=EB=A5=98=EA=B0=80=20?= =?UTF-8?q?=EB=82=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- .../apache/coyote/http11/Http11ProcessorTest.java | 12 ++++++------ .../http11/httprequest/HttpRequestConvertorTest.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java index 56a3d9b203..d363eb0fe1 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java @@ -29,12 +29,12 @@ void index() throws IOException { // then final URL resource = getClass().getClassLoader().getResource("static/index.html"); - var expected = "HTTP/1.1 200 OK \r\n" + - "Content-Length: 5670 \r\n" + - "Content-Type: text/html;charset=utf-8 \r\n" + - "\r\n"+ - new String(Files.readAllBytes(new File(resource.getFile()).toPath())); + String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); - assertThat(socket.output()).isEqualTo(expected); + assertThat(socket.output().getBytes()) + .contains("HTTP/1.1 200 OK".getBytes()) + .contains("Content-Length: 5670".getBytes()) + .contains("Content-Type: text/html;charset=utf-8".getBytes()) + .contains(body.getBytes()); } } diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java index ff6140cb3f..c439be3f13 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java @@ -113,7 +113,7 @@ void createSession() { "GET /login HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", - "Cookie: JSESSIONID=abcdefg", + "Cookie: JSESSIONID=abcd", "Content-Length: " + body.getBytes().length + " ", "Content-Type: application/x-www-form-urlencoded ", "", From afa95869d1a87a6f662734318917caa6206ff2b9 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 15:01:26 +0900 Subject: [PATCH 55/73] =?UTF-8?q?test:=20DisplayName=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http11/Http11ProcessorTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java index d363eb0fe1..48bbb028ee 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/Http11ProcessorTest.java @@ -6,14 +6,15 @@ import java.io.IOException; import java.net.URL; import java.nio.file.Files; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import support.StubSocket; class Http11ProcessorTest { + @DisplayName("정적 파일을 요청하면 해당 파일을 반환한다") @Test - void index() throws IOException { - // given + void staticResource() throws IOException { final String httpRequest= String.join("\r\n", "GET /index.html HTTP/1.1 ", "Host: localhost:8080 ", @@ -24,10 +25,8 @@ void index() throws IOException { final var socket = new StubSocket(httpRequest); final Http11Processor processor = new Http11Processor(socket); - // when processor.process(socket); - // then final URL resource = getClass().getClassLoader().getResource("static/index.html"); String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); From 7b0131dc2cac52eadd93dfcc28e28f3a10c715b8 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 20:00:01 +0900 Subject: [PATCH 56/73] =?UTF-8?q?refactor:=20Controller=EC=9D=98=20service?= =?UTF-8?q?=20=ED=98=95=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AbstractController.java | 10 +- .../com/techcourse/controller/Controller.java | 3 +- .../controller/LoginController.java | 43 +++-- .../controller/RegisterController.java | 28 ++-- .../apache/coyote/http11/Http11Processor.java | 34 ++-- .../http11/httpresponse/HttpResponse.java | 155 ++++++++---------- .../httpresponse/HttpResponseHeader.java | 9 + .../http11/httpresponse/HttpStatusLine.java | 2 - .../controller/LoginControllerTest.java | 18 +- .../controller/RegisterControllerTest.java | 12 +- .../http11/httpresponse/HttpResponseTest.java | 19 ++- 11 files changed, 168 insertions(+), 165 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/AbstractController.java b/tomcat/src/main/java/com/techcourse/controller/AbstractController.java index 0d396ac0c9..d91f52d861 100644 --- a/tomcat/src/main/java/com/techcourse/controller/AbstractController.java +++ b/tomcat/src/main/java/com/techcourse/controller/AbstractController.java @@ -7,18 +7,18 @@ public abstract class AbstractController implements Controller { @Override - public HttpResponse service(HttpRequest httpRequest) { + public void service(HttpRequest httpRequest, HttpResponse httpResponse) { if (httpRequest.isMethod(HttpMethod.GET)) { - return doGet(httpRequest); + doGet(httpRequest, httpResponse); } if (httpRequest.isMethod(HttpMethod.POST)) { - return doPost(httpRequest); + doPost(httpRequest, httpResponse); } throw new IllegalArgumentException("유효하지 않은 메소드입니다."); } - abstract protected HttpResponse doPost(HttpRequest httpRequest); + abstract protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse); - abstract protected HttpResponse doGet(HttpRequest httpRequest); + abstract protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse); } diff --git a/tomcat/src/main/java/com/techcourse/controller/Controller.java b/tomcat/src/main/java/com/techcourse/controller/Controller.java index b8ae035206..7a1cffb57a 100644 --- a/tomcat/src/main/java/com/techcourse/controller/Controller.java +++ b/tomcat/src/main/java/com/techcourse/controller/Controller.java @@ -5,5 +5,6 @@ public interface Controller { - HttpResponse service(HttpRequest httpRequest); + void service(HttpRequest request, HttpResponse response) throws Exception; } + diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index 77d26db244..aaa90b4a3e 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -21,60 +21,59 @@ public class LoginController extends AbstractController { private static final String SESSION_USER_NAME = "user"; @Override - protected HttpResponse doPost(HttpRequest httpRequest) { + protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) { if (validateUserInput(httpRequest)) { log.error("입력하지 않은 항목이 있습니다."); - return redirectPage(httpRequest, LOGIN_PATH); + redirectPage(httpRequest, httpResponse, LOGIN_PATH); + return; } - return acceptLogin(httpRequest); + acceptLogin(httpRequest, httpResponse); } private boolean validateUserInput(HttpRequest httpRequest) { return !httpRequest.containsBody(ACCOUNT) || !httpRequest.containsBody(PASSWORD); } - private HttpResponse acceptLogin(HttpRequest httpRequest) { + private void acceptLogin(HttpRequest httpRequest, HttpResponse httpResponse) { String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(() -> new UnauthorizedException("존재하지 않는 계정입니다")); if (user.checkPassword(password)) { - return redirectWithCookie(httpRequest, user); + redirectWithCookie(httpRequest, httpResponse, user); + return; } log.error("비밀번호 불일치"); throw new UnauthorizedException("존재하지 않는 계정입니다"); } - private static HttpResponse redirectWithCookie(HttpRequest httpRequest, User user) { + private void redirectWithCookie(HttpRequest httpRequest, HttpResponse httpResponse, User user) { Session session = httpRequest.getSession(); session.setAttribute(SESSION_USER_NAME, user); log.info(user.toString()); - return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) - .location(INDEX_PATH) - .build(); + httpResponse.found(httpRequest); + httpResponse.setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()); + httpResponse.location(INDEX_PATH); } @Override - protected HttpResponse doGet(HttpRequest httpRequest) { + protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { Session session = httpRequest.getSession(); if (!session.hasAttribute(SESSION_USER_NAME)) { - return HttpResponse.ok(httpRequest) - .staticResource(LOGIN_PATH) - .build(); + httpResponse.ok(httpRequest); + httpResponse.staticResource(LOGIN_PATH); + return; } User user = (User) session.getAttribute(SESSION_USER_NAME); log.info(user.toString()); - return HttpResponse.found(httpRequest) - .setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()) - .location(INDEX_PATH) - .build(); + httpResponse.found(httpRequest); + httpResponse.setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()); + httpResponse.location(INDEX_PATH); } - private HttpResponse redirectPage(HttpRequest httpRequest, String path) { - return HttpResponse.found(httpRequest) - .location(path) - .build(); + private void redirectPage(HttpRequest httpRequest, HttpResponse httpResponse, String path) { + httpResponse.found(httpRequest); + httpResponse.location(path); } } diff --git a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java index 24e91043f2..e4a6656d62 100644 --- a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java +++ b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java @@ -17,27 +17,29 @@ public class RegisterController extends AbstractController { private static final String INDEX_PATH = "/index.html"; @Override - protected HttpResponse doPost(HttpRequest httpRequest) { + protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) { if (validateUserInput(httpRequest)) { log.error("입력하지 않은 항목이 있습니다."); - return redirectPage(httpRequest, REGISTER_PATH); + redirectPage(httpRequest, httpResponse, REGISTER_PATH); + return; } - return acceptRegister(httpRequest); + acceptRegister(httpRequest, httpResponse); } - private HttpResponse acceptRegister(HttpRequest httpRequest) { + private void acceptRegister(HttpRequest httpRequest, HttpResponse httpResponse) { String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); String email = httpRequest.getBodyValue(EMAIL); if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); - return redirectPage(httpRequest, REGISTER_PATH); + redirectPage(httpRequest, httpResponse, REGISTER_PATH); + return; } User user = new User(account, password, email); InMemoryUserRepository.save(user); - return redirectPage(httpRequest, INDEX_PATH); + redirectPage(httpRequest, httpResponse, INDEX_PATH); } private boolean validateUserInput(HttpRequest httpRequest) { @@ -47,15 +49,13 @@ private boolean validateUserInput(HttpRequest httpRequest) { } @Override - protected HttpResponse doGet(HttpRequest httpRequest) { - return HttpResponse.ok(httpRequest) - .staticResource(httpRequest.getPath()) - .build(); + protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { + httpResponse.ok(httpRequest); + httpResponse.staticResource(httpRequest.getPath()); } - private HttpResponse redirectPage(HttpRequest httpRequest, String path) { - return HttpResponse.found(httpRequest) - .location(path) - .build(); + private void redirectPage(HttpRequest httpRequest, HttpResponse httpResponse, String path) { + httpResponse.found(httpRequest); + httpResponse.location(path); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index b5c6d85813..75eedf6bbe 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,14 +1,13 @@ package org.apache.coyote.http11; +import com.techcourse.controller.Controller; +import com.techcourse.controller.RequestMapping; import com.techcourse.exception.UncheckedServletException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; -import java.net.URISyntaxException; import org.apache.coyote.Processor; -import com.techcourse.controller.Controller; -import com.techcourse.controller.RequestMapping; import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; @@ -40,39 +39,40 @@ public void run() { public void process(final Socket connection) { try ( final var inputStream = connection.getInputStream(); - final var outputStream = connection.getOutputStream() + final var outputStream = connection.getOutputStream() ) { var bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); - HttpResponse httpResponse = getHttpResponse(httpRequest); + HttpResponse httpResponse = new HttpResponse(); + getHttpResponse(httpRequest, httpResponse); outputStream.write(httpResponse.getBytes()); outputStream.flush(); - } catch (IOException | UncheckedServletException | URISyntaxException e) { + } catch (IOException | UncheckedServletException e) { log.error(e.getMessage(), e); } } - private HttpResponse getHttpResponse(HttpRequest httpRequest) throws IOException, URISyntaxException { + private void getHttpResponse(HttpRequest httpRequest, HttpResponse httpResponse) { try { if (isStaticResource(httpRequest)) { - return HttpResponse.ok(httpRequest) - .staticResource(httpRequest.getPath()) - .build(); + httpResponse.ok(httpRequest); + httpResponse.staticResource(httpRequest.getPath()); + return; } RequestMapping requestMapping = new RequestMapping(); Controller controller = requestMapping.getController(httpRequest); - return controller.service(httpRequest); + controller.service(httpRequest, httpResponse); } catch (NotFoundException e) { - return HttpResponse.found(httpRequest) - .location(NOT_FOUND_PATH) - .build(); + httpResponse.found(httpRequest); + httpResponse.location(NOT_FOUND_PATH); } catch (UnauthorizedException e) { - return HttpResponse.found(httpRequest) - .location(UNAUTHORIZED_PATH) - .build(); + httpResponse.found(httpRequest); + httpResponse.location(UNAUTHORIZED_PATH); + } catch (Exception e) { + throw new IllegalArgumentException(e); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 044c6792ac..ed27b12eda 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -5,8 +5,6 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; import org.apache.coyote.http11.CharSet; import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpStatusCode; @@ -20,9 +18,9 @@ public class HttpResponse { private static final String HTML_EXTENSION = ".html"; private static final String STATIC_PATH = "static"; - private final HttpStatusLine httpStatusLine; + private HttpStatusLine httpStatusLine; private final HttpResponseHeader httpResponseHeader; - private final HttpResponseBody httpResponseBody; + private HttpResponseBody httpResponseBody; private HttpResponse( HttpStatusLine httpStatusLine, @@ -34,16 +32,78 @@ private HttpResponse( this.httpResponseBody = httpResponseBody; } - public static HttpResponseBuilder ok(HttpRequest httpRequest) { - return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK)); + public HttpResponse() { + this(null, new HttpResponseHeader(), null); } - public static HttpResponseBuilder found(HttpRequest httpRequest) { - return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND)); + public void ok(HttpRequest httpRequest) { + this.httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.OK); } - public static HttpResponseBuilder unauthorized(HttpRequest httpRequest) { - return new HttpResponseBuilder(new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED)); + public void found(HttpRequest httpRequest) { + this.httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.FOUND); + } + + public void unauthorized(HttpRequest httpRequest) { + this.httpStatusLine = new HttpStatusLine(httpRequest.getVersion(), HttpStatusCode.UNAUTHORIZED); + } + + public void addHeader(HttpHeaderName headerName, String value) { + httpResponseHeader.addHeader(headerName, value); + } + + public void location(String path) { + addHeader(HttpHeaderName.LOCATION, path); + } + + public void setCookie(String cookie) { + addHeader(HttpHeaderName.SET_COOKIE, cookie); + } + + public void contentLength(String contentLength) { + addHeader(HttpHeaderName.CONTENT_LENGTH, contentLength); + } + + public void contentType(String contentType) { + addHeader(HttpHeaderName.CONTENT_TYPE, contentType); + } + + public void responseBody(String responseBody) { + this.httpResponseBody = new HttpResponseBody(responseBody); + } + + public void staticResource(String path) { + try { + path = settingExtension(path); + String fileName = STATIC_PATH + path; + var resourceUrl = getClass().getClassLoader().getResource(fileName); + validateResourceUrl(resourceUrl); + Path filePath = Path.of(resourceUrl.toURI()); + String responseBody = new String(Files.readAllBytes(filePath)); + + setHttpHeader(filePath, responseBody); + this.httpResponseBody = new HttpResponseBody(responseBody); + } catch (URISyntaxException | IOException e) { + throw new IllegalArgumentException(e.getMessage() + e); + } + } + + private String settingExtension(String path) { + if (!path.contains(EXTENSION_DELIMITER)) { + path += HTML_EXTENSION; + } + return path; + } + + private void validateResourceUrl(URL resourceUrl) { + if (resourceUrl == null) { + throw new NotFoundException("존재하지 않는 경로입니다."); + } + } + + private void setHttpHeader(Path filePath, String responseBody) throws IOException { + contentType(Files.probeContentType(filePath) + CharSet.UTF_8.getCharset()); + contentLength(String.valueOf(responseBody.getBytes().length)); } public byte[] getBytes() { @@ -76,79 +136,4 @@ public HttpResponseHeader getHttpResponseHeader() { public HttpResponseBody getHttpResponseBody() { return httpResponseBody; } - - public static class HttpResponseBuilder { - private final HttpStatusLine httpStatusLine; - private final Map headers; - private HttpResponseBody httpResponseBody; - - public HttpResponseBuilder(HttpStatusLine httpStatusLine) { - this.httpStatusLine = httpStatusLine; - this.headers = new HashMap<>(); - } - - public HttpResponseBuilder location(String location) { - headers.put(HttpHeaderName.LOCATION, location); - return this; - } - - public HttpResponseBuilder contentType(String contentType) { - headers.put(HttpHeaderName.CONTENT_TYPE, contentType); - return this; - } - - public HttpResponseBuilder contentLength(String contentLength) { - headers.put(HttpHeaderName.CONTENT_LENGTH, contentLength); - return this; - } - - public HttpResponseBuilder setCookie(String setCookie) { - headers.put(HttpHeaderName.SET_COOKIE, setCookie); - return this; - } - - public HttpResponseBuilder staticResource(String path) { - try { - path = settingExtension(path); - String fileName = STATIC_PATH + path; - var resourceUrl = getClass().getClassLoader().getResource(fileName); - validateResourceUrl(resourceUrl); - Path filePath = Path.of(resourceUrl.toURI()); - String responseBody = new String(Files.readAllBytes(filePath)); - - setHttpHeader(filePath, responseBody); - this.httpResponseBody = new HttpResponseBody(responseBody); - return this; - } catch (URISyntaxException | IOException e) { - throw new IllegalArgumentException(e.getMessage() + e); - } - } - - private static String settingExtension(String path) { - if (!path.contains(EXTENSION_DELIMITER)) { - path += HTML_EXTENSION; - } - return path; - } - - private static void validateResourceUrl(URL resourceUrl) { - if (resourceUrl == null) { - throw new NotFoundException("존재하지 않는 경로입니다."); - } - } - - private void setHttpHeader(Path filePath, String responseBody) throws IOException { - contentType(Files.probeContentType(filePath) + CharSet.UTF_8.getCharset()); - contentLength(String.valueOf(responseBody.getBytes().length)); - } - - public HttpResponseBuilder responseBody(String responseBody) { - this.httpResponseBody = new HttpResponseBody(responseBody); - return this; - } - - public HttpResponse build() { - return new HttpResponse(httpStatusLine, new HttpResponseHeader(headers), httpResponseBody); - } - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index 3950d6f20b..793cb9a609 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -1,5 +1,6 @@ package org.apache.coyote.http11.httpresponse; +import java.util.HashMap; import java.util.Map; import org.apache.coyote.http11.HttpHeaderName; @@ -14,6 +15,14 @@ public HttpResponseHeader(Map headers) { this.headers = headers; } + public HttpResponseHeader() { + this.headers = new HashMap<>(); + } + + public void addHeader(HttpHeaderName headerName, String value) { + headers.put(headerName, value); + } + public String getString() { StringBuilder stringBuilder = new StringBuilder(); int size = headers.keySet().size(); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index 1dbcb6acb5..dab2e2cdbe 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -4,8 +4,6 @@ public class HttpStatusLine { - private static final String STATUS_LINE_DELIMITER = " "; - private final String version; private final HttpStatusCode httpStatusCode; diff --git a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java index 8c3b2940bf..816841d7d4 100644 --- a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java @@ -31,10 +31,11 @@ void login() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); + HttpResponse httpResponse = new HttpResponse(); String id = httpRequest.getSession().getId(); LoginController loginController = new LoginController(); - HttpResponse httpResponse = loginController.doPost(httpRequest); + loginController.doPost(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found ".getBytes()) @@ -55,10 +56,11 @@ void notMatchAccountAndPassword() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); + HttpResponse httpResponse = new HttpResponse(); LoginController loginController = new LoginController(); - assertThatThrownBy(() -> loginController.doPost(httpRequest)) + assertThatThrownBy(() -> loginController.doPost(httpRequest, httpResponse)) .isInstanceOf(UnauthorizedException.class); } @@ -75,10 +77,11 @@ void notExistByAccount() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); + HttpResponse httpResponse = new HttpResponse(); LoginController loginController = new LoginController(); - assertThatThrownBy(() -> loginController.doPost(httpRequest)) + assertThatThrownBy(() -> loginController.doPost(httpRequest, httpResponse)) .isInstanceOf(UnauthorizedException.class); } @@ -97,7 +100,8 @@ void notExistUserInput() { HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); - HttpResponse httpResponse = loginController.doPost(httpRequest); + HttpResponse httpResponse = new HttpResponse(); + loginController.doPost(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found ".getBytes()) @@ -117,7 +121,8 @@ void notExistSessionLogin() throws IOException { final URL resource = getClass().getClassLoader().getResource("static/login.html"); String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); LoginController loginController = new LoginController(); - HttpResponse httpResponse = loginController.doGet(httpRequest); + HttpResponse httpResponse = new HttpResponse(); + loginController.doGet(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 200 OK ".getBytes()) @@ -141,7 +146,8 @@ void existSessionLogin() { HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(login); LoginController loginController = new LoginController(); - HttpResponse httpResponse = loginController.doGet(httpRequest); + HttpResponse httpResponse = new HttpResponse(); + loginController.doGet(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 200 OK ".getBytes()) diff --git a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java index b6e4d8ce76..7af18b1a49 100644 --- a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java @@ -27,9 +27,10 @@ void register() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); + HttpResponse httpResponse = new HttpResponse(); RegisterController registerController = new RegisterController(); - HttpResponse httpResponse = registerController.doPost(httpRequest); + registerController.doPost(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found ".getBytes()) @@ -49,9 +50,10 @@ void notExistUserInput() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); + HttpResponse httpResponse = new HttpResponse(); RegisterController registerController = new RegisterController(); - HttpResponse httpResponse = registerController.doPost(httpRequest); + registerController.doPost(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found ".getBytes()) @@ -71,9 +73,10 @@ void existUserRegister() { "", body); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); + HttpResponse httpResponse = new HttpResponse(); RegisterController registerController = new RegisterController(); - HttpResponse httpResponse = registerController.doPost(httpRequest); + registerController.doPost(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found ".getBytes()) @@ -89,11 +92,12 @@ void doGet() throws IOException { "Connection: keep-alive ", ""); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(register); + HttpResponse httpResponse = new HttpResponse(); final URL resource = getClass().getClassLoader().getResource("static/register.html"); String body = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); RegisterController registerController = new RegisterController(); - HttpResponse httpResponse = registerController.doGet(httpRequest); + registerController.doGet(httpRequest, httpResponse); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 200 OK ".getBytes()) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java index d2f70f8259..31a88ca817 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java @@ -20,8 +20,9 @@ void invalidPath() { "Connection: keep-alive ", ""); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); + HttpResponse httpResponse = new HttpResponse(); - assertThatThrownBy(() -> HttpResponse.ok(httpRequest).staticResource("/ln")) + assertThatThrownBy(() -> httpResponse.staticResource("/ln")) .isInstanceOf(NotFoundException.class); } @@ -34,14 +35,14 @@ void httpResponseBuilder() { "Connection: keep-alive ", ""); HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); - - HttpResponse httpResponse = HttpResponse.found(httpRequest) - .location("/index") - .setCookie("JSESSIONID=abcde") - .contentLength("89") - .contentType("test") - .responseBody("testResponseBody") - .build(); + HttpResponse httpResponse = new HttpResponse(); + + httpResponse.found(httpRequest); + httpResponse.location("/index"); + httpResponse.setCookie("JSESSIONID=abcde"); + httpResponse.contentLength("89"); + httpResponse.contentType("test"); + httpResponse.responseBody("testResponseBody"); assertThat(httpResponse.getBytes()) .contains("HTTP/1.1 302 Found".getBytes()) From ef947a199987cd417e2e9524fe5f56e9f7c90dc3 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 20:09:37 +0900 Subject: [PATCH 57/73] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/techcourse/controller/LoginController.java | 12 ++++++------ .../coyote/http11/httprequest/HttpRequest.java | 4 ---- .../http11/httprequest/HttpRequestConvertor.java | 9 +++++---- .../http11/httpresponse/HttpResponseHeader.java | 5 +++-- .../coyote/http11/httpresponse/HttpStatusLine.java | 4 +++- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index aaa90b4a3e..02952eafdc 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -24,12 +24,17 @@ public class LoginController extends AbstractController { protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) { if (validateUserInput(httpRequest)) { log.error("입력하지 않은 항목이 있습니다."); - redirectPage(httpRequest, httpResponse, LOGIN_PATH); + redirectLoginPage(httpRequest, httpResponse); return; } acceptLogin(httpRequest, httpResponse); } + private void redirectLoginPage(HttpRequest httpRequest, HttpResponse httpResponse) { + httpResponse.found(httpRequest); + httpResponse.location(LOGIN_PATH); + } + private boolean validateUserInput(HttpRequest httpRequest) { return !httpRequest.containsBody(ACCOUNT) || !httpRequest.containsBody(PASSWORD); } @@ -71,9 +76,4 @@ protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { httpResponse.setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()); httpResponse.location(INDEX_PATH); } - - private void redirectPage(HttpRequest httpRequest, HttpResponse httpResponse, String path) { - httpResponse.found(httpRequest); - httpResponse.location(path); - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java index 09b55d63a0..d85024cf0b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequest.java @@ -32,10 +32,6 @@ public boolean isMethod(HttpMethod method) { return httpRequestLine.isMethod(method); } - public boolean isPath(String path) { - return httpRequestLine.isPath(path); - } - public boolean containsHeader(String key) { return httpRequestHeader.containsHeader(key); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 67382157ed..54235956d8 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -18,12 +18,13 @@ public class HttpRequestConvertor { private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; private static final String BODY_DELIMITER = "&"; private static final String TUPLE_DELIMITER = "="; - private static final int TUPLE_MIN_LENGTH = 2; + private static final int BODY_TUPLE_MIN_LENGTH = 2; private static final int TUPLE_KEY_INDEX = 0; private static final int TUPLE_VALUE_INDEX = 1; private static final int HEADER_KEY_INDEX = 0; - private static final SessionManager SESSION_MANAGER = new SessionManager(); private static final String REQUEST_LINE_DELIMITER = " "; + private static final int REQUEST_LINE_MIN_LENGTH = 3; + private static final SessionManager SESSION_MANAGER = new SessionManager(); public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); @@ -45,7 +46,7 @@ private static void validateRequestLine(String requestLine) { if (requestLine == null) { throw new IllegalArgumentException("요청이 비어 있습니다"); } - if (requestLine.split(REQUEST_LINE_DELIMITER).length < 3) { + if (requestLine.split(REQUEST_LINE_DELIMITER).length < REQUEST_LINE_MIN_LENGTH) { throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다"); } } @@ -116,7 +117,7 @@ private static HttpRequestBody getHttpRequestBody( private static Map extractBody(String requestBody) { String[] tokens = requestBody.split(BODY_DELIMITER); return Arrays.stream(tokens) - .filter(token -> token.split(TUPLE_DELIMITER).length >= TUPLE_MIN_LENGTH) + .filter(token -> token.split(TUPLE_DELIMITER).length >= BODY_TUPLE_MIN_LENGTH) .map(token -> token.split(TUPLE_DELIMITER)) .collect(Collectors.toMap( token -> token[TUPLE_KEY_INDEX], diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index 793cb9a609..4fce9aeca4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -8,6 +8,7 @@ public class HttpResponseHeader { private static final String HEADER_DELIMITER = ": "; private static final String RESPONSE_LINE_DELIMITER = " \r\n"; + private static final int HEADER_VALUE_START_INDEX = 1; private final Map headers; @@ -26,14 +27,14 @@ public void addHeader(HttpHeaderName headerName, String value) { public String getString() { StringBuilder stringBuilder = new StringBuilder(); int size = headers.keySet().size(); - int i = 1; + int i = HEADER_VALUE_START_INDEX; for (HttpHeaderName key : headers.keySet()) { if (i < size) { stringBuilder.append(key.getName()) .append(HEADER_DELIMITER) .append(headers.get(key)) .append(RESPONSE_LINE_DELIMITER); - size++; + i++; continue; } stringBuilder.append(key.getName()) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index dab2e2cdbe..d2a0b7a642 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -4,6 +4,8 @@ public class HttpStatusLine { + private static final String STATUS_LINE_FORMAT = "%s %s %s "; + private final String version; private final HttpStatusCode httpStatusCode; @@ -13,7 +15,7 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { } public String getString() { - return "%s %s %s ".formatted(version, httpStatusCode.getCode(), httpStatusCode.getMessage()); + return STATUS_LINE_FORMAT.formatted(version, httpStatusCode.getCode(), httpStatusCode.getMessage()); } public String getVersion() { From 98f9e5baf088161fa9859310a3e9f845e7c4d010 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 20:19:54 +0900 Subject: [PATCH 58/73] =?UTF-8?q?refactor:=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/httprequest/HttpCookie.java | 10 +++++++++ .../httprequest/HttpRequestConvertor.java | 21 ++++--------------- .../http11/httprequest/HttpRequestLine.java | 11 ++++++++++ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java index c9a4c5aee9..9410adf12b 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java @@ -5,6 +5,8 @@ public class HttpCookie { + private static final String JSESSIONID = "JSESSIONID"; + private final Map cookies; public HttpCookie() { @@ -19,7 +21,15 @@ public boolean containsCookie(String key) { return cookies.containsKey(key); } + public boolean containsSession() { + return containsCookie(JSESSIONID); + } + public String getCookieValue(String key) { return cookies.get(key); } + + public String getSessionId() { + return getCookieValue(JSESSIONID); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 54235956d8..849cc235fb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -13,7 +13,6 @@ public class HttpRequestConvertor { - private static final String JSESSIONID = "JSESSIONID"; private static final String HEADER_DELIMITER = ":"; private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; private static final String BODY_DELIMITER = "&"; @@ -22,13 +21,10 @@ public class HttpRequestConvertor { private static final int TUPLE_KEY_INDEX = 0; private static final int TUPLE_VALUE_INDEX = 1; private static final int HEADER_KEY_INDEX = 0; - private static final String REQUEST_LINE_DELIMITER = " "; - private static final int REQUEST_LINE_MIN_LENGTH = 3; private static final SessionManager SESSION_MANAGER = new SessionManager(); public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); - validateRequestLine(requestLine); HttpRequestLine httpRequestLine = new HttpRequestLine(requestLine); HttpRequestHeader httpRequestHeader = new HttpRequestHeader(getHeaders(bufferedReader)); @@ -42,15 +38,6 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro return new HttpRequest(httpRequestLine, httpRequestHeader, session); } - private static void validateRequestLine(String requestLine) { - if (requestLine == null) { - throw new IllegalArgumentException("요청이 비어 있습니다"); - } - if (requestLine.split(REQUEST_LINE_DELIMITER).length < REQUEST_LINE_MIN_LENGTH) { - throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다"); - } - } - private static Map getHeaders(BufferedReader bufferedReader) throws IOException { String line; Map headers = new HashMap<>(); @@ -81,7 +68,7 @@ private static Session getOrCreateSession(HttpRequestHeader httpRequestHeader) { HttpCookie httpCookie = HttpCookieConvertor.convertHttpCookie( httpRequestHeader.getHeaderValue(HttpHeaderName.COOKIE)); - if (!httpCookie.containsCookie(JSESSIONID)) { + if (!httpCookie.containsSession()) { return createSession(); } @@ -89,11 +76,11 @@ private static Session getOrCreateSession(HttpRequestHeader httpRequestHeader) { } private static Session getOrCreateSession(HttpCookie httpCookie) { - String jsessionid = httpCookie.getCookieValue(JSESSIONID); - if (!SESSION_MANAGER.containsSession(jsessionid)) { + String sessionId = httpCookie.getSessionId(); + if (!SESSION_MANAGER.containsSession(sessionId)) { return createSession(); } - return SESSION_MANAGER.findSession(jsessionid); + return SESSION_MANAGER.findSession(sessionId); } private static Session createSession() { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java index 46d1b7d053..495755a154 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestLine.java @@ -5,6 +5,7 @@ public class HttpRequestLine { private static final String REQUEST_LINE_DELIMITER = " "; + private static final int REQUEST_LINE_MIN_LENGTH = 3; private static final int METHOD_INDEX = 0; private static final int PATH_INDEX = 1; private static final int VERSION_INDEX = 2; @@ -14,12 +15,22 @@ public class HttpRequestLine { private final String version; public HttpRequestLine(String requestLine) { + validateRequestLine(requestLine); String[] headerFirstLine = requestLine.split(REQUEST_LINE_DELIMITER); this.method = HttpMethod.getHttpMethod(headerFirstLine[METHOD_INDEX]); this.path = headerFirstLine[PATH_INDEX]; this.version = headerFirstLine[VERSION_INDEX]; } + private void validateRequestLine(String requestLine) { + if (requestLine == null) { + throw new IllegalArgumentException("요청이 비어 있습니다"); + } + if (requestLine.split(REQUEST_LINE_DELIMITER).length < REQUEST_LINE_MIN_LENGTH) { + throw new IllegalArgumentException("RequestLine이 잘못된 요청입니다"); + } + } + public boolean isMethod(HttpMethod method) { return this.method.isMethod(method); } From 222b4adf7ae4de61229d01f7ccba5baa2ad9ef75 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 20:25:01 +0900 Subject: [PATCH 59/73] =?UTF-8?q?refactor:=20=EC=97=AD=ED=95=A0=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../techcourse/controller/LoginController.java | 13 +++++-------- .../coyote/http11/httpresponse/HttpResponse.java | 5 +++++ .../org/apache/coyote/http11/session/Session.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index 02952eafdc..f74e79039e 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -16,9 +16,6 @@ public class LoginController extends AbstractController { private static final String ACCOUNT = "account"; private static final String PASSWORD = "password"; private static final String INDEX_PATH = "/index.html"; - private static final String JSESSIONID = "JSESSIONID"; - private static final String COOKIE_DELIMITER = "="; - private static final String SESSION_USER_NAME = "user"; @Override protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) { @@ -55,25 +52,25 @@ private void acceptLogin(HttpRequest httpRequest, HttpResponse httpResponse) { private void redirectWithCookie(HttpRequest httpRequest, HttpResponse httpResponse, User user) { Session session = httpRequest.getSession(); - session.setAttribute(SESSION_USER_NAME, user); + session.setUser(user); log.info(user.toString()); httpResponse.found(httpRequest); - httpResponse.setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()); + httpResponse.setSession(session); httpResponse.location(INDEX_PATH); } @Override protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { Session session = httpRequest.getSession(); - if (!session.hasAttribute(SESSION_USER_NAME)) { + if (!session.hasUser()) { httpResponse.ok(httpRequest); httpResponse.staticResource(LOGIN_PATH); return; } - User user = (User) session.getAttribute(SESSION_USER_NAME); + User user = (User) session.getUser(); log.info(user.toString()); httpResponse.found(httpRequest); - httpResponse.setCookie(JSESSIONID + COOKIE_DELIMITER + session.getId()); + httpResponse.setSession(session); httpResponse.location(INDEX_PATH); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index ed27b12eda..e9d3696758 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -10,6 +10,7 @@ import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.exception.NotFoundException; import org.apache.coyote.http11.httprequest.HttpRequest; +import org.apache.coyote.http11.session.Session; public class HttpResponse { @@ -60,6 +61,10 @@ public void setCookie(String cookie) { addHeader(HttpHeaderName.SET_COOKIE, cookie); } + public void setSession(Session session) { + setCookie(session.getId()); + } + public void contentLength(String contentLength) { addHeader(HttpHeaderName.CONTENT_LENGTH, contentLength); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java b/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java index 41d670a193..9054689244 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/session/Session.java @@ -1,10 +1,13 @@ package org.apache.coyote.http11.session; +import com.techcourse.model.User; import java.util.HashMap; import java.util.Map; public class Session { + private static final String SESSION_USER_NAME = "user"; + private final String id; private final Map attributes; @@ -17,14 +20,26 @@ public boolean hasAttribute(String name) { return attributes.containsKey(name); } + public boolean hasUser() { + return hasAttribute(SESSION_USER_NAME); + } + public Object getAttribute(String name) { return attributes.get(name); } + public Object getUser() { + return getAttribute(SESSION_USER_NAME); + } + public void setAttribute(String name, Object value) { attributes.put(name, value); } + public void setUser(User user) { + setAttribute(SESSION_USER_NAME, user); + } + public String getId() { return id; } From c4a0070003f2ba5b803f173cba076826bd7a3d1b Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 20:39:06 +0900 Subject: [PATCH 60/73] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/httprequest/HttpRequestConvertor.java | 8 +++----- .../coyote/http11/httprequest/HttpRequestHeader.java | 6 ++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 849cc235fb..c7eca2cee0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -14,13 +14,12 @@ public class HttpRequestConvertor { private static final String HEADER_DELIMITER = ":"; - private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final int HEADER_KEY_INDEX = 0; private static final String BODY_DELIMITER = "&"; - private static final String TUPLE_DELIMITER = "="; private static final int BODY_TUPLE_MIN_LENGTH = 2; + private static final String TUPLE_DELIMITER = "="; private static final int TUPLE_KEY_INDEX = 0; private static final int TUPLE_VALUE_INDEX = 1; - private static final int HEADER_KEY_INDEX = 0; private static final SessionManager SESSION_MANAGER = new SessionManager(); public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { @@ -113,7 +112,6 @@ private static Map extractBody(String requestBody) { } private static boolean isExistRequestBody(HttpRequestHeader httpRequestHeader) { - return httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) - && httpRequestHeader.getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals(BODY_FORM_CONTENT_TYPE); + return httpRequestHeader.containsHeader(HttpHeaderName.CONTENT_LENGTH) && httpRequestHeader.existRequestBody(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java index 371d0f6d5d..37a9305131 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java @@ -5,6 +5,8 @@ public class HttpRequestHeader { + private static final String BODY_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private final Map headers; public HttpRequestHeader(Map headers) { @@ -19,6 +21,10 @@ public boolean containsHeader(HttpHeaderName httpHeaderName) { return headers.containsKey(httpHeaderName.getName()); } + public boolean existRequestBody() { + return getHeaderValue(HttpHeaderName.CONTENT_LENGTH).equals(BODY_FORM_CONTENT_TYPE); + } + public String getHeaderValue(String key) { return headers.get(key); } From 4ec21d275df52f4531b5e7dc58a099dcc0a02854 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 21:38:33 +0900 Subject: [PATCH 61/73] =?UTF-8?q?fix:=20=EC=84=B8=EC=85=98=EC=9D=B4=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=EC=9D=B4=20=EC=95=88=20=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/httprequest/HttpCookie.java | 2 +- .../apache/coyote/http11/httprequest/HttpRequestHeader.java | 2 +- .../org/apache/coyote/http11/httpresponse/HttpResponse.java | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java index 9410adf12b..00a3253ff0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpCookie.java @@ -5,7 +5,7 @@ public class HttpCookie { - private static final String JSESSIONID = "JSESSIONID"; + public static final String JSESSIONID = "JSESSIONID"; private final Map cookies; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java index 37a9305131..766592af59 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestHeader.java @@ -22,7 +22,7 @@ public boolean containsHeader(HttpHeaderName httpHeaderName) { } public boolean existRequestBody() { - return getHeaderValue(HttpHeaderName.CONTENT_LENGTH).equals(BODY_FORM_CONTENT_TYPE); + return getHeaderValue(HttpHeaderName.CONTENT_TYPE).equals(BODY_FORM_CONTENT_TYPE); } public String getHeaderValue(String key) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index e9d3696758..23f87b7aa9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -9,11 +9,13 @@ import org.apache.coyote.http11.HttpHeaderName; import org.apache.coyote.http11.HttpStatusCode; import org.apache.coyote.http11.exception.NotFoundException; +import org.apache.coyote.http11.httprequest.HttpCookie; import org.apache.coyote.http11.httprequest.HttpRequest; import org.apache.coyote.http11.session.Session; public class HttpResponse { + private static final String COOKIE_TOKEN_DELIMITER = "="; private static final String RESPONSE_LINE_DELIMITER = "\r\n"; private static final String EXTENSION_DELIMITER = "."; private static final String HTML_EXTENSION = ".html"; @@ -62,7 +64,7 @@ public void setCookie(String cookie) { } public void setSession(Session session) { - setCookie(session.getId()); + setCookie(HttpCookie.JSESSIONID + COOKIE_TOKEN_DELIMITER + session.getId()); } public void contentLength(String contentLength) { @@ -122,11 +124,13 @@ public byte[] getBytes() { statusLine, responseHeader, responseBody); + System.out.println(join); return join.getBytes(); } String join = String.join(RESPONSE_LINE_DELIMITER, statusLine, responseHeader); + System.out.println(join); return join.getBytes(); } From 4fc70b66aa684c10dfa74d18cdcbfd11d71c2576 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 21:38:50 +0900 Subject: [PATCH 62/73] =?UTF-8?q?fix:=20SessionManager=20=EC=8B=B1?= =?UTF-8?q?=EA=B8=80=ED=86=A4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/httprequest/HttpRequestConvertor.java | 2 +- .../org/apache/coyote/http11/session/SessionManager.java | 7 +++++++ .../com/techcourse/controller/LoginControllerTest.java | 2 +- .../http11/httprequest/HttpRequestConvertorTest.java | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index c7eca2cee0..654aa445d0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -20,7 +20,7 @@ public class HttpRequestConvertor { private static final String TUPLE_DELIMITER = "="; private static final int TUPLE_KEY_INDEX = 0; private static final int TUPLE_VALUE_INDEX = 1; - private static final SessionManager SESSION_MANAGER = new SessionManager(); + private static final SessionManager SESSION_MANAGER = SessionManager.getInstance(); public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) throws IOException { String requestLine = bufferedReader.readLine(); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java index 41d7ea3068..7d9a6d3820 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java @@ -6,8 +6,15 @@ public class SessionManager implements Manager { + private static final SessionManager INSTANCE = new SessionManager(); private static final Map SESSIONS = new HashMap<>(); + private SessionManager() {} + + public static SessionManager getInstance() { + return INSTANCE; + } + @Override public void add(Session session) { SESSIONS.put(session.getId(), session); diff --git a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java index 816841d7d4..9283175286 100644 --- a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java @@ -134,7 +134,7 @@ void notExistSessionLogin() throws IOException { @DisplayName("쿠키에 유저 정보가 저장된 세션이 있으면 index.html 페이지로 이동한다") @Test void existSessionLogin() { - SessionManager sessionManager = new SessionManager(); + SessionManager sessionManager = SessionManager.getInstance(); Session session = new Session("abcdefg"); sessionManager.add(session); final String login = String.join("\r\n", diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java index c439be3f13..aef78d32eb 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java @@ -76,7 +76,7 @@ void convertHttpRequest() { @DisplayName("SessionManager에 저장된 세션이 쿠키로 들어오면 해당 세션을 불러온다") @Test void loadSession() { - SessionManager sessionManager = new SessionManager(); + SessionManager sessionManager = SessionManager.getInstance(); Session session = new Session("abcdefg"); sessionManager.add(session); String body = "account=gugu&password=1"; From 1b628be94022c2b2d021b333541f58463b7fb4e6 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 21:55:45 +0900 Subject: [PATCH 63/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/http11/Http11Processor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 75eedf6bbe..339f3bf09e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -45,7 +45,7 @@ public void process(final Socket connection) { HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); HttpResponse httpResponse = new HttpResponse(); - getHttpResponse(httpRequest, httpResponse); + handle(httpRequest, httpResponse); outputStream.write(httpResponse.getBytes()); outputStream.flush(); @@ -54,7 +54,7 @@ public void process(final Socket connection) { } } - private void getHttpResponse(HttpRequest httpRequest, HttpResponse httpResponse) { + private void handle(HttpRequest httpRequest, HttpResponse httpResponse) { try { if (isStaticResource(httpRequest)) { httpResponse.ok(httpRequest); From f5a49166972a79cb65f905354d6c8bd8eea48970 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 22:09:52 +0900 Subject: [PATCH 64/73] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginController.java | 9 ++---- .../controller/RegisterController.java | 3 +- .../apache/coyote/http11/Http11Processor.java | 28 +++++++++++-------- .../http11/httpresponse/HttpResponse.java | 3 +- .../http11/httpresponse/HttpResponseTest.java | 3 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index f74e79039e..74538e0e7e 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -28,8 +28,7 @@ protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) { } private void redirectLoginPage(HttpRequest httpRequest, HttpResponse httpResponse) { - httpResponse.found(httpRequest); - httpResponse.location(LOGIN_PATH); + httpResponse.location(httpRequest, LOGIN_PATH); } private boolean validateUserInput(HttpRequest httpRequest) { @@ -54,9 +53,8 @@ private void redirectWithCookie(HttpRequest httpRequest, HttpResponse httpRespon Session session = httpRequest.getSession(); session.setUser(user); log.info(user.toString()); - httpResponse.found(httpRequest); + httpResponse.location(httpRequest, INDEX_PATH); httpResponse.setSession(session); - httpResponse.location(INDEX_PATH); } @Override @@ -69,8 +67,7 @@ protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { } User user = (User) session.getUser(); log.info(user.toString()); - httpResponse.found(httpRequest); + httpResponse.location(httpRequest, INDEX_PATH); httpResponse.setSession(session); - httpResponse.location(INDEX_PATH); } } diff --git a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java index e4a6656d62..b02b87a503 100644 --- a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java +++ b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java @@ -55,7 +55,6 @@ protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) { } private void redirectPage(HttpRequest httpRequest, HttpResponse httpResponse, String path) { - httpResponse.found(httpRequest); - httpResponse.location(path); + httpResponse.location(httpRequest, path); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 339f3bf09e..c2859e8129 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -37,15 +37,12 @@ public void run() { @Override public void process(final Socket connection) { - try ( - final var inputStream = connection.getInputStream(); - final var outputStream = connection.getOutputStream() - ) { + try (final var inputStream = connection.getInputStream(); + final var outputStream = connection.getOutputStream()) { var bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); HttpRequest httpRequest = HttpRequestConvertor.convertHttpRequest(bufferedReader); - HttpResponse httpResponse = new HttpResponse(); - handle(httpRequest, httpResponse); + HttpResponse httpResponse = createResponse(httpRequest); outputStream.write(httpResponse.getBytes()); outputStream.flush(); @@ -54,6 +51,19 @@ public void process(final Socket connection) { } } + private HttpResponse createResponse(HttpRequest httpRequest) { + HttpResponse httpResponse = new HttpResponse(); + try { + handle(httpRequest, httpResponse); + return httpResponse; + } catch (NotFoundException e) { + httpResponse.location(httpRequest, NOT_FOUND_PATH); + } catch (UnauthorizedException e) { + httpResponse.location(httpRequest, UNAUTHORIZED_PATH); + } + return httpResponse; + } + private void handle(HttpRequest httpRequest, HttpResponse httpResponse) { try { if (isStaticResource(httpRequest)) { @@ -65,12 +75,6 @@ private void handle(HttpRequest httpRequest, HttpResponse httpResponse) { Controller controller = requestMapping.getController(httpRequest); controller.service(httpRequest, httpResponse); - } catch (NotFoundException e) { - httpResponse.found(httpRequest); - httpResponse.location(NOT_FOUND_PATH); - } catch (UnauthorizedException e) { - httpResponse.found(httpRequest); - httpResponse.location(UNAUTHORIZED_PATH); } catch (Exception e) { throw new IllegalArgumentException(e); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 23f87b7aa9..3e5da8fb75 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -55,7 +55,8 @@ public void addHeader(HttpHeaderName headerName, String value) { httpResponseHeader.addHeader(headerName, value); } - public void location(String path) { + public void location(HttpRequest httpRequest, String path) { + found(httpRequest); addHeader(HttpHeaderName.LOCATION, path); } diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java index 31a88ca817..3992317b7e 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java @@ -37,8 +37,7 @@ void httpResponseBuilder() { HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); HttpResponse httpResponse = new HttpResponse(); - httpResponse.found(httpRequest); - httpResponse.location("/index"); + httpResponse.location(httpRequest, "/index"); httpResponse.setCookie("JSESSIONID=abcde"); httpResponse.contentLength("89"); httpResponse.contentType("test"); From 84a3721b83e85992f1925de7a73a384a6718ef61 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 22:45:26 +0900 Subject: [PATCH 65/73] =?UTF-8?q?refactor:=20depth=20=EA=B0=84=EC=86=8C?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../httprequest/HttpRequestConvertor.java | 10 +-------- .../httpresponse/HttpResponseHeader.java | 22 ++++--------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 654aa445d0..1c0bd7fb61 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -49,15 +49,7 @@ private static Map getHeaders(BufferedReader bufferedReader) thr } private static String parseHeaderValue(String[] requestLine) { - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < requestLine.length; i++) { - sb.append(requestLine[i].strip()); - if (i != requestLine.length - 1) { - sb.append(HEADER_DELIMITER); - } - } - - return sb.toString(); + return String.join(HEADER_DELIMITER, Arrays.copyOfRange(requestLine, 1, requestLine.length)).strip(); } private static Session getOrCreateSession(HttpRequestHeader httpRequestHeader) { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index 4fce9aeca4..ddbe2d7361 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; import org.apache.coyote.http11.HttpHeaderName; public class HttpResponseHeader { @@ -25,24 +26,9 @@ public void addHeader(HttpHeaderName headerName, String value) { } public String getString() { - StringBuilder stringBuilder = new StringBuilder(); - int size = headers.keySet().size(); - int i = HEADER_VALUE_START_INDEX; - for (HttpHeaderName key : headers.keySet()) { - if (i < size) { - stringBuilder.append(key.getName()) - .append(HEADER_DELIMITER) - .append(headers.get(key)) - .append(RESPONSE_LINE_DELIMITER); - i++; - continue; - } - stringBuilder.append(key.getName()) - .append(HEADER_DELIMITER) - .append(headers.get(key)); - } - - return stringBuilder.toString(); + return headers.keySet().stream() + .map(key -> key.getName() + HEADER_DELIMITER + headers.get(key)) + .collect(Collectors.joining(RESPONSE_LINE_DELIMITER)); } public Map getHeaders() { From 245384ba3834481fa66c425bc3c6ad7ee59f452a Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 12 Sep 2024 22:46:47 +0900 Subject: [PATCH 66/73] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B3=80=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 --- .../coyote/http11/httpresponse/HttpResponseHeader.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index ddbe2d7361..b4e013e572 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -9,14 +9,9 @@ public class HttpResponseHeader { private static final String HEADER_DELIMITER = ": "; private static final String RESPONSE_LINE_DELIMITER = " \r\n"; - private static final int HEADER_VALUE_START_INDEX = 1; private final Map headers; - public HttpResponseHeader(Map headers) { - this.headers = headers; - } - public HttpResponseHeader() { this.headers = new HashMap<>(); } From 99a54b96b3b29b9967ac4299aa362bcd8b221918 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 10:47:03 +0900 Subject: [PATCH 67/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginController.java | 17 ++++----- .../controller/RegisterController.java | 5 +-- .../apache/coyote/http11/Http11Processor.java | 13 ++++--- .../httprequest/HttpRequestConvertor.java | 1 - .../http11/httpresponse/HttpResponse.java | 35 ++++++++----------- .../httpresponse/HttpResponseHeader.java | 2 +- .../http11/httpresponse/HttpStatusLine.java | 2 +- .../controller/LoginControllerTest.java | 8 ++--- .../controller/RegisterControllerTest.java | 8 ++--- .../http11/httpresponse/HttpResponseTest.java | 2 +- 10 files changed, 44 insertions(+), 49 deletions(-) diff --git a/tomcat/src/main/java/com/techcourse/controller/LoginController.java b/tomcat/src/main/java/com/techcourse/controller/LoginController.java index 74538e0e7e..1efa021996 100644 --- a/tomcat/src/main/java/com/techcourse/controller/LoginController.java +++ b/tomcat/src/main/java/com/techcourse/controller/LoginController.java @@ -39,14 +39,15 @@ private void acceptLogin(HttpRequest httpRequest, HttpResponse httpResponse) { String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); - User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(() -> new UnauthorizedException("존재하지 않는 계정입니다")); - if (user.checkPassword(password)) { - redirectWithCookie(httpRequest, httpResponse, user); - return; - } - log.error("비밀번호 불일치"); - throw new UnauthorizedException("존재하지 않는 계정입니다"); + InMemoryUserRepository.findByAccount(account) + .filter(user -> user.checkPassword(password)) + .ifPresentOrElse( + user -> redirectWithCookie(httpRequest, httpResponse, user), + () -> { + log.error("존재하지 않는 계정이거나 비밀번호 불일치"); + throw new UnauthorizedException("존재하지 않는 계정입니다"); + } + ); } private void redirectWithCookie(HttpRequest httpRequest, HttpResponse httpResponse, User user) { diff --git a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java index b02b87a503..acb6eda770 100644 --- a/tomcat/src/main/java/com/techcourse/controller/RegisterController.java +++ b/tomcat/src/main/java/com/techcourse/controller/RegisterController.java @@ -30,15 +30,12 @@ private void acceptRegister(HttpRequest httpRequest, HttpResponse httpResponse) String account = httpRequest.getBodyValue(ACCOUNT); String password = httpRequest.getBodyValue(PASSWORD); String email = httpRequest.getBodyValue(EMAIL); - if (InMemoryUserRepository.containsByAccount(account)) { log.error("이미 존재하는 account입니다"); redirectPage(httpRequest, httpResponse, REGISTER_PATH); return; } - - User user = new User(account, password, email); - InMemoryUserRepository.save(user); + InMemoryUserRepository.save(new User(account, password, email)); redirectPage(httpRequest, httpResponse, INDEX_PATH); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index c2859e8129..e623c76679 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -44,7 +44,7 @@ public void process(final Socket connection) { HttpResponse httpResponse = createResponse(httpRequest); - outputStream.write(httpResponse.getBytes()); + outputStream.write(httpResponse.toResponse()); outputStream.flush(); } catch (IOException | UncheckedServletException e) { log.error(e.getMessage(), e); @@ -71,15 +71,18 @@ private void handle(HttpRequest httpRequest, HttpResponse httpResponse) { httpResponse.staticResource(httpRequest.getPath()); return; } - RequestMapping requestMapping = new RequestMapping(); - Controller controller = requestMapping.getController(httpRequest); - - controller.service(httpRequest, httpResponse); + setHttpResponse(httpRequest, httpResponse); } catch (Exception e) { throw new IllegalArgumentException(e); } } + private static void setHttpResponse(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception { + RequestMapping requestMapping = new RequestMapping(); + Controller controller = requestMapping.getController(httpRequest); + controller.service(httpRequest, httpResponse); + } + private boolean isStaticResource(HttpRequest httpRequest) { return httpRequest.getMethod() == HttpMethod.GET && httpRequest.getPath().contains(CHECKED_STATIC_RESOURCE); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java index 1c0bd7fb61..0d65cb918d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httprequest/HttpRequestConvertor.java @@ -33,7 +33,6 @@ public static HttpRequest convertHttpRequest(BufferedReader bufferedReader) thro HttpRequestBody httpRequestBody = getHttpRequestBody(bufferedReader, httpRequestHeader); return new HttpRequest(httpRequestLine, httpRequestHeader, httpRequestBody, session); } - return new HttpRequest(httpRequestLine, httpRequestHeader, session); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 3e5da8fb75..4e22c7b398 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -82,9 +82,7 @@ public void responseBody(String responseBody) { public void staticResource(String path) { try { - path = settingExtension(path); - String fileName = STATIC_PATH + path; - var resourceUrl = getClass().getClassLoader().getResource(fileName); + URL resourceUrl = getRssourceUrl(path); validateResourceUrl(resourceUrl); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); @@ -96,6 +94,12 @@ public void staticResource(String path) { } } + private URL getRssourceUrl(String path) { + path = settingExtension(path); + String fileName = STATIC_PATH + settingExtension(path); + return getClass().getClassLoader().getResource(fileName); + } + private String settingExtension(String path) { if (!path.contains(EXTENSION_DELIMITER)) { path += HTML_EXTENSION; @@ -114,25 +118,16 @@ private void setHttpHeader(Path filePath, String responseBody) throws IOExceptio contentLength(String.valueOf(responseBody.getBytes().length)); } - public byte[] getBytes() { - String statusLine = httpStatusLine.getString(); - - String responseHeader = httpResponseHeader.getString(); - + public byte[] toResponse() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(httpStatusLine.createStatusLineResponse()) + .append(RESPONSE_LINE_DELIMITER) + .append(httpResponseHeader.createHeadersResponse()); if (httpResponseBody != null) { - String responseBody = httpResponseBody.getBody(); - String join = String.join(RESPONSE_LINE_DELIMITER, - statusLine, - responseHeader, - responseBody); - System.out.println(join); - return join.getBytes(); + stringBuilder.append(RESPONSE_LINE_DELIMITER) + .append(httpResponseBody.getBody()); } - String join = String.join(RESPONSE_LINE_DELIMITER, - statusLine, - responseHeader); - System.out.println(join); - return join.getBytes(); + return stringBuilder.toString().getBytes(); } public HttpStatusLine getHttpStatusLine() { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java index b4e013e572..e97862d0c3 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponseHeader.java @@ -20,7 +20,7 @@ public void addHeader(HttpHeaderName headerName, String value) { headers.put(headerName, value); } - public String getString() { + public String createHeadersResponse() { return headers.keySet().stream() .map(key -> key.getName() + HEADER_DELIMITER + headers.get(key)) .collect(Collectors.joining(RESPONSE_LINE_DELIMITER)); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java index d2a0b7a642..377be4dd53 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpStatusLine.java @@ -14,7 +14,7 @@ public HttpStatusLine(String version, HttpStatusCode httpStatusCode) { this.httpStatusCode = httpStatusCode; } - public String getString() { + public String createStatusLineResponse() { return STATUS_LINE_FORMAT.formatted(version, httpStatusCode.getCode(), httpStatusCode.getMessage()); } diff --git a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java index 9283175286..dbcde0bf20 100644 --- a/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/LoginControllerTest.java @@ -37,7 +37,7 @@ void login() { LoginController loginController = new LoginController(); loginController.doPost(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found ".getBytes()) .contains("Location: /index.html ".getBytes()) .contains(("Set-Cookie: JSESSIONID=" + id + " ").getBytes()); @@ -103,7 +103,7 @@ void notExistUserInput() { HttpResponse httpResponse = new HttpResponse(); loginController.doPost(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found ".getBytes()) .contains("Location: /login".getBytes()); } @@ -124,7 +124,7 @@ void notExistSessionLogin() throws IOException { HttpResponse httpResponse = new HttpResponse(); loginController.doGet(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 200 OK ".getBytes()) .contains("Content-Type: text/html;charset=utf-8 ".getBytes()) .contains(("Content-Length: " + body.getBytes().length + " ").getBytes()) @@ -149,7 +149,7 @@ void existSessionLogin() { HttpResponse httpResponse = new HttpResponse(); loginController.doGet(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 200 OK ".getBytes()) .contains("Location: /login".getBytes()); } diff --git a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java index 7af18b1a49..78f703d005 100644 --- a/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/RegisterControllerTest.java @@ -32,7 +32,7 @@ void register() { RegisterController registerController = new RegisterController(); registerController.doPost(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found ".getBytes()) .contains("Location: /index".getBytes()); } @@ -55,7 +55,7 @@ void notExistUserInput() { RegisterController registerController = new RegisterController(); registerController.doPost(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found ".getBytes()) .contains("Location: /register".getBytes()); } @@ -78,7 +78,7 @@ void existUserRegister() { RegisterController registerController = new RegisterController(); registerController.doPost(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found ".getBytes()) .contains("Location: /register".getBytes()); } @@ -99,7 +99,7 @@ void doGet() throws IOException { RegisterController registerController = new RegisterController(); registerController.doGet(httpRequest, httpResponse); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 200 OK ".getBytes()) .contains("Content-Type: text/html;charset=utf-8 ".getBytes()) .contains(("Content-Length: " + body.getBytes().length + " ").getBytes()) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java index 3992317b7e..f097af5e72 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java @@ -43,7 +43,7 @@ void httpResponseBuilder() { httpResponse.contentType("test"); httpResponse.responseBody("testResponseBody"); - assertThat(httpResponse.getBytes()) + assertThat(httpResponse.toResponse()) .contains("HTTP/1.1 302 Found".getBytes()) .contains("Location: /index".getBytes()) .contains("Set-Cookie: JSESSIONID=abcde".getBytes()) From 05d3356b6ca275c3d3fb0a64ec44efa7e66d9de3 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 10:51:17 +0900 Subject: [PATCH 68/73] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/http11/httpresponse/HttpResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java index 4e22c7b398..f57c27375f 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/httpresponse/HttpResponse.java @@ -82,7 +82,7 @@ public void responseBody(String responseBody) { public void staticResource(String path) { try { - URL resourceUrl = getRssourceUrl(path); + URL resourceUrl = getResourceUrl(path); validateResourceUrl(resourceUrl); Path filePath = Path.of(resourceUrl.toURI()); String responseBody = new String(Files.readAllBytes(filePath)); @@ -94,7 +94,7 @@ public void staticResource(String path) { } } - private URL getRssourceUrl(String path) { + private URL getResourceUrl(String path) { path = settingExtension(path); String fileName = STATIC_PATH + settingExtension(path); return getClass().getClassLoader().getResource(fileName); From dae1388691ef050ec4d4152d42dffac0072fc30e Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 10:54:32 +0900 Subject: [PATCH 69/73] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/UnauthorizedInterceptor.java | 18 -------- .../techcourse/controller/RequestMapping.java | 8 ---- .../config/UnauthorizedInterceptorTest.java | 41 ------------------- 3 files changed, 67 deletions(-) delete mode 100644 tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java delete mode 100644 tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java diff --git a/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java b/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java deleted file mode 100644 index 55060a3046..0000000000 --- a/tomcat/src/main/java/com/techcourse/config/UnauthorizedInterceptor.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.techcourse.config; - -import java.util.Set; -import org.apache.coyote.http11.HttpHeaderName; -import org.apache.coyote.http11.httprequest.HttpRequest; - -public class UnauthorizedInterceptor { - - private final Set unauthorizedPaths; - - public UnauthorizedInterceptor() { - unauthorizedPaths = Set.of("/401", "/404", "/500", "/401.html", "/404.html", "/500.html"); - } - - public boolean isInterceptPath(HttpRequest httpRequest) { - return !httpRequest.containsHeader(HttpHeaderName.LOCATION) && unauthorizedPaths.contains(httpRequest.getPath()); - } -} diff --git a/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java index 26d2d9caa8..4f21da64cb 100644 --- a/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java +++ b/tomcat/src/main/java/com/techcourse/controller/RequestMapping.java @@ -2,27 +2,19 @@ import java.util.HashMap; import java.util.Map; -import com.techcourse.config.UnauthorizedInterceptor; import org.apache.coyote.http11.exception.NotFoundException; -import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; public class RequestMapping { private final Map controllers = new HashMap<>(); - private final UnauthorizedInterceptor unauthorizedInterceptor; public RequestMapping() { - this.unauthorizedInterceptor = new UnauthorizedInterceptor(); controllers.put("/login", new LoginController()); controllers.put("/register", new RegisterController()); } public Controller getController(HttpRequest httpRequest) { - if (unauthorizedInterceptor.isInterceptPath(httpRequest)) { - throw new UnauthorizedException("권한이 없는 페이지로의 접근입니다"); - } - String path = httpRequest.getPath(); if (controllers.containsKey(path)) { return controllers.get(path); diff --git a/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java b/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java deleted file mode 100644 index 943bef1aad..0000000000 --- a/tomcat/src/test/java/com/techcourse/config/UnauthorizedInterceptorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.techcourse.config; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.coyote.http11.httprequest.HttpRequest; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import support.HttpRequestMaker; - -class UnauthorizedInterceptorTest { - - @DisplayName("해당 path가 Unauthorized인 Path이면 true를 반환한다") - @Test - void isInterceptPath() { - final String interceptPath = String.join("\r\n", - "GET /401 HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - ""); - HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(interceptPath); - - UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); - - assertThat(unauthorizedInterceptor.isInterceptPath(httpRequest)).isTrue(); - } - - @DisplayName("해당 path가 Unauthorized인 Path가 아니면 false를 반환한다") - @Test - void isNotInterceptPath() { - final String notInterceptPath = String.join("\r\n", - "GET /index.html HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - ""); - HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(notInterceptPath); - - UnauthorizedInterceptor unauthorizedInterceptor = new UnauthorizedInterceptor(); - - assertThat(unauthorizedInterceptor.isInterceptPath(httpRequest)).isFalse(); - } -} From 99c5f8ebee154608e052c1b92e3fc739cc400f93 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 10:58:44 +0900 Subject: [PATCH 70/73] =?UTF-8?q?refactor:=20Concurrent=20Collections?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http11/session/SessionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java index 7d9a6d3820..d196714211 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/session/SessionManager.java @@ -1,13 +1,13 @@ package org.apache.coyote.http11.session; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.catalina.Manager; public class SessionManager implements Manager { private static final SessionManager INSTANCE = new SessionManager(); - private static final Map SESSIONS = new HashMap<>(); + private static final Map SESSIONS = new ConcurrentHashMap<>(); private SessionManager() {} From 459958dcdce6583697db906105e79ed11a0979fd Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 11:02:43 +0900 Subject: [PATCH 71/73] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RequestMappingTest.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java index efb2d3d18c..bc6cdaba73 100644 --- a/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java +++ b/tomcat/src/test/java/com/techcourse/controller/RequestMappingTest.java @@ -4,7 +4,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.apache.coyote.http11.exception.NotFoundException; -import org.apache.coyote.http11.exception.UnauthorizedException; import org.apache.coyote.http11.httprequest.HttpRequest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -44,20 +43,4 @@ void notExistPath() { assertThatThrownBy(() -> requestMapping.getController(httpRequest)) .isInstanceOf(NotFoundException.class); } - - @DisplayName("권한이 없는 페이지로 접근할 경우 예외를 발생시킨다") - @Test - void unauthorizedPath() { - final String request = String.join("\r\n", - "GET /500 HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - ""); - HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); - - RequestMapping requestMapping = new RequestMapping(); - - assertThatThrownBy(() -> requestMapping.getController(httpRequest)) - .isInstanceOf(UnauthorizedException.class); - } } From 3037360a3264392fe33e2651d00da7841f859817 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 11:04:56 +0900 Subject: [PATCH 72/73] =?UTF-8?q?test:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=B3=80=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 --- .../org/apache/coyote/http11/httpresponse/HttpResponseTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java index f097af5e72..ee538c0bcd 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httpresponse/HttpResponseTest.java @@ -19,7 +19,6 @@ void invalidPath() { "Host: localhost:8080 ", "Connection: keep-alive ", ""); - HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); HttpResponse httpResponse = new HttpResponse(); assertThatThrownBy(() -> httpResponse.staticResource("/ln")) From 9e8ea4dc6c76fe2f457219defb0f7e1b95e85e92 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Fri, 13 Sep 2024 11:18:50 +0900 Subject: [PATCH 73/73] =?UTF-8?q?test:=20RequestBody=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../httprequest/HttpRequestConvertorTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java index aef78d32eb..10671335d4 100644 --- a/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java +++ b/tomcat/src/test/java/org/apache/coyote/http11/httprequest/HttpRequestConvertorTest.java @@ -73,6 +73,26 @@ void convertHttpRequest() { ); } + @DisplayName("들어온 요청에 RequestBody가 없을 경우 RequestBody를 생성하지 않는다") + @Test + void notExistRequestBody() { + final String request = String.join("\r\n", + "GET /login HTTP/1.1 ", + "Host: localhost:8080 ", + "Connection: keep-alive ", + ""); + HttpRequest httpRequest = HttpRequestMaker.makeHttpRequest(request); + + assertAll( + () -> assertThat(httpRequest.getMethod()).isEqualTo(HttpMethod.GET), + () -> assertThat(httpRequest.getPath()).isEqualTo("/login"), + () -> assertThat(httpRequest.getVersion()).isEqualTo("HTTP/1.1"), + () -> assertThat(httpRequest.getHeaderValue("Host")).isEqualTo("localhost:8080"), + () -> assertThat(httpRequest.getHeaderValue("Connection")).isEqualTo("keep-alive"), + () -> assertThat(httpRequest.getHttpRequestBody()).isNull() + ); + } + @DisplayName("SessionManager에 저장된 세션이 쿠키로 들어오면 해당 세션을 불러온다") @Test void loadSession() {