From 7ecee39a1fa121d3ee45ee26292192134a954ae4 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 09:44:51 +0900 Subject: [PATCH 01/21] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EC=9A=94?= =?UTF-8?q?=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 9d01d7c0d1..64fcfddec6 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,14 @@ - [x] Login 도 POST 로 변경 - [x] Cookie에 JSESSIONID 값 저장하기 - [x] Session 구현하기 + +### 3단계 - 리팩터링 + +- [x] HttpRequest 클래스 구현하기 +- [x] HttpResponse 클래스 구현하기 +- [ ] Controller 인터페이스 추가하기 + +### 4단계 - 동시성 확장하기 + +- [ ] Executors로 Thread Pool 적용 +- [ ] 동시성 컬렉션 사용하기 From 61384c056550456284146cd1549f0bd6915a1331 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 22:00:44 +0900 Subject: [PATCH 02/21] =?UTF-8?q?refactor:=20ContentType=20svg=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 --- .../src/main/java/org/apache/coyote/common/ContentType.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/common/ContentType.java b/tomcat/src/main/java/org/apache/coyote/common/ContentType.java index 0745b2c857..d1875eb861 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/ContentType.java +++ b/tomcat/src/main/java/org/apache/coyote/common/ContentType.java @@ -6,7 +6,8 @@ public enum ContentType { HTML("html", "text/html"), CSS("css", "text/css"), JAVASCRIPT("js", "text/javascript"), - FAVICON("ico", "image/x-icon"); + FAVICON("ico", "image/x-icon"), + SVG("svg", "image/svg+xml"); private final String extension; private final String type; @@ -18,7 +19,7 @@ public enum ContentType { public static ContentType from(String extension) { return Arrays.stream(values()) - .filter(it -> it.getExtension().equals(extension)) + .filter(contentType -> contentType.getExtension().equals(extension)) .findFirst() .orElse(HTML); } From 77070f7cb9801a72352d7f4f776900d0955b2765 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 22:01:21 +0900 Subject: [PATCH 03/21] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=20=EC=83=81=EC=88=98=ED=99=94.=20java=20convention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/common/HttpCookie.java | 29 ++++++++++++------- .../coyote/request/HttpRequestBody.java | 1 + .../coyote/request/HttpRequestLine.java | 12 ++++++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java index 9910d8f67f..ec3ec0b67f 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java @@ -8,6 +8,9 @@ public class HttpCookie { + private static final String KEY_VALUE_SEPERATOR = "="; + private static final String COOKIE_SEPERATOR = "; "; + private final Map cookie; public HttpCookie(Map cookie) { @@ -18,20 +21,24 @@ public static HttpCookie of(String cookieString) { Map cookies = new LinkedHashMap<>(); if (StringUtils.isNotBlank(cookieString)) { - String[] cookiePairs = cookieString.split("; "); - for (String cookiePair : cookiePairs) { - String[] parts = cookiePair.split("="); - if (parts.length == 2) { - String name = parts[0]; - String value = parts[1]; - cookies.put(name, value); - } - } + String[] cookiePairs = cookieString.split(COOKIE_SEPERATOR); + generateCookie(cookies, cookiePairs); } return new HttpCookie(cookies); } + private static void generateCookie(Map cookies, String[] cookiePairs) { + for (String cookiePair : cookiePairs) { + String[] parts = cookiePair.split(KEY_VALUE_SEPERATOR); + if (parts.length == 2) { + String name = parts[0]; + String value = parts[1]; + cookies.put(name, value); + } + } + } + public String getValue(String key) { return cookie.get(key); } @@ -39,8 +46,8 @@ public String getValue(String key) { public String convertToHeader() { return cookie.entrySet() .stream() - .map(entry -> entry.getKey() + "=" + entry.getValue()) - .collect(Collectors.joining("; ")); + .map(entry -> entry.getKey() + KEY_VALUE_SEPERATOR + entry.getValue()) + .collect(Collectors.joining(COOKIE_SEPERATOR)); } @Override diff --git a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestBody.java b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestBody.java index 52f6c109c3..c45d7a6f50 100644 --- a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestBody.java +++ b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestBody.java @@ -7,6 +7,7 @@ public class HttpRequestBody { private static final String BODY_SEPERATOR = "="; private static final String SEPERATOR = "&"; + private final Map body; private HttpRequestBody(Map body) { diff --git a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestLine.java b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestLine.java index 73e65d503f..1d941920a9 100644 --- a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestLine.java @@ -3,7 +3,12 @@ public class HttpRequestLine { + private static final String GET = "GET"; + private static final String POST = "POST"; private static final String SEPERATOR = " "; + private static final int METHOD_INDEX = 0; + private static final int REQUEST_URI_INDEX = 1; + private static final int VERSION_INDEX = 2; private final String method; private final RequestUri requestUri; @@ -18,7 +23,8 @@ public HttpRequestLine(String method, RequestUri requestUri, String version) { public static HttpRequestLine from(String requestLine) { String[] splitedLines = requestLine.split(SEPERATOR); - return new HttpRequestLine(splitedLines[0], RequestUri.from(splitedLines[1]), splitedLines[2]); + return new HttpRequestLine(splitedLines[METHOD_INDEX], + RequestUri.from(splitedLines[REQUEST_URI_INDEX]), splitedLines[VERSION_INDEX]); } public RequestUri getRequestUri() { @@ -26,10 +32,10 @@ public RequestUri getRequestUri() { } public boolean isGetMethod() { - return method.equals("GET"); + return method.equals(GET); } public boolean isPostMethod() { - return method.equals("POST"); + return method.equals(POST); } } From 82e3e5ca6674149e188d9bfc6f36c7663360e6f4 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 22:01:34 +0900 Subject: [PATCH 04/21] =?UTF-8?q?refactor:=20HttpStatus=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 --- .../src/main/java/org/apache/coyote/response/HttpStatus.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpStatus.java b/tomcat/src/main/java/org/apache/coyote/response/HttpStatus.java index 38ab9c26e1..d59ed6aa30 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpStatus.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpStatus.java @@ -4,7 +4,9 @@ public enum HttpStatus { OK(200), FOUND(302), - UNAUTHORIZED(401); + UNAUTHORIZED(401), + NOT_FOUND(404), + INTERNAL_SERVER_ERROR(500); private final int code; From c0f964bd3b51d1a7f476c3718f8764395ef5f48c Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 22:01:59 +0900 Subject: [PATCH 05/21] =?UTF-8?q?feat:=20=EC=A0=95=EC=A0=81=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=AA=BB=20=EC=9D=BD=EC=96=B4=EC=98=AC=EB=95=8C=20?= =?UTF-8?q?404=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EB=A6=AC=ED=84=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/utils/FileUtils.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java index 377fee426d..c050cb7ad3 100644 --- a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java +++ b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java @@ -1,6 +1,7 @@ package org.apache.coyote.utils; import java.io.IOException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; @@ -8,9 +9,23 @@ public class FileUtils { private static final String STATIC_DIRECTORY = "static"; + private static final String NOT_FOUND_PAGE = "/404.html"; public static String readFile(String path) throws IOException { - final Path filePath = Path.of(Objects.requireNonNull(FileUtils.class.getClassLoader().getResource(STATIC_DIRECTORY + path)).getPath()); + Path filePath = null; + try { + URL resource = FileUtils.class + .getClassLoader() + .getResource(STATIC_DIRECTORY + path); + + filePath = Path.of(resource.getPath()); + } catch (NullPointerException e) { + URL resource = Objects.requireNonNull(FileUtils.class + .getClassLoader() + .getResource(STATIC_DIRECTORY + NOT_FOUND_PAGE)); + + filePath = Path.of(resource.getPath()); + } return new String(Files.readAllBytes(filePath)); } From 434ad4b2d065fc20a27163ae9394e4593b73f53e Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 23:32:26 +0900 Subject: [PATCH 06/21] =?UTF-8?q?feat:=20controller=20interface=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/AbstractController.java | 27 +++++++++++++++++++ .../java/org/apache/coyote/Controller.java | 8 ++++++ 2 files changed, 35 insertions(+) create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/Controller.java diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java new file mode 100644 index 0000000000..20b01e8adc --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -0,0 +1,27 @@ +package nextstep.jwp.controller; + +import org.apache.coyote.Controller; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AbstractController implements Controller { + + protected static final Logger log = LoggerFactory.getLogger(AbstractController.class); + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + if (request.getRequestLine().isGetMethod()) { + doGet(request, response); + return; + } + if (request.getRequestLine().isPostMethod()) { + doPost(request, response); + } + } + + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } + + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } +} diff --git a/tomcat/src/main/java/org/apache/coyote/Controller.java b/tomcat/src/main/java/org/apache/coyote/Controller.java new file mode 100644 index 0000000000..140c89eb96 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/Controller.java @@ -0,0 +1,8 @@ +package org.apache.coyote; + +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public interface Controller { + void service(HttpRequest request, HttpResponse response) throws Exception; +} From 61b1b2958539db6c52ab18e7d36f13f83eb93ee6 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 23:35:51 +0900 Subject: [PATCH 07/21] =?UTF-8?q?feat:=20uri=20=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/DefaultController.java | 20 ++++ .../jwp/controller/LoginController.java | 91 +++++++++++++++++++ .../jwp/controller/RegisterController.java | 47 ++++++++++ .../jwp/controller/RootController.java | 15 +++ 4 files changed, 173 insertions(+) create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/LoginController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/RootController.java diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java new file mode 100644 index 0000000000..8c0e7fc207 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -0,0 +1,20 @@ +package nextstep.jwp.controller; + +import org.apache.coyote.common.ContentType; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.request.RequestUri; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.utils.FileUtils; + +public class DefaultController extends AbstractController { + + @Override + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + RequestUri requestUri = request.getRequestLine().getRequestUri(); + + response = new HttpResponse.Builder() + .contentType(ContentType.from(requestUri.getExtension())) + .body(FileUtils.readFile(requestUri.getPath())) + .build(); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java new file mode 100644 index 0000000000..41395e389f --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -0,0 +1,91 @@ +package nextstep.jwp.controller; + +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.User; +import org.apache.catalina.manager.SessionManager; +import org.apache.coyote.common.HttpCookie; +import org.apache.coyote.common.Session; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.request.HttpRequestBody; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.utils.FileUtils; + +import java.util.Optional; + +import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.response.HttpStatus.FOUND; +import static org.apache.coyote.response.HttpStatus.OK; + +public class LoginController extends AbstractController { + + @Override + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { + HttpRequestBody httpRequestBody = request.getRequestBody(); + String account = httpRequestBody.getValue("account"); + String password = httpRequestBody.getValue("password"); + + Optional user = InMemoryUserRepository.findByAccount(account); + + if (user.isPresent() && user.get().checkPassword(password)) { + log.info(user.toString()); + + response = loginSuccess(user); + + } else if (user.isPresent()) { + log.warn("비밀번호가 틀렸습니다"); + + response = loginFail(); + + } else { + log.warn("미가입회원입니다"); + + response = loginFail(); + } + } + + private HttpResponse loginSuccess(Optional user) { + Session session = new Session(); + session.setAttribute("user", user); + SessionManager.add(session); + + HttpCookie cookie = HttpCookie.of("JSESSIONID=" + session.getId()); + + return new HttpResponse.Builder() + .status(FOUND) + .contentType(HTML) + .header("Location", "/index.html") + .setCookie(cookie) + .build(); + } + + private HttpResponse loginFail() { + return new HttpResponse.Builder() + .status(FOUND) + .contentType(HTML) + .header("Location", "/401.html") + .build(); + } + + + @Override + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + HttpCookie cookie = request.getRequestHeader().getCookie(); + + String jsessionid = cookie.getValue("JSESSIONID"); + Session session = SessionManager.findSession(jsessionid); + + if (session != null) { + response = new HttpResponse.Builder() + .status(FOUND) + .header("Location", "/index.html") + .contentType(HTML) + .build(); + } + + response = new HttpResponse.Builder() + .status(OK) + .contentType(HTML) + .body(FileUtils.readFile("/login.html")) + .build(); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java new file mode 100644 index 0000000000..446cc78c12 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -0,0 +1,47 @@ +package nextstep.jwp.controller; + +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.User; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.request.HttpRequestBody; +import org.apache.coyote.request.RequestUri; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.utils.FileUtils; + +import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.response.HttpStatus.FOUND; + +public class RegisterController extends AbstractController { + + @Override + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { + HttpRequestBody httpRequestBody = request.getRequestBody(); + + String account = httpRequestBody.getValue("account"); + String password = httpRequestBody.getValue("password"); + String email = httpRequestBody.getValue("email"); + + if (InMemoryUserRepository.findByAccount(account).isPresent()) { + throw new IllegalArgumentException("중복 ID 입니다"); + } + + InMemoryUserRepository.save(new User(account, password, email)); + + response = new HttpResponse.Builder() + .status(FOUND) + .contentType(HTML) + .header("Location", "/index.html") + .build(); + } + + @Override + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + RequestUri requestUri = request.getRequestLine().getRequestUri(); + + response = new HttpResponse.Builder() + .contentType(ContentType.from(requestUri.getExtension())) + .body(FileUtils.readFile("/register.html")) + .build(); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RootController.java b/tomcat/src/main/java/nextstep/jwp/controller/RootController.java new file mode 100644 index 0000000000..166132d038 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/RootController.java @@ -0,0 +1,15 @@ +package nextstep.jwp.controller; + +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +import static org.apache.coyote.common.ContentType.HTML; + +public class RootController extends AbstractController { + + @Override + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + response.setContentType(HTML); + response.setBody("Hello world!"); + } +} From 7f7ece7e7828c5efb5e2cfc460ab3f026f4aa983 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 23:36:11 +0900 Subject: [PATCH 08/21] =?UTF-8?q?feat:=20RequestMapping=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A1=9C=20=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=9C=84=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/RequestMapping.java | 27 ++++ .../apache/coyote/http11/Http11Processor.java | 147 ++---------------- 2 files changed, 40 insertions(+), 134 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/RequestMapping.java diff --git a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java new file mode 100644 index 0000000000..0ffa3a3315 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java @@ -0,0 +1,27 @@ +package org.apache.coyote; + +import nextstep.jwp.controller.DefaultController; +import nextstep.jwp.controller.LoginController; +import nextstep.jwp.controller.RegisterController; +import nextstep.jwp.controller.RootController; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.request.RequestUri; + +public class RequestMapping { + + public Controller getController(HttpRequest request) { + RequestUri requestUri = request.getRequestLine().getRequestUri(); + + String path = requestUri.getPath(); + if (path.equals("/")) { + return new RootController(); + } + if (path.equals("/login")) { + return new LoginController(); + } + if (path.equals("/register")) { + return new RegisterController(); + } + return new DefaultController(); + } +} 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 7bd72c524d..6fbe73b0ef 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,17 +1,14 @@ package org.apache.coyote.http11; -import nextstep.jwp.db.InMemoryUserRepository; -import nextstep.jwp.exception.UncheckedServletException; -import nextstep.jwp.model.User; -import org.apache.catalina.manager.SessionManager; +import org.apache.coyote.Controller; import org.apache.coyote.Processor; -import org.apache.coyote.common.ContentType; -import org.apache.coyote.common.HttpCookie; -import org.apache.coyote.common.Session; -import org.apache.coyote.request.*; +import org.apache.coyote.RequestMapping; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.request.HttpRequestBody; +import org.apache.coyote.request.HttpRequestHeader; +import org.apache.coyote.request.HttpRequestLine; import org.apache.coyote.response.HttpResponse; -import org.apache.coyote.utils.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,11 +18,6 @@ import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Objects; -import java.util.Optional; - -import static org.apache.coyote.common.ContentType.HTML; -import static org.apache.coyote.response.HttpStatus.FOUND; -import static org.apache.coyote.response.HttpStatus.OK; public class Http11Processor implements Runnable, Processor { @@ -49,42 +41,17 @@ public void process(final Socket connection) { final var outputStream = connection.getOutputStream(); final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { - HttpRequest httpRequest = generateHttpRequest(reader); - - RequestUri requestUri = httpRequest.getRequestLine().getRequestUri(); - - String path = requestUri.getPath(); - - HttpResponse response = null; - - if (path.equals("/")) { - response = new HttpResponse.Builder() - .contentType(HTML) - .body("Hello world!") - .build(); - } else if (path.equals("/login") && httpRequest.getRequestLine().isGetMethod()) { - response = getLoginHttpResponse(httpRequest); - } else if (path.equals("/login") && httpRequest.getRequestLine().isPostMethod()) { - response = postLoginHttpResponse(httpRequest); - } else if (path.equals("/register") && httpRequest.getRequestLine().isGetMethod()) { - response = new HttpResponse.Builder() - .contentType(ContentType.from(requestUri.getExtension())) - .body(FileUtils.readFile("/register.html")) - .build(); - } else if (path.equals("/register") && httpRequest.getRequestLine().isPostMethod()) { - response = postRegisterHttpResponse(httpRequest); - } else { - response = new HttpResponse.Builder() - .contentType(ContentType.from(requestUri.getExtension())) - .body(FileUtils.readFile(requestUri.getPath())) - .build(); - } + HttpRequest request = generateHttpRequest(reader); + + HttpResponse response = HttpResponse.createDefaultResponse(); + Controller controller = new RequestMapping().getController(request); + + controller.service(request, response); outputStream.write(response.getResponse().getBytes()); outputStream.flush(); - } catch (IOException | - UncheckedServletException e) { + } catch (Exception e) { log.error(e.getMessage(), e); } } @@ -122,92 +89,4 @@ private HttpRequestHeader getRequestHeader(BufferedReader reader) throws IOExcep return HttpRequestHeader.from(requestHeader.toString()); } - - private HttpResponse getLoginHttpResponse(HttpRequest httpRequest) throws IOException { - HttpCookie cookie = httpRequest.getRequestHeader().getCookie(); - - String jsessionid = cookie.getValue("JSESSIONID"); - Session session = SessionManager.findSession(jsessionid); - - if (session != null) { - return new HttpResponse.Builder() - .status(FOUND) - .header("Location", "/index.html") - .contentType(HTML) - .build(); - } - - return new HttpResponse.Builder() - .status(OK) - .contentType(HTML) - .body(FileUtils.readFile("/login.html")) - .build(); - } - - private HttpResponse postLoginHttpResponse(HttpRequest httpRequest) { - HttpRequestBody httpRequestBody = httpRequest.getRequestBody(); - String account = httpRequestBody.getValue("account"); - String password = httpRequestBody.getValue("password"); - - Optional user = InMemoryUserRepository.findByAccount(account); - - if (user.isPresent() && user.get().checkPassword(password)) { - log.info(user.toString()); - - return loginSuccess(user); - - } else if (user.isPresent()) { - log.warn("비밀번호가 틀렸습니다"); - - return loginFail(); - - } else { - log.warn("미가입회원입니다"); - - return loginFail(); - } - } - - private HttpResponse loginSuccess(Optional user) { - Session session = new Session(); - session.setAttribute("user", user); - SessionManager.add(session); - - HttpCookie cookie = HttpCookie.of("JSESSIONID=" + session.getId()); - - return new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/index.html") - .setCookie(cookie) - .build(); - } - - private HttpResponse loginFail() { - return new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/401.html") - .build(); - } - - private HttpResponse postRegisterHttpResponse(HttpRequest httpRequest) { - HttpRequestBody httpRequestBody = httpRequest.getRequestBody(); - - String account = httpRequestBody.getValue("account"); - String password = httpRequestBody.getValue("password"); - String email = httpRequestBody.getValue("email"); - - if (InMemoryUserRepository.findByAccount(account).isPresent()) { - throw new IllegalArgumentException("중복 ID 입니다"); - } - - InMemoryUserRepository.save(new User(account, password, email)); - - return new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/index.html") - .build(); - } } From d727cb43d7eeb910f83b152792ce69f1750f3b22 Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 23:36:31 +0900 Subject: [PATCH 09/21] =?UTF-8?q?feat:=20HttpResponse=20=EC=A0=95=EC=A0=81?= =?UTF-8?q?=ED=8C=A9=ED=84=B0=EB=A6=AC=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/response/HttpResponse.java | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index 416617a2f7..d66c8fe3fb 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -8,9 +8,27 @@ public class HttpResponse { + private static final String DEFAULT_VERSION = "HTTP/1.1"; + private final StatusLine statusLine; private final HttpResponseHeader headers; - private final String body; + + private String body; + + private HttpResponse(StatusLine statusLine, HttpResponseHeader headers, String body) { + this.statusLine = statusLine; + this.headers = headers; + this.body = body; + } + + public static HttpResponse createDefaultResponse() { + String version = DEFAULT_VERSION; + HttpStatus httpStatus = HttpStatus.OK; + Map headers = new LinkedHashMap<>(); + String body = ""; + + return new HttpResponse(new StatusLine(version, httpStatus), new HttpResponseHeader(headers), body); + } private HttpResponse(Builder builder) { this.statusLine = new StatusLine(builder.version, builder.httpStatus); @@ -18,10 +36,19 @@ private HttpResponse(Builder builder) { this.body = builder.body; } + public String getResponse() { return statusLine.getStatusLine() + "\r\n" + headers.getResponseHeader() + "\r\n" + body; } + public void setContentType(ContentType contentType) { + this.headers.add("Content-Type", contentType.getType() + ";charset=utf-8"); + } + + public void setBody(String body) { + this.body = body; + } + public static class Builder { private final String version; private final Map headers; @@ -29,7 +56,7 @@ public static class Builder { private String body; public Builder() { - this.version = "HTTP/1.1"; + this.version = DEFAULT_VERSION; this.httpStatus = HttpStatus.OK; this.headers = new LinkedHashMap<>(); this.body = ""; From 2447158db020c6fb73277d4fbbb33b951e25d64c Mon Sep 17 00:00:00 2001 From: yenawee Date: Sun, 10 Sep 2023 23:49:51 +0900 Subject: [PATCH 10/21] =?UTF-8?q?feat:=20HttpResponse=20=EB=B9=8C=EB=8D=94?= =?UTF-8?q?=ED=8C=A8=ED=84=B4=20=EC=82=AD=EC=A0=9C.=20setter=20=EB=A1=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/DefaultController.java | 6 +- .../jwp/controller/LoginController.java | 45 +++++++-------- .../jwp/controller/RegisterController.java | 14 ++--- .../apache/coyote/response/HttpResponse.java | 55 +++---------------- .../apache/coyote/response/StatusLine.java | 8 ++- .../coyote/http11/Http11ProcessorTest.java | 12 ++-- 6 files changed, 45 insertions(+), 95 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java index 8c0e7fc207..9ac81c0f00 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -12,9 +12,7 @@ public class DefaultController extends AbstractController { protected void doGet(HttpRequest request, HttpResponse response) throws Exception { RequestUri requestUri = request.getRequestLine().getRequestUri(); - response = new HttpResponse.Builder() - .contentType(ContentType.from(requestUri.getExtension())) - .body(FileUtils.readFile(requestUri.getPath())) - .build(); + response.setContentType(ContentType.from(requestUri.getExtension())); + response.setBody(FileUtils.readFile(requestUri.getPath())); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 41395e389f..e39c3432c5 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -29,41 +29,37 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti if (user.isPresent() && user.get().checkPassword(password)) { log.info(user.toString()); - response = loginSuccess(user); + loginSuccess(user, response); } else if (user.isPresent()) { log.warn("비밀번호가 틀렸습니다"); - response = loginFail(); + loginFail(response); } else { log.warn("미가입회원입니다"); - response = loginFail(); + loginFail(response); } } - private HttpResponse loginSuccess(Optional user) { + private void loginSuccess(Optional user, HttpResponse response) { Session session = new Session(); session.setAttribute("user", user); SessionManager.add(session); HttpCookie cookie = HttpCookie.of("JSESSIONID=" + session.getId()); - return new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/index.html") - .setCookie(cookie) - .build(); + response.setStatus(FOUND); + response.setContentType(HTML); + response.addHeader("Location", "/index.html"); + response.setCookie(cookie); } - private HttpResponse loginFail() { - return new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/401.html") - .build(); + private void loginFail(HttpResponse response) { + response.setStatus(FOUND); + response.setContentType(HTML); + response.addHeader("Location", "/401.html"); } @@ -75,17 +71,14 @@ protected void doGet(HttpRequest request, HttpResponse response) throws Exceptio Session session = SessionManager.findSession(jsessionid); if (session != null) { - response = new HttpResponse.Builder() - .status(FOUND) - .header("Location", "/index.html") - .contentType(HTML) - .build(); + response.setStatus(FOUND); + response.addHeader("Location", "/index.html"); + response.setContentType(HTML); + return; } - response = new HttpResponse.Builder() - .status(OK) - .contentType(HTML) - .body(FileUtils.readFile("/login.html")) - .build(); + response.setStatus(OK); + response.setContentType(HTML); + response.setBody(FileUtils.readFile("/login.html")); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index 446cc78c12..ba6055b293 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -28,20 +28,16 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti InMemoryUserRepository.save(new User(account, password, email)); - response = new HttpResponse.Builder() - .status(FOUND) - .contentType(HTML) - .header("Location", "/index.html") - .build(); + response.setStatus(FOUND); + response.setContentType(HTML); + response.addHeader("Location", "/index.html"); } @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { RequestUri requestUri = request.getRequestLine().getRequestUri(); - response = new HttpResponse.Builder() - .contentType(ContentType.from(requestUri.getExtension())) - .body(FileUtils.readFile("/register.html")) - .build(); + response.setContentType(ContentType.from(requestUri.getExtension())); + response.setBody(FileUtils.readFile("/register.html")); } } diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index d66c8fe3fb..c56a8b8f2d 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -30,13 +30,6 @@ public static HttpResponse createDefaultResponse() { return new HttpResponse(new StatusLine(version, httpStatus), new HttpResponseHeader(headers), body); } - private HttpResponse(Builder builder) { - this.statusLine = new StatusLine(builder.version, builder.httpStatus); - this.headers = new HttpResponseHeader(builder.headers); - this.body = builder.body; - } - - public String getResponse() { return statusLine.getStatusLine() + "\r\n" + headers.getResponseHeader() + "\r\n" + body; } @@ -49,47 +42,15 @@ public void setBody(String body) { this.body = body; } - public static class Builder { - private final String version; - private final Map headers; - private HttpStatus httpStatus; - private String body; - - public Builder() { - this.version = DEFAULT_VERSION; - this.httpStatus = HttpStatus.OK; - this.headers = new LinkedHashMap<>(); - this.body = ""; - } - - public Builder header(String key, String value) { - this.headers.put(key, value); - return this; - } - - public Builder status(HttpStatus httpStatus) { - this.httpStatus = httpStatus; - return this; - } - - public Builder contentType(ContentType contentType) { - this.headers.put("Content-Type", contentType.getType() + ";charset=utf-8"); - return this; - } - - public Builder setCookie(HttpCookie cookie) { - this.headers.put("Set-Cookie", cookie.convertToHeader()); - return this; - } + public void setStatus(HttpStatus status) { + this.statusLine.setStatus(status); + } - public Builder body(String body) { - this.headers.put("Content-Length", String.valueOf(body.getBytes().length)); - this.body = body; - return this; - } + public void addHeader(String key, String value) { + this.headers.add(key, value); + } - public HttpResponse build() { - return new HttpResponse(this); - } + public void setCookie(HttpCookie cookie) { + this.headers.add("Set-Cookie", cookie.convertToHeader()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java b/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java index dfa2528ca0..430f96f1c3 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java @@ -4,8 +4,8 @@ public class StatusLine { private static final String SEPERATOR = " "; - private final String version; - private final HttpStatus httpStatus; + private String version; + private HttpStatus httpStatus; public StatusLine(String version, HttpStatus httpStatus) { this.version = version; @@ -15,4 +15,8 @@ public StatusLine(String version, HttpStatus httpStatus) { public String getStatusLine() { return version + SEPERATOR + httpStatus.getHttpStatus() + SEPERATOR; } + + public void setStatus(HttpStatus status) { + this.httpStatus = status; + } } diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java index adb4135adb..696790cf54 100644 --- a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java @@ -83,13 +83,11 @@ void index() throws IOException { final URL resource = getClass().getClassLoader().getResource("static/login.html"); String responseBody = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); - HttpResponse expected = new HttpResponse.Builder() - .status(OK) - .contentType(HTML) - .header("Content-Length", String.valueOf(responseBody.length())) - .body(responseBody) - .build(); - + HttpResponse expected = HttpResponse.createDefaultResponse(); + expected.setStatus(OK); + expected.setContentType(HTML); + expected.addHeader("Content-Length", String.valueOf(responseBody.length())); + expected.setBody(responseBody); assertThat(socket.output()).isEqualTo(expected.getResponse()); } From 18c7c2e8a41b41c8069f414ad714d95d0686e8fb Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 00:04:39 +0900 Subject: [PATCH 11/21] =?UTF-8?q?refactor:=20RequestMapping=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/RequestMapping.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java index 0ffa3a3315..ac9d4e23ba 100644 --- a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java @@ -7,21 +7,30 @@ import org.apache.coyote.request.HttpRequest; import org.apache.coyote.request.RequestUri; +import java.util.LinkedHashMap; +import java.util.Map; + public class RequestMapping { + private static Map mappers = new LinkedHashMap<>(); + + static { + mappers.put("/", new RootController()); + mappers.put("/login", new LoginController()); + mappers.put("/register", new RegisterController()); + } + + public Controller getController(HttpRequest request) { RequestUri requestUri = request.getRequestLine().getRequestUri(); String path = requestUri.getPath(); - if (path.equals("/")) { - return new RootController(); - } - if (path.equals("/login")) { - return new LoginController(); - } - if (path.equals("/register")) { - return new RegisterController(); - } - return new DefaultController(); + + return mappers.entrySet() + .stream() + .filter(entry -> path.equals(entry.getKey())) + .map(Map.Entry::getValue) + .findFirst() + .orElse(new DefaultController()); } } From b4b4de779a4cb1feb4ac4585d000946e85b03b14 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 00:10:28 +0900 Subject: [PATCH 12/21] =?UTF-8?q?refactor:=20SessionManager=20=EB=8F=99?= =?UTF-8?q?=EC=8B=9C=EC=84=B1=20=EC=BB=AC=EB=A0=89=EC=85=98=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- .../main/java/org/apache/catalina/manager/SessionManager.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 64fcfddec6..68072b8b29 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ - [x] HttpRequest 클래스 구현하기 - [x] HttpResponse 클래스 구현하기 -- [ ] Controller 인터페이스 추가하기 +- [x] Controller 인터페이스 추가하기 ### 4단계 - 동시성 확장하기 - [ ] Executors로 Thread Pool 적용 -- [ ] 동시성 컬렉션 사용하기 +- [x] 동시성 컬렉션 사용하기 diff --git a/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java b/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java index 894d6f93e4..2311283792 100644 --- a/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java +++ b/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java @@ -2,12 +2,12 @@ import org.apache.coyote.common.Session; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public class SessionManager { - private static final Map SESSIONS = new HashMap<>(); + private static final Map SESSIONS = new ConcurrentHashMap<>(); private SessionManager() { } From c0bab3e894445dc996cb40306c9a3611c27d6d75 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 00:33:10 +0900 Subject: [PATCH 13/21] =?UTF-8?q?feat:=20Executors=20=EB=A1=9C=20ThreadPoo?= =?UTF-8?q?l=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../org/apache/catalina/connector/Connector.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 68072b8b29..378414cb10 100644 --- a/README.md +++ b/README.md @@ -24,5 +24,5 @@ ### 4단계 - 동시성 확장하기 -- [ ] Executors로 Thread Pool 적용 +- [x] Executors로 Thread Pool 적용 - [x] 동시성 컬렉션 사용하기 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..4205e2b7d1 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -4,10 +4,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.awt.*; import java.io.IOException; import java.io.UncheckedIOException; import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Connector implements Runnable { @@ -15,8 +18,11 @@ 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() { @@ -26,6 +32,13 @@ public Connector() { public Connector(final int port, final int acceptCount) { this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; + this.executorService = Executors.newFixedThreadPool(DEFAULT_MAX_THREADS); + } + + public Connector(final Container container, final int port, final int acceptCount, final int maxThreads) { + this.serverSocket = createServerSocket(port, acceptCount); + this.stopped = false; + this.executorService = Executors.newFixedThreadPool(maxThreads); } private ServerSocket createServerSocket(final int port, final int acceptCount) { @@ -67,13 +80,14 @@ private void process(final Socket connection) { return; } var processor = new Http11Processor(connection); - new Thread(processor).start(); + executorService.execute(processor); } public void stop() { stopped = true; try { serverSocket.close(); + executorService.shutdown(); } catch (IOException e) { log.error(e.getMessage(), e); } From 7d0199e90b3f0237949d1d8b798ea20fc67548f5 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 00:56:34 +0900 Subject: [PATCH 14/21] =?UTF-8?q?fix:=20LoginController=20NPE=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/controller/LoginController.java | 4 ++-- .../java/org/apache/catalina/manager/SessionManager.java | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index e39c3432c5..9dc8ba976b 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -68,9 +68,9 @@ protected void doGet(HttpRequest request, HttpResponse response) throws Exceptio HttpCookie cookie = request.getRequestHeader().getCookie(); String jsessionid = cookie.getValue("JSESSIONID"); - Session session = SessionManager.findSession(jsessionid); + Optional session = SessionManager.findSession(jsessionid); - if (session != null) { + if (session.isPresent()) { response.setStatus(FOUND); response.addHeader("Location", "/index.html"); response.setContentType(HTML); diff --git a/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java b/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java index 2311283792..7e5fdd1f68 100644 --- a/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java +++ b/tomcat/src/main/java/org/apache/catalina/manager/SessionManager.java @@ -3,6 +3,7 @@ import org.apache.coyote.common.Session; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; public class SessionManager { @@ -16,8 +17,11 @@ public static void add(final Session session) { SESSIONS.put(session.getId(), session); } - public static Session findSession(final String id) { - return SESSIONS.get(id); + public static Optional findSession(final String id) { + if (id == null) { + return Optional.empty(); + } + return Optional.ofNullable(SESSIONS.get(id)); } public void remove(final String id) { From c6cb5e19a8d6323b4eca93231866d6366a975adc Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 01:00:14 +0900 Subject: [PATCH 15/21] =?UTF-8?q?fix:=20Controller=20=EC=8B=B1=EA=B8=80?= =?UTF-8?q?=ED=86=A4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/controller/DefaultController.java | 7 +++++++ .../java/nextstep/jwp/controller/LoginController.java | 7 +++++++ .../java/nextstep/jwp/controller/RegisterController.java | 7 +++++++ .../java/nextstep/jwp/controller/RootController.java | 7 +++++++ .../src/main/java/org/apache/coyote/RequestMapping.java | 9 +++++---- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java index 9ac81c0f00..2d9153ec06 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -1,5 +1,6 @@ package nextstep.jwp.controller; +import org.apache.coyote.Controller; import org.apache.coyote.common.ContentType; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.request.RequestUri; @@ -8,6 +9,12 @@ public class DefaultController extends AbstractController { + private static final Controller INSTANCE = new DefaultController(); + + public static Controller getInstance() { + return INSTANCE; + } + @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { RequestUri requestUri = request.getRequestLine().getRequestUri(); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 9dc8ba976b..5f68153231 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -3,6 +3,7 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; import org.apache.catalina.manager.SessionManager; +import org.apache.coyote.Controller; import org.apache.coyote.common.HttpCookie; import org.apache.coyote.common.Session; import org.apache.coyote.request.HttpRequest; @@ -18,6 +19,12 @@ public class LoginController extends AbstractController { + private static final Controller INSTANCE = new LoginController(); + + public static Controller getInstance() { + return INSTANCE; + } + @Override protected void doPost(HttpRequest request, HttpResponse response) throws Exception { HttpRequestBody httpRequestBody = request.getRequestBody(); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index ba6055b293..e36bb56921 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -2,6 +2,7 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; +import org.apache.coyote.Controller; import org.apache.coyote.common.ContentType; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.request.HttpRequestBody; @@ -14,6 +15,12 @@ public class RegisterController extends AbstractController { + private static final Controller INSTANCE = new RegisterController(); + + public static Controller getInstance() { + return INSTANCE; + } + @Override protected void doPost(HttpRequest request, HttpResponse response) throws Exception { HttpRequestBody httpRequestBody = request.getRequestBody(); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RootController.java b/tomcat/src/main/java/nextstep/jwp/controller/RootController.java index 166132d038..343f824a57 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RootController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RootController.java @@ -1,5 +1,6 @@ package nextstep.jwp.controller; +import org.apache.coyote.Controller; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -7,6 +8,12 @@ public class RootController extends AbstractController { + private static final Controller INSTANCE = new RootController(); + + public static Controller getInstance() { + return INSTANCE; + } + @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setContentType(HTML); diff --git a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java index ac9d4e23ba..02744ed3ae 100644 --- a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java @@ -15,9 +15,10 @@ public class RequestMapping { private static Map mappers = new LinkedHashMap<>(); static { - mappers.put("/", new RootController()); - mappers.put("/login", new LoginController()); - mappers.put("/register", new RegisterController()); + mappers = Map.of( + "/", RootController.getInstance(), + "/login", LoginController.getInstance(), + "/register", RegisterController.getInstance()); } @@ -31,6 +32,6 @@ public Controller getController(HttpRequest request) { .filter(entry -> path.equals(entry.getKey())) .map(Map.Entry::getValue) .findFirst() - .orElse(new DefaultController()); + .orElse(DefaultController.getInstance()); } } From a1a51beb42c4f1295dd95d0c076aa9613bdce8ba Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 01:13:24 +0900 Subject: [PATCH 16/21] =?UTF-8?q?feat:=20404,=20500=20=EB=A6=AC=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EB=A0=89=EC=85=98=20=EC=B2=98=EB=A6=AC=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 --- .../jwp/controller/AbstractController.java | 22 ++++++++++++++----- .../jwp/controller/DefaultController.java | 15 +++++++++++-- .../org/apache/coyote/utils/FileUtils.java | 19 ++++------------ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java index 20b01e8adc..1194164836 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -6,18 +6,28 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.response.HttpStatus.FOUND; + public class AbstractController implements Controller { protected static final Logger log = LoggerFactory.getLogger(AbstractController.class); @Override public void service(HttpRequest request, HttpResponse response) throws Exception { - if (request.getRequestLine().isGetMethod()) { - doGet(request, response); - return; - } - if (request.getRequestLine().isPostMethod()) { - doPost(request, response); + + try { + if (request.getRequestLine().isGetMethod()) { + doGet(request, response); + return; + } + if (request.getRequestLine().isPostMethod()) { + doPost(request, response); + } + } catch (Exception e) { + response.setStatus(FOUND); + response.setContentType(HTML); + response.addHeader("Location", "/500.html"); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java index 2d9153ec06..b80a755b78 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -7,6 +7,9 @@ import org.apache.coyote.response.HttpResponse; import org.apache.coyote.utils.FileUtils; +import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.response.HttpStatus.FOUND; + public class DefaultController extends AbstractController { private static final Controller INSTANCE = new DefaultController(); @@ -19,7 +22,15 @@ public static Controller getInstance() { protected void doGet(HttpRequest request, HttpResponse response) throws Exception { RequestUri requestUri = request.getRequestLine().getRequestUri(); - response.setContentType(ContentType.from(requestUri.getExtension())); - response.setBody(FileUtils.readFile(requestUri.getPath())); + + try { + FileUtils.readFile(requestUri.getPath()); + response.setContentType(ContentType.from(requestUri.getExtension())); + response.setBody(FileUtils.readFile(requestUri.getPath())); + } catch (NullPointerException e) { + response.setStatus(FOUND); + response.setContentType(HTML); + response.addHeader("Location", "/404.html"); + } } } diff --git a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java index c050cb7ad3..e0fe1b3373 100644 --- a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java +++ b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java @@ -4,28 +4,17 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Objects; public class FileUtils { private static final String STATIC_DIRECTORY = "static"; - private static final String NOT_FOUND_PAGE = "/404.html"; public static String readFile(String path) throws IOException { - Path filePath = null; - try { - URL resource = FileUtils.class - .getClassLoader() - .getResource(STATIC_DIRECTORY + path); + URL resource = FileUtils.class + .getClassLoader() + .getResource(STATIC_DIRECTORY + path); - filePath = Path.of(resource.getPath()); - } catch (NullPointerException e) { - URL resource = Objects.requireNonNull(FileUtils.class - .getClassLoader() - .getResource(STATIC_DIRECTORY + NOT_FOUND_PAGE)); - - filePath = Path.of(resource.getPath()); - } + Path filePath = Path.of(resource.getPath()); return new String(Files.readAllBytes(filePath)); } From d0f63235994683b459dd05ee6642a3868ca394f5 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 09:11:17 +0900 Subject: [PATCH 17/21] =?UTF-8?q?fix:=20test=20=EA=B9=A8=EC=A7=80=EB=8A=94?= =?UTF-8?q?=20=EA=B2=83=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/response/HttpResponse.java | 1 + .../apache/coyote/http11/Http11ProcessorTest.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index c56a8b8f2d..852818f22b 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -39,6 +39,7 @@ public void setContentType(ContentType contentType) { } public void setBody(String body) { + addHeader("Content-Length", String.valueOf(body.length())); this.body = body; } diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java index 696790cf54..2d82c88e3b 100644 --- a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java @@ -54,13 +54,14 @@ 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: 5564 \r\n" + - "\r\n" + - new String(Files.readAllBytes(new File(resource.getFile()).toPath())); - assertThat(socket.output()).isEqualTo(expected); + String responseBody = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); + + HttpResponse expected = HttpResponse.createDefaultResponse(); + expected.setContentType(HTML); + expected.setBody(responseBody); + + assertThat(socket.output()).isEqualTo(expected.getResponse()); } @Test @@ -84,9 +85,7 @@ void index() throws IOException { String responseBody = new String(Files.readAllBytes(new File(resource.getFile()).toPath())); HttpResponse expected = HttpResponse.createDefaultResponse(); - expected.setStatus(OK); expected.setContentType(HTML); - expected.addHeader("Content-Length", String.valueOf(responseBody.length())); expected.setBody(responseBody); assertThat(socket.output()).isEqualTo(expected.getResponse()); From 93065f25eb90ac49bc54fbe1d0e6a0e428006fa8 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 09:23:19 +0900 Subject: [PATCH 18/21] =?UTF-8?q?refactor:=20Header=20=EC=83=81=EC=88=98?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nextstep/jwp/controller/AbstractController.java | 3 ++- .../nextstep/jwp/controller/DefaultController.java | 3 ++- .../nextstep/jwp/controller/LoginController.java | 12 +++++++----- .../nextstep/jwp/controller/RegisterController.java | 3 ++- .../main/java/org/apache/coyote/RequestMapping.java | 3 +-- .../main/java/org/apache/coyote/common/Headers.java | 11 +++++++++++ .../org/apache/coyote/response/HttpResponse.java | 11 ++++++----- 7 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/common/Headers.java diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java index 1194164836..486160b42a 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory; import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.common.Headers.LOCATION; import static org.apache.coyote.response.HttpStatus.FOUND; public class AbstractController implements Controller { @@ -27,7 +28,7 @@ public void service(HttpRequest request, HttpResponse response) throws Exception } catch (Exception e) { response.setStatus(FOUND); response.setContentType(HTML); - response.addHeader("Location", "/500.html"); + response.addHeader(LOCATION, "/500.html"); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java index b80a755b78..89128e047c 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -8,6 +8,7 @@ import org.apache.coyote.utils.FileUtils; import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.common.Headers.LOCATION; import static org.apache.coyote.response.HttpStatus.FOUND; public class DefaultController extends AbstractController { @@ -30,7 +31,7 @@ protected void doGet(HttpRequest request, HttpResponse response) throws Exceptio } catch (NullPointerException e) { response.setStatus(FOUND); response.setContentType(HTML); - response.addHeader("Location", "/404.html"); + response.addHeader(LOCATION, "/404.html"); } } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 5f68153231..2ab1305e39 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -14,6 +14,8 @@ import java.util.Optional; import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.common.Headers.JSESSIONID; +import static org.apache.coyote.common.Headers.LOCATION; import static org.apache.coyote.response.HttpStatus.FOUND; import static org.apache.coyote.response.HttpStatus.OK; @@ -55,18 +57,18 @@ private void loginSuccess(Optional user, HttpResponse response) { session.setAttribute("user", user); SessionManager.add(session); - HttpCookie cookie = HttpCookie.of("JSESSIONID=" + session.getId()); + HttpCookie cookie = HttpCookie.of(JSESSIONID + "=" + session.getId()); response.setStatus(FOUND); response.setContentType(HTML); - response.addHeader("Location", "/index.html"); + response.addHeader(LOCATION, "/index.html"); response.setCookie(cookie); } private void loginFail(HttpResponse response) { response.setStatus(FOUND); response.setContentType(HTML); - response.addHeader("Location", "/401.html"); + response.addHeader(LOCATION, "/401.html"); } @@ -74,12 +76,12 @@ private void loginFail(HttpResponse response) { protected void doGet(HttpRequest request, HttpResponse response) throws Exception { HttpCookie cookie = request.getRequestHeader().getCookie(); - String jsessionid = cookie.getValue("JSESSIONID"); + String jsessionid = cookie.getValue(JSESSIONID); Optional session = SessionManager.findSession(jsessionid); if (session.isPresent()) { response.setStatus(FOUND); - response.addHeader("Location", "/index.html"); + response.addHeader(LOCATION, "/index.html"); response.setContentType(HTML); return; } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index e36bb56921..b085c72d60 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -11,6 +11,7 @@ import org.apache.coyote.utils.FileUtils; import static org.apache.coyote.common.ContentType.HTML; +import static org.apache.coyote.common.Headers.LOCATION; import static org.apache.coyote.response.HttpStatus.FOUND; public class RegisterController extends AbstractController { @@ -37,7 +38,7 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti response.setStatus(FOUND); response.setContentType(HTML); - response.addHeader("Location", "/index.html"); + response.addHeader(LOCATION, "/index.html"); } @Override diff --git a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java index 02744ed3ae..73b64adcf4 100644 --- a/tomcat/src/main/java/org/apache/coyote/RequestMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/RequestMapping.java @@ -7,12 +7,11 @@ import org.apache.coyote.request.HttpRequest; import org.apache.coyote.request.RequestUri; -import java.util.LinkedHashMap; import java.util.Map; public class RequestMapping { - private static Map mappers = new LinkedHashMap<>(); + private static final Map mappers; static { mappers = Map.of( diff --git a/tomcat/src/main/java/org/apache/coyote/common/Headers.java b/tomcat/src/main/java/org/apache/coyote/common/Headers.java new file mode 100644 index 0000000000..2bb96ab478 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/common/Headers.java @@ -0,0 +1,11 @@ +package org.apache.coyote.common; + +public class Headers { + + public static final String LOCATION = "Location"; + public static final String JSESSIONID = "JSESSIONID"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String CONTENT_LENGTH = "Content-Length"; + public static final String SET_COOKIE = "Set-Cookie"; + public static final String CHARSET_UTF8 = ";charset=utf-8"; +} diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index 852818f22b..86009561de 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -6,6 +6,8 @@ import java.util.LinkedHashMap; import java.util.Map; +import static org.apache.coyote.common.Headers.*; + public class HttpResponse { private static final String DEFAULT_VERSION = "HTTP/1.1"; @@ -22,12 +24,11 @@ private HttpResponse(StatusLine statusLine, HttpResponseHeader headers, String b } public static HttpResponse createDefaultResponse() { - String version = DEFAULT_VERSION; HttpStatus httpStatus = HttpStatus.OK; Map headers = new LinkedHashMap<>(); String body = ""; - return new HttpResponse(new StatusLine(version, httpStatus), new HttpResponseHeader(headers), body); + return new HttpResponse(new StatusLine(DEFAULT_VERSION, httpStatus), new HttpResponseHeader(headers), body); } public String getResponse() { @@ -35,11 +36,11 @@ public String getResponse() { } public void setContentType(ContentType contentType) { - this.headers.add("Content-Type", contentType.getType() + ";charset=utf-8"); + this.headers.add(CONTENT_TYPE, contentType.getType() + CHARSET_UTF8); } public void setBody(String body) { - addHeader("Content-Length", String.valueOf(body.length())); + addHeader(CONTENT_LENGTH, String.valueOf(body.length())); this.body = body; } @@ -52,6 +53,6 @@ public void addHeader(String key, String value) { } public void setCookie(HttpCookie cookie) { - this.headers.add("Set-Cookie", cookie.convertToHeader()); + this.headers.add(SET_COOKIE, cookie.convertToHeader()); } } From 26983934cb1a1ccd2544303a4f5c5d06d150d3e5 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 09:31:08 +0900 Subject: [PATCH 19/21] =?UTF-8?q?refactor:=20sonarlint=20=EB=B6=84?= =?UTF-8?q?=EC=84=9D=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/controller/AbstractController.java | 1 - .../src/main/java/org/apache/coyote/common/Headers.java | 4 ++++ .../org/apache/coyote/request/HttpRequestHeader.java | 9 ++++++--- .../main/java/org/apache/coyote/request/RequestUri.java | 1 - .../src/main/java/org/apache/coyote/utils/FileUtils.java | 3 +++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java index 486160b42a..1b67118737 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -20,7 +20,6 @@ public void service(HttpRequest request, HttpResponse response) throws Exception try { if (request.getRequestLine().isGetMethod()) { doGet(request, response); - return; } if (request.getRequestLine().isPostMethod()) { doPost(request, response); diff --git a/tomcat/src/main/java/org/apache/coyote/common/Headers.java b/tomcat/src/main/java/org/apache/coyote/common/Headers.java index 2bb96ab478..164c42cbff 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/Headers.java +++ b/tomcat/src/main/java/org/apache/coyote/common/Headers.java @@ -2,10 +2,14 @@ public class Headers { + private Headers() { + } + public static final String LOCATION = "Location"; public static final String JSESSIONID = "JSESSIONID"; public static final String CONTENT_TYPE = "Content-Type"; public static final String CONTENT_LENGTH = "Content-Length"; public static final String SET_COOKIE = "Set-Cookie"; public static final String CHARSET_UTF8 = ";charset=utf-8"; + public static final String COOKIE = "Cookie"; } diff --git a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java index 941c64500a..2416c2d148 100644 --- a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java @@ -7,6 +7,9 @@ import java.util.List; import java.util.Map; +import static org.apache.coyote.common.Headers.CONTENT_LENGTH; +import static org.apache.coyote.common.Headers.COOKIE; + public class HttpRequestHeader { private static final String SEPERATOR = "\r\n"; @@ -35,16 +38,16 @@ public static HttpRequestHeader from(String requestHeader) { } public int getContentLength() { - String contentLength = headers.get("Content-Length"); + String contentLength = headers.get(CONTENT_LENGTH); try { return Integer.parseInt(contentLength); } catch (NumberFormatException e) { + return 0; } - return 0; } public HttpCookie getCookie() { - String cookie = headers.get("Cookie"); + String cookie = headers.get(COOKIE); return HttpCookie.of(cookie); } } diff --git a/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java b/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java index a39949709c..fc12ba43c1 100644 --- a/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java +++ b/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java @@ -6,7 +6,6 @@ public class RequestUri { - private static final String SEPERATOR = "\\?"; private static final String QUERY_SEPARATOR = "&"; private static final String KEY_VALUE_SEPEARTOR = "="; private static final String DOT = "."; diff --git a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java index e0fe1b3373..1382608b9a 100644 --- a/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java +++ b/tomcat/src/main/java/org/apache/coyote/utils/FileUtils.java @@ -9,6 +9,9 @@ public class FileUtils { private static final String STATIC_DIRECTORY = "static"; + private FileUtils() { + } + public static String readFile(String path) throws IOException { URL resource = FileUtils.class .getClassLoader() From 7c1c382163af1486118e0f0a3845015f4a5e3718 Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 22:57:13 +0900 Subject: [PATCH 20/21] =?UTF-8?q?refactor:=20LoginController=20if/else=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/LoginController.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 2ab1305e39..896be89fe8 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -35,24 +35,23 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti Optional user = InMemoryUserRepository.findByAccount(account); - if (user.isPresent() && user.get().checkPassword(password)) { - log.info(user.toString()); - - loginSuccess(user, response); - - } else if (user.isPresent()) { - log.warn("비밀번호가 틀렸습니다"); - - loginFail(response); - - } else { - log.warn("미가입회원입니다"); - - loginFail(response); + if (user.isPresent()) { + user.filter(userInfo -> userInfo.checkPassword(password)) + .ifPresentOrElse(registerUser -> { + log.info(registerUser.toString()); + loginSuccess(registerUser, response); + } + , () -> { + log.warn("비밀번호가 틀렸습니다"); + loginFail(response); + }); + return; } + log.warn("미가입회원입니다"); + loginFail(response); } - private void loginSuccess(Optional user, HttpResponse response) { + private void loginSuccess(User user, HttpResponse response) { Session session = new Session(); session.setAttribute("user", user); SessionManager.add(session); From c02a87b952e2797ed9b901d8d6959ea4e87e403a Mon Sep 17 00:00:00 2001 From: yenawee Date: Mon, 11 Sep 2023 22:57:37 +0900 Subject: [PATCH 21/21] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=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 --- .../nextstep/jwp/controller/DefaultController.java | 1 - .../java/org/apache/coyote/common/Headers.java | 1 + .../java/org/apache/coyote/common/HttpCookie.java | 6 ++++-- .../apache/coyote/request/HttpRequestHeader.java | 14 +++++++------- .../org/apache/coyote/response/HttpResponse.java | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java index 89128e047c..b33e02a82c 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/DefaultController.java @@ -23,7 +23,6 @@ public static Controller getInstance() { protected void doGet(HttpRequest request, HttpResponse response) throws Exception { RequestUri requestUri = request.getRequestLine().getRequestUri(); - try { FileUtils.readFile(requestUri.getPath()); response.setContentType(ContentType.from(requestUri.getExtension())); diff --git a/tomcat/src/main/java/org/apache/coyote/common/Headers.java b/tomcat/src/main/java/org/apache/coyote/common/Headers.java index 164c42cbff..03e1325653 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/Headers.java +++ b/tomcat/src/main/java/org/apache/coyote/common/Headers.java @@ -12,4 +12,5 @@ private Headers() { public static final String SET_COOKIE = "Set-Cookie"; public static final String CHARSET_UTF8 = ";charset=utf-8"; public static final String COOKIE = "Cookie"; + public static final String CRLF = "\r\n"; } diff --git a/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java index ec3ec0b67f..145b7f2680 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpCookie.java @@ -10,6 +10,8 @@ public class HttpCookie { private static final String KEY_VALUE_SEPERATOR = "="; private static final String COOKIE_SEPERATOR = "; "; + private static final int KEY_INDEX = 0; + private static final int VALUE_INDEX = 1; private final Map cookie; @@ -32,8 +34,8 @@ private static void generateCookie(Map cookies, String[] cookieP for (String cookiePair : cookiePairs) { String[] parts = cookiePair.split(KEY_VALUE_SEPERATOR); if (parts.length == 2) { - String name = parts[0]; - String value = parts[1]; + String name = parts[KEY_INDEX]; + String value = parts[VALUE_INDEX]; cookies.put(name, value); } } diff --git a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java index 2416c2d148..7292ab52be 100644 --- a/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java +++ b/tomcat/src/main/java/org/apache/coyote/request/HttpRequestHeader.java @@ -7,13 +7,13 @@ import java.util.List; import java.util.Map; -import static org.apache.coyote.common.Headers.CONTENT_LENGTH; -import static org.apache.coyote.common.Headers.COOKIE; +import static org.apache.coyote.common.Headers.*; public class HttpRequestHeader { - private static final String SEPERATOR = "\r\n"; private static final String HEADER_SEPERATOR = ": "; + private static final int KEY_INDEX = 0; + private static final int VALUE_INDEX = 1; private final Map headers; @@ -23,14 +23,14 @@ private HttpRequestHeader(Map headers) { public static HttpRequestHeader from(String requestHeader) { Map headers = new LinkedHashMap<>(); - String[] splitedLines = requestHeader.split(SEPERATOR); + String[] splitedLines = requestHeader.split(CRLF); List splited = Arrays.asList(splitedLines); for (String line : splited) { String[] parts = line.split(HEADER_SEPERATOR); if (parts.length == 2) { - String key = parts[0].trim(); - String value = parts[1].trim(); + String key = parts[KEY_INDEX].trim(); + String value = parts[VALUE_INDEX].trim(); headers.put(key, value); } } @@ -42,7 +42,7 @@ public int getContentLength() { try { return Integer.parseInt(contentLength); } catch (NumberFormatException e) { - return 0; + return KEY_INDEX; } } diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index 86009561de..15d518f76a 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -32,7 +32,7 @@ public static HttpResponse createDefaultResponse() { } public String getResponse() { - return statusLine.getStatusLine() + "\r\n" + headers.getResponseHeader() + "\r\n" + body; + return statusLine.getStatusLine() + CRLF + headers.getResponseHeader() + CRLF + body; } public void setContentType(ContentType contentType) {