From 5f53414708027e6acb28ae0aae17c297eded7171 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 5 Sep 2023 15:29:17 +0900 Subject: [PATCH 01/43] =?UTF-8?q?feat:=20CacheControl=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=EC=85=89=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cachecontrol/CacheInterceptor.java | 21 +++++++++++++++++++ .../example/cachecontrol/CacheWebConfig.java | 1 + .../org/apache/coyote/http/HttpHeader.java | 16 ++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 study/src/main/java/cache/com/example/cachecontrol/CacheInterceptor.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java diff --git a/study/src/main/java/cache/com/example/cachecontrol/CacheInterceptor.java b/study/src/main/java/cache/com/example/cachecontrol/CacheInterceptor.java new file mode 100644 index 0000000000..4a9be4935a --- /dev/null +++ b/study/src/main/java/cache/com/example/cachecontrol/CacheInterceptor.java @@ -0,0 +1,21 @@ +package cache.com.example.cachecontrol; + +import com.google.common.net.HttpHeaders; +import org.springframework.http.CacheControl; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class CacheInterceptor implements HandlerInterceptor { + + @Override + public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) throws Exception { + final String cacheControlValue = CacheControl.noCache() + .cachePrivate() + .getHeaderValue(); + + response.addHeader(HttpHeaders.CACHE_CONTROL, cacheControlValue); + } +} diff --git a/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java b/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java index 305b1f1e1e..eaac52447f 100644 --- a/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java +++ b/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java @@ -9,5 +9,6 @@ public class CacheWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(new CacheInterceptor()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java b/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java new file mode 100644 index 0000000000..047899abd4 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java @@ -0,0 +1,16 @@ +package org.apache.coyote.http; + +public enum HttpHeader { + + CONTENT_TYPE("Content-Type"), + CONTENT_LENGTH("Content-Length"), + LOCATION("Location"), + COOKIE("Cookie"), + SET_COOKIE("Set-Cookie"); + + private final String header; + + HttpHeader(final String header) { + this.header = header; + } +} From 818588c4dd9b91263ad19f27fdd03161e210023a Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 5 Sep 2023 15:55:02 +0900 Subject: [PATCH 02/43] =?UTF-8?q?feat:=20=EC=95=95=EC=B6=95=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/main/resources/application.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 4e8655a962..78fc4ffa3d 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -7,3 +7,7 @@ server: max-connections: 1 threads: max: 2 + + compression: + enabled: true + min-response-size: 10 From b205cc0a9bdd99a3f5475b01d5d45af261fed12e Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 5 Sep 2023 16:46:06 +0900 Subject: [PATCH 03/43] =?UTF-8?q?feat:=20Etag=20=EC=84=A4=EC=A0=95=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 --- .../com/example/etag/EtagFilterConfiguration.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java b/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java index 41ef7a3d9a..1b42f6eced 100644 --- a/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java +++ b/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java @@ -1,12 +1,19 @@ package cache.com.example.etag; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.ShallowEtagHeaderFilter; @Configuration public class EtagFilterConfiguration { -// @Bean -// public FilterRegistrationBean shallowEtagHeaderFilter() { -// return null; -// } + @Bean + public FilterRegistrationBean shallowEtagHeaderFilter() { + final FilterRegistrationBean shallowEtagHeaderFilterFilterRegistrationBean + = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter()); + shallowEtagHeaderFilterFilterRegistrationBean.addUrlPatterns("/etag"); + shallowEtagHeaderFilterFilterRegistrationBean.setName("etagFilter"); + return shallowEtagHeaderFilterFilterRegistrationBean; + } } From e42bd2a322174bdf0f979ed0067ed97a68abc52f Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 5 Sep 2023 17:16:46 +0900 Subject: [PATCH 04/43] =?UTF-8?q?feat:=20Version=20=EB=B0=8F=20=EC=BA=90?= =?UTF-8?q?=EC=8B=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cache/com/example/cachecontrol/CacheWebConfig.java | 3 ++- .../cache/com/example/etag/EtagFilterConfiguration.java | 2 +- .../cache/com/example/version/CacheBustingWebConfig.java | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java b/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java index eaac52447f..80302d6159 100644 --- a/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java +++ b/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java @@ -9,6 +9,7 @@ public class CacheWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(new CacheInterceptor()); + registry.addInterceptor(new CacheInterceptor()) + .excludePathPatterns("/resources/**"); } } diff --git a/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java b/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java index 1b42f6eced..795231a56c 100644 --- a/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java +++ b/study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.java @@ -12,7 +12,7 @@ public class EtagFilterConfiguration { public FilterRegistrationBean shallowEtagHeaderFilter() { final FilterRegistrationBean shallowEtagHeaderFilterFilterRegistrationBean = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter()); - shallowEtagHeaderFilterFilterRegistrationBean.addUrlPatterns("/etag"); + shallowEtagHeaderFilterFilterRegistrationBean.addUrlPatterns("/etag", "/resources/*"); shallowEtagHeaderFilterFilterRegistrationBean.setName("etagFilter"); return shallowEtagHeaderFilterFilterRegistrationBean; } diff --git a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java index 6da6d2c795..d7e238c887 100644 --- a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java +++ b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java @@ -2,13 +2,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.util.concurrent.TimeUnit; + @Configuration public class CacheBustingWebConfig implements WebMvcConfigurer { public static final String PREFIX_STATIC_RESOURCES = "/resources"; + public static final Long MAX_AGE = 365L; private final ResourceVersion version; @@ -20,6 +24,6 @@ public CacheBustingWebConfig(ResourceVersion version) { @Override public void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**") - .addResourceLocations("classpath:/static/"); + .setCacheControl(CacheControl.maxAge(MAX_AGE, TimeUnit.DAYS).cachePublic()).addResourceLocations("classpath:/static/"); } } From 815ecb54d03ba1d38794888a0e512214f1e35d79 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 11:29:52 +0900 Subject: [PATCH 05/43] =?UTF-8?q?test:=20=EC=93=B0=EB=A0=88=EB=93=9C=20sta?= =?UTF-8?q?ge0=20=ED=95=99=EC=8A=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/test/java/thread/stage0/SynchronizationTest.java | 2 +- study/src/test/java/thread/stage0/ThreadPoolsTest.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/study/src/test/java/thread/stage0/SynchronizationTest.java b/study/src/test/java/thread/stage0/SynchronizationTest.java index 0333c18e3b..b463c2b984 100644 --- a/study/src/test/java/thread/stage0/SynchronizationTest.java +++ b/study/src/test/java/thread/stage0/SynchronizationTest.java @@ -41,7 +41,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..03efdabc8d 100644 --- a/study/src/test/java/thread/stage0/ThreadPoolsTest.java +++ b/study/src/test/java/thread/stage0/ThreadPoolsTest.java @@ -31,8 +31,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 +46,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()); From 35d7e5766978c1dffb6c2323a63b81a5cf430ebd Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 13:32:04 +0900 Subject: [PATCH 06/43] =?UTF-8?q?test:=20=EC=93=B0=EB=A0=88=EB=93=9C=20sta?= =?UTF-8?q?ge1=20=ED=95=99=EC=8A=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/test/java/thread/stage1/UserServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/study/src/test/java/thread/stage1/UserServlet.java b/study/src/test/java/thread/stage1/UserServlet.java index b180a84c32..a78e7b4ad4 100644 --- a/study/src/test/java/thread/stage1/UserServlet.java +++ b/study/src/test/java/thread/stage1/UserServlet.java @@ -11,7 +11,7 @@ public void service(final User user) { join(user); } - private void join(final User user) { + private synchronized void join(final User user) { if (!users.contains(user)) { users.add(user); } From c714b06de6f73aa0a36759ccc480f286a3f0e61a Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:09:15 +0900 Subject: [PATCH 07/43] =?UTF-8?q?test:=20=EC=93=B0=EB=A0=88=EB=93=9C=20sta?= =?UTF-8?q?ge2=20=ED=95=99=EC=8A=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 78fc4ffa3d..409a60dc1c 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -4,7 +4,7 @@ handlebars: server: tomcat: accept-count: 1 - max-connections: 1 + max-connections: 2 threads: max: 2 From 4fd6b3443eff586510f33fa29251e4ff7a54fe01 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:12:18 +0900 Subject: [PATCH 08/43] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/handler/FrontHandler.java | 8 ++++---- .../coyote/handler/mapping/{ => login}/LoginFilter.java | 2 +- .../coyote/handler/mapping/{ => login}/LoginMapping.java | 3 ++- .../handler/mapping/{ => login}/LoginPageMapping.java | 3 ++- .../handler/mapping/{ => register}/RegisterMapping.java | 3 ++- .../mapping/{ => register}/RegisterPageMapping.java | 3 ++- 6 files changed, 13 insertions(+), 9 deletions(-) rename tomcat/src/main/java/org/apache/coyote/handler/mapping/{ => login}/LoginFilter.java (93%) rename tomcat/src/main/java/org/apache/coyote/handler/mapping/{ => login}/LoginMapping.java (95%) rename tomcat/src/main/java/org/apache/coyote/handler/mapping/{ => login}/LoginPageMapping.java (96%) rename tomcat/src/main/java/org/apache/coyote/handler/mapping/{ => register}/RegisterMapping.java (90%) rename tomcat/src/main/java/org/apache/coyote/handler/mapping/{ => register}/RegisterPageMapping.java (91%) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 06cc2f006d..f758870881 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -2,11 +2,11 @@ import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.handler.mapping.HomePageMapping; -import org.apache.coyote.handler.mapping.LoginMapping; -import org.apache.coyote.handler.mapping.LoginPageMapping; -import org.apache.coyote.handler.mapping.RegisterMapping; -import org.apache.coyote.handler.mapping.RegisterPageMapping; import org.apache.coyote.handler.mapping.StaticFileMapping; +import org.apache.coyote.handler.mapping.login.LoginMapping; +import org.apache.coyote.handler.mapping.login.LoginPageMapping; +import org.apache.coyote.handler.mapping.register.RegisterMapping; +import org.apache.coyote.handler.mapping.register.RegisterPageMapping; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginFilter.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java similarity index 93% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginFilter.java rename to tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java index 4542493c81..ecfacaea38 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginFilter.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java @@ -1,4 +1,4 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.mapping.login; import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.session.Session; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java similarity index 95% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java index 49c4388a85..cbab50ad94 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java @@ -1,7 +1,8 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.mapping.login; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; +import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeader; import org.apache.coyote.http.common.HttpHeaders; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java similarity index 96% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginPageMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index 86ef5c53a3..2af050cc6c 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -1,7 +1,8 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.mapping.login; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; +import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpCookie; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java similarity index 90% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java index 8ac2f150b9..4be728cf1a 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java @@ -1,7 +1,8 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.mapping.register; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; +import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java similarity index 91% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterPageMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 886e609afd..0767736044 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -1,5 +1,6 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.mapping.register; +import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpRequest; From 7c08debae69afa27b697f0c1898a7a0106f85791 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:27:27 +0900 Subject: [PATCH 09/43] =?UTF-8?q?refactor:=20HttpHeaders=20=EC=9D=98=20key?= =?UTF-8?q?=20=EB=A5=BC=20enummap=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/handler/mapping/HomePageMapping.java | 4 +--- .../handler/mapping/StaticFileMapping.java | 12 +++++------- .../handler/mapping/login/LoginMapping.java | 6 ++---- .../handler/mapping/login/LoginPageMapping.java | 3 +-- .../mapping/register/RegisterPageMapping.java | 4 +--- .../java/org/apache/coyote/http/HttpHeader.java | 16 ---------------- .../apache/coyote/http/common/HttpHeaders.java | 10 +++++++--- .../http/response/HttpResponseBuilder.java | 11 +++++++++-- .../apache/coyote/http11/HttpRequestParser.java | 5 ++--- 9 files changed, 28 insertions(+), 43 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java index a21b4ab1d1..fbe14accef 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java @@ -1,7 +1,6 @@ package org.apache.coyote.handler.mapping; import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; @@ -9,7 +8,6 @@ import org.apache.coyote.http.response.StatusLine; import java.io.IOException; -import java.util.Map; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; @@ -24,7 +22,7 @@ public boolean supports(final HttpRequest httpRequest) { public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.HTML.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) .body(new HttpBody("Hello world!")) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java index a38c9d7534..7a28c46da6 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java @@ -1,7 +1,6 @@ package org.apache.coyote.handler.mapping; import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; @@ -9,7 +8,6 @@ import org.apache.coyote.http.response.StatusLine; import java.io.IOException; -import java.util.Map; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; @@ -33,7 +31,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { if (requestUri.endsWith(".html")) { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.HTML.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) .body(HttpBody.file(filePath)) .build(); } @@ -41,7 +39,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { if (requestUri.endsWith(".js")) { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.JS.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.JS.getValue()) .body(HttpBody.file(filePath)) .build(); } @@ -49,7 +47,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { if (requestUri.endsWith(".css")) { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.CSS.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.CSS.getValue()) .body(HttpBody.file(filePath)) .build(); } @@ -57,11 +55,11 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { if (requestUri.endsWith(".ico")) { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.ICO.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.ICO.getValue()) .body(HttpBody.file(filePath)) .build(); } - return null; + return HttpResponse.redirect("/404.html"); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java index cbab50ad94..ce64f3fb1b 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java @@ -5,7 +5,6 @@ import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeader; -import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; @@ -52,9 +51,8 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.FOUND)) - .httpHeaders(new HttpHeaders( - Map.of(HttpHeader.LOCATION, "/index.html", - HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid))) + .httpHeaders(HttpHeader.LOCATION, "/index.html") + .httpHeaders(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid) .body(HttpBody.empty()) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index 2af050cc6c..d3d5fe7b1e 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -4,7 +4,6 @@ import nextstep.jwp.model.User; import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpCookie; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.ContentType; @@ -68,7 +67,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.HTML.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) .body(HttpBody.file("static/login.html")) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 0767736044..832dfef11b 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -2,7 +2,6 @@ import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.common.HttpHeaders; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; @@ -10,7 +9,6 @@ import org.apache.coyote.http.response.StatusLine; import java.io.IOException; -import java.util.Map; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; @@ -27,7 +25,7 @@ public boolean supports(final HttpRequest httpRequest) { public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(new HttpHeaders(Map.of(CONTENT_TYPE, ContentType.HTML.getValue()))) + .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) .body(HttpBody.file("static/register.html")) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java b/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java deleted file mode 100644 index 047899abd4..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http/HttpHeader.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.apache.coyote.http; - -public enum HttpHeader { - - CONTENT_TYPE("Content-Type"), - CONTENT_LENGTH("Content-Length"), - LOCATION("Location"), - COOKIE("Cookie"), - SET_COOKIE("Set-Cookie"); - - private final String header; - - HttpHeader(final String header) { - this.header = header; - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java b/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java index ef7568df97..06002541ef 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java +++ b/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java @@ -1,12 +1,13 @@ package org.apache.coyote.http.common; +import java.util.EnumMap; import java.util.Map; public class HttpHeaders { - private final Map headers; + private final EnumMap headers; - public HttpHeaders(final Map headers) { + public HttpHeaders(final EnumMap headers) { this.headers = headers; } @@ -22,10 +23,13 @@ public boolean containsKey(final HttpHeader headerName) { return headers.containsKey(headerName); } + public void add(final HttpHeader key, final String value) { + headers.put(key, value); + } + public void add(final HttpHeaders httpHeaders) { headers.putAll(httpHeaders.getHeaders()); } - public Map getHeaders() { return headers; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java index 649bd7d8f0..82ceae9459 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java @@ -1,8 +1,11 @@ package org.apache.coyote.http.response; import org.apache.coyote.http.common.HttpBody; +import org.apache.coyote.http.common.HttpHeader; import org.apache.coyote.http.common.HttpHeaders; +import java.util.EnumMap; + public class HttpResponseBuilder { private StatusLine statusLine; @@ -17,8 +20,12 @@ public HttpResponseBuilder statusLine(final StatusLine statusLine) { return this; } - public HttpResponseBuilder httpHeaders(final HttpHeaders httpHeaders) { - this.httpHeaders = httpHeaders; + public HttpResponseBuilder httpHeaders(final HttpHeader key, final String value) { + if (httpHeaders == null) { + this.httpHeaders = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + } + + httpHeaders.add(key, value); return this; } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java index d1c7460567..67d1e8bd95 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java @@ -11,8 +11,7 @@ import java.io.BufferedReader; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +import java.util.EnumMap; import static org.apache.coyote.http.common.HttpHeader.CONTENT_LENGTH; import static org.apache.coyote.http.request.HttpMethod.POST; @@ -47,7 +46,7 @@ private RequestLine parseStartLine(final String startLine) { } private HttpHeaders parseHeader(final BufferedReader bufferedReader) throws IOException { - final Map headers = new HashMap<>(); + final EnumMap headers = new EnumMap<>(HttpHeader.class); String header = bufferedReader.readLine(); while (!"".equals(header)) { final String[] parsedHeader = header.split(": "); From 86187268e4fc2366e70bceef89083d0f4396426f Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:42:43 +0900 Subject: [PATCH 10/43] =?UTF-8?q?refactor:=20=EC=A0=95=EC=A0=81=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=9D=98=20=ED=99=95=EC=9E=A5=EC=9E=90=EB=A5=BC=20con?= =?UTF-8?q?tenttype=EC=9C=BC=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/mapping/HomePageMapping.java | 2 +- .../handler/mapping/StaticFileMapping.java | 64 +++++++++---------- .../mapping/login/LoginPageMapping.java | 2 +- .../mapping/register/RegisterPageMapping.java | 2 +- .../coyote/http/common/ContentType.java | 26 ++++++++ .../coyote/http/request/HttpRequest.java | 4 ++ .../coyote/http/request/RequestLine.java | 4 ++ .../coyote/http/request/RequestUri.java | 4 ++ .../coyote/http/response/ContentType.java | 20 ------ .../coyote/http/response/HttpResponse.java | 4 +- 10 files changed, 74 insertions(+), 58 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http/common/ContentType.java delete mode 100644 tomcat/src/main/java/org/apache/coyote/http/response/ContentType.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java index fbe14accef..26e4d84f4c 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java @@ -1,8 +1,8 @@ package org.apache.coyote.handler.mapping; +import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java index 7a28c46da6..d70c912fa8 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java @@ -1,65 +1,65 @@ package org.apache.coyote.handler.mapping; +import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; import java.io.IOException; +import static org.apache.coyote.http.common.ContentType.CSS; +import static org.apache.coyote.http.common.ContentType.HTML; +import static org.apache.coyote.http.common.ContentType.ICO; +import static org.apache.coyote.http.common.ContentType.JS; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; public class StaticFileMapping implements HandlerMapping { + private static final String DEFAULT_FILE_PATH = "static"; + @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && - (httpRequest.getRequestUri().getRequestUri().endsWith(".html") || - httpRequest.getRequestUri().getRequestUri().endsWith(".js") || - httpRequest.getRequestUri().getRequestUri().endsWith(".css") || - httpRequest.getRequestUri().getRequestUri().endsWith(".ico") - ); + return httpRequest.isGetRequest() && isStaticFile(httpRequest); + } + + private static boolean isStaticFile(final HttpRequest httpRequest) { + return httpRequest.isRequestUriEndsWith(HTML.getFileExtension()) || + httpRequest.isRequestUriEndsWith(JS.getFileExtension()) || + httpRequest.isRequestUriEndsWith(CSS.getFileExtension()) || + httpRequest.isRequestUriEndsWith(ICO.getFileExtension()); } @Override public HttpResponse handle(final HttpRequest httpRequest) throws IOException { final String requestUri = httpRequest.getRequestUri().getRequestUri(); - final String filePath = "static" + requestUri; + final String filePath = DEFAULT_FILE_PATH + requestUri; - if (requestUri.endsWith(".html")) { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(HttpBody.file(filePath)) - .build(); + if (httpRequest.isRequestUriEndsWith(HTML.getFileExtension())) { + return createHttpResponseByContentTypeAndPath(HTML, filePath); } - if (requestUri.endsWith(".js")) { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.JS.getValue()) - .body(HttpBody.file(filePath)) - .build(); + if (httpRequest.isRequestUriEndsWith(JS.getFileExtension())) { + return createHttpResponseByContentTypeAndPath(JS, filePath); } - if (requestUri.endsWith(".css")) { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.CSS.getValue()) - .body(HttpBody.file(filePath)) - .build(); + if (httpRequest.isRequestUriEndsWith(CSS.getFileExtension())) { + return createHttpResponseByContentTypeAndPath(CSS, filePath); } - if (requestUri.endsWith(".ico")) { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.ICO.getValue()) - .body(HttpBody.file(filePath)) - .build(); + if (httpRequest.isRequestUriEndsWith(ICO.getFileExtension())) { + return createHttpResponseByContentTypeAndPath(ICO, filePath); } return HttpResponse.redirect("/404.html"); } + + private static HttpResponse createHttpResponseByContentTypeAndPath(final ContentType contentType, final String filePath) throws IOException { + return HttpResponse.builder() + .statusLine(StatusLine.from(StatusCode.OK)) + .httpHeaders(CONTENT_TYPE, contentType.getValue()) + .body(HttpBody.file(filePath)) + .build(); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index d3d5fe7b1e..78c4fadd0d 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -3,10 +3,10 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; import org.apache.coyote.handler.mapping.HandlerMapping; +import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpCookie; import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 832dfef11b..23c2833514 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -1,9 +1,9 @@ package org.apache.coyote.handler.mapping.register; import org.apache.coyote.handler.mapping.HandlerMapping; +import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.ContentType; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; diff --git a/tomcat/src/main/java/org/apache/coyote/http/common/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http/common/ContentType.java new file mode 100644 index 0000000000..b1d5bc343f --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http/common/ContentType.java @@ -0,0 +1,26 @@ +package org.apache.coyote.http.common; + +public enum ContentType { + + HTML(".html", "text/html;charset=utf-8"), + CSS(".css", "text/css;charset=utf-8"), + JS(".js", "text/javascript;charset=utf-8"), + ICO(".ico", "image/x-icon"), + ; + + private final String fileExtension; + private final String value; + + ContentType(final String fileExtension, final String value) { + this.fileExtension = fileExtension; + this.value = value; + } + + public String getFileExtension() { + return fileExtension; + } + + public String getValue() { + return value; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index 3b784d2817..562585fcc1 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -30,6 +30,10 @@ public boolean containsRequestUri(final String uri) { return requestLine.containsRequestUri(uri); } + public boolean isRequestUriEndsWith(final String uri) { + return requestLine.endsWithRequestUri(uri); + } + public boolean containsHeader(final HttpHeader headerName) { return headers.containsKey(headerName); } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index e2377e36a9..ca4537390c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -31,6 +31,10 @@ public boolean containsRequestUri(final String uri) { return requestUri.contains(uri); } + public boolean endsWithRequestUri(final String uri) { + return requestUri.endsWith(uri); + } + public RequestUri getRequestUri() { return requestUri; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java index 3bd4ee9029..c79d6f07ab 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java @@ -12,6 +12,10 @@ public boolean contains(final String uri) { return requestUri.contains(uri); } + public boolean endsWith(final String uri) { + return requestUri.endsWith(uri); + } + public String getRequestUri() { return requestUri; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http/response/ContentType.java deleted file mode 100644 index 7a3bf0e35d..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http/response/ContentType.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.apache.coyote.http.response; - -public enum ContentType { - - HTML("text/html;charset=utf-8"), - CSS("text/css;charset=utf-8"), - JS("text/javascript;charset=utf-8"), - ICO("image/x-icon"), - ; - - private final String value; - - ContentType(final String value) { - this.value = value; - } - - public String getValue() { - return value; - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java index 6d307fdef6..dc3ce1b16c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java @@ -4,8 +4,6 @@ import org.apache.coyote.http.common.HttpHeader; import org.apache.coyote.http.common.HttpHeaders; -import java.util.Map; - public class HttpResponse { public static final String SPACE = " "; @@ -26,7 +24,7 @@ public class HttpResponse { public static HttpResponse redirect(final String redirectUri) { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.FOUND)) - .httpHeaders(new HttpHeaders(Map.of(HttpHeader.LOCATION, redirectUri))) + .httpHeaders(HttpHeader.LOCATION, redirectUri) .body(HttpBody.empty()) .build(); } From 0b1b0e66e2e8507351a15a87e2db4ab882f8de99 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:43:34 +0900 Subject: [PATCH 11/43] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=EC=9D=98?= =?UTF-8?q?=20=EC=A0=91=EA=B7=BC=20=EC=A0=9C=ED=95=9C=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?private=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cache/com/example/version/CacheBustingWebConfig.java | 4 ++-- .../apache/coyote/handler/mapping/login/LoginMapping.java | 2 +- .../coyote/handler/mapping/login/LoginPageMapping.java | 2 +- .../coyote/handler/mapping/register/RegisterMapping.java | 2 +- .../handler/mapping/register/RegisterPageMapping.java | 2 +- .../org/apache/coyote/http/response/HttpResponse.java | 8 ++++---- .../java/org/apache/coyote/http11/HttpRequestParser.java | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java index d7e238c887..2571acd023 100644 --- a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java +++ b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java @@ -11,8 +11,8 @@ @Configuration public class CacheBustingWebConfig implements WebMvcConfigurer { - public static final String PREFIX_STATIC_RESOURCES = "/resources"; - public static final Long MAX_AGE = 365L; + private static final String PREFIX_STATIC_RESOURCES = "/resources"; + private static final Long MAX_AGE = 365L; private final ResourceVersion version; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java index ce64f3fb1b..770d123f85 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java @@ -18,7 +18,7 @@ public class LoginMapping extends LoginFilter implements HandlerMapping { - public static final String TARGET_URI = "login"; + private static final String TARGET_URI = "login"; private static final Logger log = LoggerFactory.getLogger(LoginMapping.class); @Override diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index 78c4fadd0d..fec4d5cb00 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -23,7 +23,7 @@ public class LoginPageMapping extends LoginFilter implements HandlerMapping { - public static final String TARGET_URI = "login"; + private static final String TARGET_URI = "login"; private static final Logger log = LoggerFactory.getLogger(LoginPageMapping.class); @Override diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java index 4be728cf1a..2cceea8bb3 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java @@ -11,7 +11,7 @@ public class RegisterMapping implements HandlerMapping { - public static final String TARGET_URI = "register"; + private static final String TARGET_URI = "register"; @Override public boolean supports(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 23c2833514..3fd4c0638d 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -14,7 +14,7 @@ public class RegisterPageMapping implements HandlerMapping { - public static final String TARGET_URI = "register"; + private static final String TARGET_URI = "register"; @Override public boolean supports(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java index dc3ce1b16c..073f2865d7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java @@ -6,10 +6,10 @@ public class HttpResponse { - public static final String SPACE = " "; - public static final String HEADER_DELIMETER = ": "; - public static final String CRLF = "\r\n"; - public static final String BLANK_LINE = ""; + private static final String SPACE = " "; + private static final String HEADER_DELIMETER = ": "; + private static final String CRLF = "\r\n"; + private static final String BLANK_LINE = ""; private final StatusLine statusLine; private final HttpHeaders httpHeaders; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java index 67d1e8bd95..2979ee1c43 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequestParser.java @@ -18,7 +18,7 @@ public class HttpRequestParser { - public static final String SPACE = " "; + private static final String SPACE = " "; public HttpRequestParser() { } From 2d9e91c6ef73c4602bd16ced602ea4fb4025e773 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 15:52:25 +0900 Subject: [PATCH 12/43] =?UTF-8?q?refactor:=20HomePageMapping=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B2=BD=EB=A1=9C=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/handler/mapping/HomePageMapping.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java index 26e4d84f4c..6e9ea9a331 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java @@ -13,9 +13,12 @@ public class HomePageMapping implements HandlerMapping { + private static final String HOME_MESSAGE = "Hello world!"; + private static final String TARGET_URI = "/"; + @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && "/".equals(httpRequest.getRequestUri().getRequestUri()); + return httpRequest.isGetRequest() && TARGET_URI.equals(httpRequest.getRequestUri().getRequestUri()); } @Override @@ -23,7 +26,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(new HttpBody("Hello world!")) + .body(new HttpBody(HOME_MESSAGE)) .build(); } } From 8a1647e5fba306645e93f8edd6abb61e3fcb8586 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 16:08:55 +0900 Subject: [PATCH 13/43] =?UTF-8?q?refactor:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20Path=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/handler/FrontHandler.java | 4 +++- .../apache/coyote/handler/mapping/Path.java | 21 +++++++++++++++++++ .../handler/mapping/StaticFileMapping.java | 4 +--- .../handler/mapping/login/LoginMapping.java | 7 +++++-- .../mapping/login/LoginPageMapping.java | 11 ++++++---- .../mapping/register/RegisterMapping.java | 4 +++- .../mapping/register/RegisterPageMapping.java | 3 ++- .../apache/coyote/http/common/HttpBody.java | 3 ++- 8 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index f758870881..1f41303a5d 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -14,6 +14,8 @@ import java.util.HashSet; import java.util.Set; +import static org.apache.coyote.handler.mapping.Path.NOT_FOUND; + public class FrontHandler { private static final Set handlerMapping = new HashSet<>(); @@ -34,6 +36,6 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { } } - return HttpResponse.redirect("/404.html"); + return HttpResponse.redirect(NOT_FOUND.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java new file mode 100644 index 0000000000..489f6ce33d --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java @@ -0,0 +1,21 @@ +package org.apache.coyote.handler.mapping; + +public enum Path { + + HOME("/"), + MAIN("/index.html"), + LOGIN("/login.html"), + REGISTER("/register.html"), + UNAUTHORIZED("/401.html"), + NOT_FOUND("/404.html"); + + private final String path; + + Path(final String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java index d70c912fa8..0b276bfc01 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java @@ -17,7 +17,6 @@ public class StaticFileMapping implements HandlerMapping { - private static final String DEFAULT_FILE_PATH = "static"; @Override public boolean supports(final HttpRequest httpRequest) { @@ -33,8 +32,7 @@ private static boolean isStaticFile(final HttpRequest httpRequest) { @Override public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - final String requestUri = httpRequest.getRequestUri().getRequestUri(); - final String filePath = DEFAULT_FILE_PATH + requestUri; + final String filePath = httpRequest.getRequestUri().getRequestUri(); if (httpRequest.isRequestUriEndsWith(HTML.getFileExtension())) { return createHttpResponseByContentTypeAndPath(HTML, filePath); diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java index 770d123f85..7e009034f2 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java @@ -16,6 +16,9 @@ import java.util.Map; import java.util.UUID; +import static org.apache.coyote.handler.mapping.Path.MAIN; +import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; + public class LoginMapping extends LoginFilter implements HandlerMapping { private static final String TARGET_URI = "login"; @@ -43,7 +46,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { log.info("로그인 성공! user = {}", user); } catch (final IllegalArgumentException e) { log.warn("login error = {}", e); - return HttpResponse.redirect("/401.html"); + return HttpResponse.redirect(UNAUTHORIZED.getPath()); } final UUID uuid = UUID.randomUUID(); @@ -51,7 +54,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.FOUND)) - .httpHeaders(HttpHeader.LOCATION, "/index.html") + .httpHeaders(HttpHeader.LOCATION, MAIN.getPath()) .httpHeaders(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid) .body(HttpBody.empty()) .build(); diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index fec4d5cb00..9bfc94719e 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -18,6 +18,9 @@ import java.util.Map; import java.util.stream.Collectors; +import static org.apache.coyote.handler.mapping.Path.LOGIN; +import static org.apache.coyote.handler.mapping.Path.MAIN; +import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; import static org.apache.coyote.http.common.HttpHeader.COOKIE; @@ -36,7 +39,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { if (httpRequest.containsHeader(COOKIE)) { final HttpCookie cookies = HttpCookie.from(httpRequest.getHeader(COOKIE)); if (isAlreadyLogined(cookies.get("JSESSIONID"))) { - return HttpResponse.redirect("/index.html"); + return HttpResponse.redirect(MAIN.getPath()); } } @@ -59,16 +62,16 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { log.info("로그인 성공! user = {}", user); } catch (final IllegalArgumentException e) { log.warn("login error = {}", e); - return HttpResponse.redirect("/401.html"); + return HttpResponse.redirect(UNAUTHORIZED.getPath()); } - return HttpResponse.redirect("/index.html"); + return HttpResponse.redirect(MAIN.getPath()); } return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(HttpBody.file("static/login.html")) + .body(HttpBody.file(LOGIN.getPath())) .build(); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java index 2cceea8bb3..2ecd13cd9d 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java @@ -9,6 +9,8 @@ import java.io.IOException; import java.util.Map; +import static org.apache.coyote.handler.mapping.Path.MAIN; + public class RegisterMapping implements HandlerMapping { private static final String TARGET_URI = "register"; @@ -29,6 +31,6 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { final User user = new User(account, password, email); InMemoryUserRepository.save(user); - return HttpResponse.redirect("/index.html"); + return HttpResponse.redirect(MAIN.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 3fd4c0638d..1a68091488 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -10,6 +10,7 @@ import java.io.IOException; +import static org.apache.coyote.handler.mapping.Path.REGISTER; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; public class RegisterPageMapping implements HandlerMapping { @@ -26,7 +27,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { return HttpResponse.builder() .statusLine(StatusLine.from(StatusCode.OK)) .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(HttpBody.file("static/register.html")) + .body(HttpBody.file(REGISTER.getPath())) .build(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http/common/HttpBody.java b/tomcat/src/main/java/org/apache/coyote/http/common/HttpBody.java index 0852cf1d22..fa73114df9 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/common/HttpBody.java +++ b/tomcat/src/main/java/org/apache/coyote/http/common/HttpBody.java @@ -20,7 +20,8 @@ public HttpBody(final String value) { } public static HttpBody file(final String filePath) throws IOException { - final URL fileUrl = HttpBody.class.getClassLoader().getResource(filePath); + final String defaultFilePath = "static"; + final URL fileUrl = HttpBody.class.getClassLoader().getResource(defaultFilePath + filePath); final Path path = new File(fileUrl.getPath()).toPath(); return new HttpBody(new String(Files.readAllBytes(path))); } From 10bb2f296ea7fbdff2dab93a506bd159318d78e1 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 16:15:35 +0900 Subject: [PATCH 14/43] =?UTF-8?q?refactor:=20requestLine=20=EB=B9=88=20?= =?UTF-8?q?=EC=A4=84=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/coyote/http/request/RequestLine.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index ca4537390c..94c1a2d03e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -6,7 +6,6 @@ public class RequestLine { private final HttpMethod httpMethod; private final RequestUri requestUri; - private final Protocol protocol; public RequestLine(final HttpMethod httpMethod, final RequestUri requestUri, final Protocol protocol) { From 2f774c9dc203e8860eb70c1baa5f0a65220a180c Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 16:36:49 +0900 Subject: [PATCH 15/43] =?UTF-8?q?refactor:=20QueryString=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapping/login/LoginPageMapping.java | 16 +++++----------- .../coyote/http/request/HttpRequest.java | 8 ++++++++ .../coyote/http/request/QueryString.java | 19 +++++++++++++++++++ .../coyote/http/request/RequestLine.java | 4 ++++ .../coyote/http/request/RequestUri.java | 14 ++++++++++++++ 5 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http/request/QueryString.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index 9bfc94719e..e19c270e81 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -7,6 +7,7 @@ import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpCookie; import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.QueryString; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; @@ -14,9 +15,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.Arrays; -import java.util.Map; -import java.util.stream.Collectors; import static org.apache.coyote.handler.mapping.Path.LOGIN; import static org.apache.coyote.handler.mapping.Path.MAIN; @@ -43,14 +41,11 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { } } - final String[] parsedRequestUri = httpRequest.getRequestUri().getRequestUri().split("\\?"); - if (httpRequest.getRequestUri().getRequestUri().contains("?")) { - final Map queryStrings = Arrays.stream(parsedRequestUri[1].split("&")) - .map(param -> param.split("=")) - .collect(Collectors.toMap(param -> param[0], param -> param[1])); + if (httpRequest.hasQueryString()) { + final QueryString queryString = httpRequest.getQueryString(); - final String account = queryStrings.get("account"); - final String password = queryStrings.get("password"); + final String account = queryString.get("account"); + final String password = queryString.get("password"); try { final User user = InMemoryUserRepository.findByAccount(account) @@ -74,5 +69,4 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { .body(HttpBody.file(LOGIN.getPath())) .build(); } - } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index 562585fcc1..8c38a27250 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -30,6 +30,10 @@ public boolean containsRequestUri(final String uri) { return requestLine.containsRequestUri(uri); } + public boolean hasQueryString() { + return requestLine.containsRequestUri("?"); + } + public boolean isRequestUriEndsWith(final String uri) { return requestLine.endsWithRequestUri(uri); } @@ -42,6 +46,10 @@ public String getHeader(final HttpHeader httpHeader) { return headers.get(httpHeader); } + public QueryString getQueryString() { + return requestLine.getQueryString(); + } + public Map getParsedBody() { return httpBody.parseBodyParameters(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/QueryString.java b/tomcat/src/main/java/org/apache/coyote/http/request/QueryString.java new file mode 100644 index 0000000000..4655dc71e8 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http/request/QueryString.java @@ -0,0 +1,19 @@ +package org.apache.coyote.http.request; + +import java.util.Map; + +public class QueryString { + + private final Map values; + + public QueryString(final Map values) { + this.values = values; + } + + public String get(final String key) { + if (!values.containsKey(key)) { + throw new IllegalStateException("HttpRequest 에 존재하지 않는 queryString 입니다."); + } + return values.get(key); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index 94c1a2d03e..0df38c0ac5 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -34,6 +34,10 @@ public boolean endsWithRequestUri(final String uri) { return requestUri.endsWith(uri); } + public QueryString getQueryString() { + return requestUri.getQueryString(); + } + public RequestUri getRequestUri() { return requestUri; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java index c79d6f07ab..838902ac16 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestUri.java @@ -1,5 +1,9 @@ package org.apache.coyote.http.request; +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + public class RequestUri { private final String requestUri; @@ -16,6 +20,16 @@ public boolean endsWith(final String uri) { return requestUri.endsWith(uri); } + public QueryString getQueryString() { + final String[] parsedRequestUri = requestUri.split("\\?"); + + final Map queryStrings = Arrays.stream(parsedRequestUri[1].split("&")) + .map(param -> param.split("=")) + .collect(Collectors.toMap(param -> param[0], param -> param[1])); + + return new QueryString(queryStrings); + } + public String getRequestUri() { return requestUri; } From f7d6fc22f9fb03b4fba82c2c0eb553bd98b7385d Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 17:06:33 +0900 Subject: [PATCH 16/43] =?UTF-8?q?refactor:=20keySet()=EC=9D=84=20entrySet(?= =?UTF-8?q?)=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/coyote/handler/mapping/login/LoginFilter.java | 4 ++-- .../apache/coyote/handler/mapping/login/LoginPageMapping.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java index ecfacaea38..4e6f4f074a 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java @@ -16,8 +16,8 @@ protected boolean isAlreadyLogined(final String jSessionId) { protected void setSession(final String jSessionId, final Map sessionData) { final Session session = new Session(jSessionId); - for (final String key : sessionData.keySet()) { - session.add(key, sessionData.get(key)); + for (final Map.Entry entry : sessionData.entrySet()) { + session.add(entry.getKey(), entry.getValue()); } loginManager.add(session); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index e19c270e81..9a3f840d89 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -46,7 +46,7 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { final String account = queryString.get("account"); final String password = queryString.get("password"); - + try { final User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); From da45451d541d59364d14d95c14e6c2075d4b77d5 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 21:09:36 +0900 Subject: [PATCH 17/43] =?UTF-8?q?feat:=20Controller=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/handler/AbstractController.java | 27 +++++++++++++++++++ .../org/apache/coyote/handler/Controller.java | 9 +++++++ 2 files changed, 36 insertions(+) create mode 100644 tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/handler/Controller.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java new file mode 100644 index 0000000000..94d77b7b74 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java @@ -0,0 +1,27 @@ +package org.apache.coyote.handler; + +import org.apache.coyote.http.request.HttpMethod; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.response.HttpResponse; + +public abstract class AbstractController implements Controller { + + @Override + public void service(final HttpRequest request, final HttpResponse httpResponse) throws Exception { + if (request.isSameRequestMethod(HttpMethod.GET)) { + doGet(request, httpResponse); + return; + } + + if (request.isSameRequestMethod(HttpMethod.POST)) { + doPost(request, httpResponse); + return; + } + + throw new UnsupportedOperationException("지원하지 않는 HTTP Method 입니다."); + } + + protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; + + protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; +} diff --git a/tomcat/src/main/java/org/apache/coyote/handler/Controller.java b/tomcat/src/main/java/org/apache/coyote/handler/Controller.java new file mode 100644 index 0000000000..9e590eb157 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/handler/Controller.java @@ -0,0 +1,9 @@ +package org.apache.coyote.handler; + +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.response.HttpResponse; + +public interface Controller { + + void service(final HttpRequest request, final HttpResponse response) throws Exception; +} From 23216a75093556315f7faffb3ee1a30a05967239 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 22:13:05 +0900 Subject: [PATCH 18/43] =?UTF-8?q?refactor:=20AbstractController=20?= =?UTF-8?q?=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/handler/AbstractController.java | 7 +-- .../apache/coyote/handler/FrontHandler.java | 25 +++++----- .../handler/mapping/HomePageMapping.java | 22 +++++---- .../handler/mapping/StaticFileMapping.java | 45 ++++++++++------- .../handler/mapping/login/LoginMapping.java | 40 ++++++++++----- .../mapping/login/LoginPageMapping.java | 49 ++++++++++++------- .../mapping/register/RegisterMapping.java | 17 ++++--- .../mapping/register/RegisterPageMapping.java | 15 +++++- .../coyote/http/request/HttpRequest.java | 4 ++ .../coyote/http/request/RequestLine.java | 4 ++ .../coyote/http/response/HttpResponse.java | 49 ++++++++++++------- .../apache/coyote/http11/Http11Processor.java | 11 ++--- 12 files changed, 180 insertions(+), 108 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java index 94d77b7b74..fe06a89217 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java @@ -7,20 +7,21 @@ public abstract class AbstractController implements Controller { @Override - public void service(final HttpRequest request, final HttpResponse httpResponse) throws Exception { + public void service(final HttpRequest request, final HttpResponse response) throws Exception { if (request.isSameRequestMethod(HttpMethod.GET)) { - doGet(request, httpResponse); + doGet(request, response); return; } if (request.isSameRequestMethod(HttpMethod.POST)) { - doPost(request, httpResponse); + doPost(request, response); return; } throw new UnsupportedOperationException("지원하지 않는 HTTP Method 입니다."); } + protected abstract boolean supports(final HttpRequest httpRequest); protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 1f41303a5d..98d893a9fb 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -1,6 +1,5 @@ package org.apache.coyote.handler; -import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.handler.mapping.HomePageMapping; import org.apache.coyote.handler.mapping.StaticFileMapping; import org.apache.coyote.handler.mapping.login.LoginMapping; @@ -10,7 +9,6 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; -import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -18,24 +16,25 @@ public class FrontHandler { - private static final Set handlerMapping = new HashSet<>(); + private static final Set requestControllers = new HashSet<>(); static { - handlerMapping.add(new HomePageMapping()); - handlerMapping.add(new StaticFileMapping()); - handlerMapping.add(new LoginMapping()); - handlerMapping.add(new LoginPageMapping()); - handlerMapping.add(new RegisterMapping()); - handlerMapping.add(new RegisterPageMapping()); + requestControllers.add(new HomePageMapping()); + requestControllers.add(new StaticFileMapping()); + requestControllers.add(new LoginMapping()); + requestControllers.add(new LoginPageMapping()); + requestControllers.add(new RegisterMapping()); + requestControllers.add(new RegisterPageMapping()); } - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - for (final HandlerMapping mapping : handlerMapping) { + public void handle(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception { + for (final AbstractController mapping : requestControllers) { if (mapping.supports(httpRequest)) { - return mapping.handle(httpRequest); + mapping.service(httpRequest, httpResponse); + return; } } - return HttpResponse.redirect(NOT_FOUND.getPath()); + httpResponse.mapToRedirect(NOT_FOUND.getPath()); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java index 6e9ea9a331..00b52c5fee 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java @@ -1,5 +1,6 @@ package org.apache.coyote.handler.mapping; +import org.apache.coyote.handler.AbstractController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -7,26 +8,27 @@ import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; -import java.io.IOException; - import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class HomePageMapping implements HandlerMapping { +public class HomePageMapping extends AbstractController { private static final String HOME_MESSAGE = "Hello world!"; private static final String TARGET_URI = "/"; @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && TARGET_URI.equals(httpRequest.getRequestUri().getRequestUri()); + return TARGET_URI.equals(httpRequest.getRequestUri().getRequestUri()); + } + + @Override + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); } @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(new HttpBody(HOME_MESSAGE)) - .build(); + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(new HttpBody(HOME_MESSAGE)); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java index 0b276bfc01..debeb005fd 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java @@ -1,5 +1,6 @@ package org.apache.coyote.handler.mapping; +import org.apache.coyote.handler.AbstractController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -15,8 +16,7 @@ import static org.apache.coyote.http.common.ContentType.JS; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class StaticFileMapping implements HandlerMapping { - +public class StaticFileMapping extends AbstractController { @Override public boolean supports(final HttpRequest httpRequest) { @@ -31,33 +31,40 @@ private static boolean isStaticFile(final HttpRequest httpRequest) { } @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - final String filePath = httpRequest.getRequestUri().getRequestUri(); + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + final String filePath = request.getRequestUri().getRequestUri(); - if (httpRequest.isRequestUriEndsWith(HTML.getFileExtension())) { - return createHttpResponseByContentTypeAndPath(HTML, filePath); + if (request.isRequestUriEndsWith(HTML.getFileExtension())) { + createHttpResponseByContentTypeAndPath(response, HTML, filePath); + return; } - if (httpRequest.isRequestUriEndsWith(JS.getFileExtension())) { - return createHttpResponseByContentTypeAndPath(JS, filePath); + if (request.isRequestUriEndsWith(JS.getFileExtension())) { + createHttpResponseByContentTypeAndPath(response, JS, filePath); + return; } - if (httpRequest.isRequestUriEndsWith(CSS.getFileExtension())) { - return createHttpResponseByContentTypeAndPath(CSS, filePath); + if (request.isRequestUriEndsWith(CSS.getFileExtension())) { + createHttpResponseByContentTypeAndPath(response, CSS, filePath); + return; } - if (httpRequest.isRequestUriEndsWith(ICO.getFileExtension())) { - return createHttpResponseByContentTypeAndPath(ICO, filePath); + if (request.isRequestUriEndsWith(ICO.getFileExtension())) { + createHttpResponseByContentTypeAndPath(response, ICO, filePath); + return; } - return HttpResponse.redirect("/404.html"); + response.mapToRedirect("/404.html"); } - private static HttpResponse createHttpResponseByContentTypeAndPath(final ContentType contentType, final String filePath) throws IOException { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, contentType.getValue()) - .body(HttpBody.file(filePath)) - .build(); + private void createHttpResponseByContentTypeAndPath(final HttpResponse response, final ContentType contentType, final String filePath) throws IOException { + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, contentType.getValue()); + response.changeBody(HttpBody.file(filePath)); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java index 7e009034f2..5e6105c9a8 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java @@ -2,24 +2,28 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.mapping.HandlerMapping; +import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeader; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; +import org.apache.coyote.http.session.Session; +import org.apache.coyote.http.session.SessionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Map; import java.util.UUID; import static org.apache.coyote.handler.mapping.Path.MAIN; import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; -public class LoginMapping extends LoginFilter implements HandlerMapping { +public class LoginMapping extends AbstractController { + + private static final LoginManager loginManager = new SessionManager(); private static final String TARGET_URI = "login"; private static final Logger log = LoggerFactory.getLogger(LoginMapping.class); @@ -30,8 +34,8 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - final Map bodyParams = httpRequest.getParsedBody(); + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + final Map bodyParams = request.getParsedBody(); final String account = bodyParams.get("account"); final String password = bodyParams.get("password"); @@ -46,17 +50,29 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { log.info("로그인 성공! user = {}", user); } catch (final IllegalArgumentException e) { log.warn("login error = {}", e); - return HttpResponse.redirect(UNAUTHORIZED.getPath()); + response.mapToRedirect(UNAUTHORIZED.getPath()); + return; } final UUID uuid = UUID.randomUUID(); setSession(uuid.toString(), Map.of("account", user.getAccount())); - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.FOUND)) - .httpHeaders(HttpHeader.LOCATION, MAIN.getPath()) - .httpHeaders(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid) - .body(HttpBody.empty()) - .build(); + response.changeStatusLine(StatusLine.from(StatusCode.FOUND)); + response.addHeader(HttpHeader.LOCATION, MAIN.getPath()); + response.addHeader(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid); + response.changeBody(HttpBody.empty()); + } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); + } + + protected void setSession(final String jSessionId, final Map sessionData) { + final Session session = new Session(jSessionId); + for (final Map.Entry entry : sessionData.entrySet()) { + session.add(entry.getKey(), entry.getValue()); + } + loginManager.add(session); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java index 9a3f840d89..f23ffea483 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java @@ -2,7 +2,8 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.mapping.HandlerMapping; +import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpCookie; @@ -11,20 +12,22 @@ import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; +import org.apache.coyote.http.session.SessionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; - import static org.apache.coyote.handler.mapping.Path.LOGIN; import static org.apache.coyote.handler.mapping.Path.MAIN; import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; import static org.apache.coyote.http.common.HttpHeader.COOKIE; -public class LoginPageMapping extends LoginFilter implements HandlerMapping { +public class LoginPageMapping extends AbstractController { + + private static final LoginManager loginManager = new SessionManager(); private static final String TARGET_URI = "login"; + private static final Logger log = LoggerFactory.getLogger(LoginPageMapping.class); @Override @@ -33,20 +36,26 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - if (httpRequest.containsHeader(COOKIE)) { - final HttpCookie cookies = HttpCookie.from(httpRequest.getHeader(COOKIE)); + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + if (request.containsHeader(COOKIE)) { + final HttpCookie cookies = HttpCookie.from(request.getHeader(COOKIE)); if (isAlreadyLogined(cookies.get("JSESSIONID"))) { - return HttpResponse.redirect(MAIN.getPath()); + response.mapToRedirect(MAIN.getPath()); + return; } } - if (httpRequest.hasQueryString()) { - final QueryString queryString = httpRequest.getQueryString(); + if (request.hasQueryString()) { + final QueryString queryString = request.getQueryString(); final String account = queryString.get("account"); final String password = queryString.get("password"); - + try { final User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); @@ -57,16 +66,20 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { log.info("로그인 성공! user = {}", user); } catch (final IllegalArgumentException e) { log.warn("login error = {}", e); - return HttpResponse.redirect(UNAUTHORIZED.getPath()); + response.mapToRedirect(UNAUTHORIZED.getPath()); + return; } - return HttpResponse.redirect(MAIN.getPath()); + response.mapToRedirect(MAIN.getPath()); + return; } - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(HttpBody.file(LOGIN.getPath())) - .build(); + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(HttpBody.file(LOGIN.getPath())); + } + + protected boolean isAlreadyLogined(final String jSessionId) { + return loginManager.isAlreadyLogined(jSessionId); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java index 2ecd13cd9d..640ec319b4 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java @@ -2,17 +2,15 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.mapping.HandlerMapping; +import org.apache.coyote.handler.AbstractController; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; -import java.io.IOException; import java.util.Map; import static org.apache.coyote.handler.mapping.Path.MAIN; -public class RegisterMapping implements HandlerMapping { - +public class RegisterMapping extends AbstractController { private static final String TARGET_URI = "register"; @Override @@ -21,8 +19,8 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - final Map bodyParams = httpRequest.getParsedBody(); + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + final Map bodyParams = request.getParsedBody(); final String account = bodyParams.get("account"); final String password = bodyParams.get("password"); @@ -31,6 +29,11 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { final User user = new User(account, password, email); InMemoryUserRepository.save(user); - return HttpResponse.redirect(MAIN.getPath()); + response.mapToRedirect(MAIN.getPath()); + } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 1a68091488..81d8bac798 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -1,5 +1,6 @@ package org.apache.coyote.handler.mapping.register; +import org.apache.coyote.handler.AbstractController; import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; @@ -13,7 +14,7 @@ import static org.apache.coyote.handler.mapping.Path.REGISTER; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class RegisterPageMapping implements HandlerMapping { +public class RegisterPageMapping extends AbstractController implements HandlerMapping { private static final String TARGET_URI = "register"; @@ -30,4 +31,16 @@ public HttpResponse handle(final HttpRequest httpRequest) throws IOException { .body(HttpBody.file(REGISTER.getPath())) .build(); } + + @Override + protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(HttpBody.file(REGISTER.getPath())); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index 8c38a27250..3e637831da 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -18,6 +18,10 @@ public HttpRequest(final RequestLine requestLine, final HttpHeaders headers, fin this.httpBody = httpBody; } + public boolean isSameRequestMethod(final HttpMethod httpMethod) { + return requestLine.isSameRequestMethod(httpMethod); + } + public boolean isPostRequest() { return requestLine.isPostMethod(); } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index 0df38c0ac5..8ff726cc48 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -18,6 +18,10 @@ public HttpMethod getHttpMethod() { return httpMethod; } + public boolean isSameRequestMethod(final HttpMethod httpMethod) { + return this.httpMethod == httpMethod; + } + public boolean isPostMethod() { return httpMethod == HttpMethod.POST; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java index 073f2865d7..e42ac9dc10 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java @@ -4,6 +4,8 @@ import org.apache.coyote.http.common.HttpHeader; import org.apache.coyote.http.common.HttpHeaders; +import java.util.EnumMap; + public class HttpResponse { private static final String SPACE = " "; @@ -11,9 +13,12 @@ public class HttpResponse { private static final String CRLF = "\r\n"; private static final String BLANK_LINE = ""; - private final StatusLine statusLine; - private final HttpHeaders httpHeaders; - private final HttpBody body; + private StatusLine statusLine; + private HttpHeaders httpHeaders; + private HttpBody body; + + public HttpResponse() { + } HttpResponse(final StatusLine statusLine, final HttpHeaders httpHeaders, final HttpBody body) { this.statusLine = statusLine; @@ -21,12 +26,26 @@ public class HttpResponse { this.body = body; } - public static HttpResponse redirect(final String redirectUri) { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.FOUND)) - .httpHeaders(HttpHeader.LOCATION, redirectUri) - .body(HttpBody.empty()) - .build(); + public void mapToRedirect(final String redirectUri) { + changeStatusLine(StatusLine.from(StatusCode.FOUND)); + addHeader(HttpHeader.LOCATION, redirectUri); + changeBody(HttpBody.empty()); + } + + public void changeStatusLine(final StatusLine statusLine) { + this.statusLine = statusLine; + } + + public void addHeader(final HttpHeader httpHeader, final String value) { + if (httpHeaders == null) { + this.httpHeaders = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + } + + this.httpHeaders.add(httpHeader, value); + } + + public void changeBody(final HttpBody body) { + this.body = body; } public static HttpResponseBuilder builder() { @@ -43,10 +62,7 @@ public String serialize() { return response.toString(); } - response.append(HttpHeader.CONTENT_LENGTH.getValue()) - .append(HEADER_DELIMETER) - .append(body.getValue().getBytes().length) - .append(SPACE).append(CRLF); + response.append(HttpHeader.CONTENT_LENGTH.getValue()).append(HEADER_DELIMETER).append(body.getValue().getBytes().length).append(SPACE).append(CRLF); serializeBody(response); return response.toString(); @@ -59,12 +75,7 @@ private void serializeStatusLine(final StringBuilder response) { } private void serializeHeaders(final StringBuilder response) { - httpHeaders.getHeaders().forEach((key, value) -> response.append(key.getValue()) - .append(HEADER_DELIMETER) - .append(value) - .append(SPACE) - .append(CRLF) - ); + httpHeaders.getHeaders().forEach((key, value) -> response.append(key.getValue()).append(HEADER_DELIMETER).append(value).append(SPACE).append(CRLF)); } private void serializeBody(final StringBuilder response) { 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 0c290c29a0..96fa1a0043 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,6 +1,5 @@ package org.apache.coyote.http11; -import nextstep.jwp.exception.UncheckedServletException; import org.apache.coyote.Processor; import org.apache.coyote.handler.FrontHandler; import org.apache.coyote.http.request.HttpRequest; @@ -9,7 +8,6 @@ import org.slf4j.LoggerFactory; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; @@ -37,18 +35,19 @@ public void run() { public void process(final Socket connection) { try (final var inputStream = connection.getInputStream(); final var outputStream = connection.getOutputStream(); - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) ) { final HttpRequest httpRequest = httpRequestParser.parseHttpRequest(bufferedReader); if (httpRequest == null) { return; } - final HttpResponse response = frontHandler.handle(httpRequest); + final HttpResponse httpResponse = new HttpResponse(); + frontHandler.handle(httpRequest, httpResponse); - outputStream.write(response.serialize().getBytes()); + outputStream.write(httpResponse.serialize().getBytes()); outputStream.flush(); - } catch (IOException | UncheckedServletException e) { + } catch (final Exception e) { log.error(e.getMessage(), e); } } From 41804729b3904b5fe9a9ed0fa76608ae30c75163 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 7 Sep 2023 22:17:54 +0900 Subject: [PATCH 19/43] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/mapping/HandlerMapping.java | 13 ---------- .../handler/mapping/login/LoginFilter.java | 24 ------------------- .../mapping/register/RegisterPageMapping.java | 14 +---------- 3 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/handler/mapping/HandlerMapping.java delete mode 100644 tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HandlerMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/HandlerMapping.java deleted file mode 100644 index 7a006efb4d..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HandlerMapping.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.apache.coyote.handler.mapping; - -import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.HttpResponse; - -import java.io.IOException; - -public interface HandlerMapping { - - boolean supports(final HttpRequest httpRequest); - - HttpResponse handle(final HttpRequest httpRequest) throws IOException; -} diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java deleted file mode 100644 index 4e6f4f074a..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginFilter.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.apache.coyote.handler.mapping.login; - -import org.apache.coyote.http.LoginManager; -import org.apache.coyote.http.session.Session; -import org.apache.coyote.http.session.SessionManager; - -import java.util.Map; - -public abstract class LoginFilter { - - private static final LoginManager loginManager = new SessionManager(); - - protected boolean isAlreadyLogined(final String jSessionId) { - return loginManager.isAlreadyLogined(jSessionId); - } - - protected void setSession(final String jSessionId, final Map sessionData) { - final Session session = new Session(jSessionId); - for (final Map.Entry entry : sessionData.entrySet()) { - session.add(entry.getKey(), entry.getValue()); - } - loginManager.add(session); - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java index 81d8bac798..3ce070afc8 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java @@ -1,7 +1,6 @@ package org.apache.coyote.handler.mapping.register; import org.apache.coyote.handler.AbstractController; -import org.apache.coyote.handler.mapping.HandlerMapping; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -9,12 +8,10 @@ import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; -import java.io.IOException; - import static org.apache.coyote.handler.mapping.Path.REGISTER; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class RegisterPageMapping extends AbstractController implements HandlerMapping { +public class RegisterPageMapping extends AbstractController { private static final String TARGET_URI = "register"; @@ -23,15 +20,6 @@ public boolean supports(final HttpRequest httpRequest) { return httpRequest.isGetRequest() && httpRequest.containsRequestUri(TARGET_URI); } - @Override - public HttpResponse handle(final HttpRequest httpRequest) throws IOException { - return HttpResponse.builder() - .statusLine(StatusLine.from(StatusCode.OK)) - .httpHeaders(CONTENT_TYPE, ContentType.HTML.getValue()) - .body(HttpBody.file(REGISTER.getPath())) - .build(); - } - @Override protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { throw new UnsupportedOperationException(); From 0e0cb5b3683c49e5f80d1826e1742b53b8ca0be3 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 08:36:39 +0900 Subject: [PATCH 20/43] =?UTF-8?q?refactor:=20Mapping=20=EC=9D=84=20Control?= =?UTF-8?q?ler=20=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/handler/FrontHandler.java | 30 +++++++++---------- ...Controller.java => RequestController.java} | 3 +- .../HomePageController.java} | 6 ++-- .../handler/{mapping => controller}/Path.java | 2 +- .../StaticFileController.java} | 6 ++-- .../login/LoginController.java} | 12 ++++---- .../login/LoginPageController.java} | 14 ++++----- .../register/RegisterController.java} | 8 ++--- .../register/RegisterPageController.java} | 8 ++--- 9 files changed, 45 insertions(+), 44 deletions(-) rename tomcat/src/main/java/org/apache/coyote/handler/{AbstractController.java => RequestController.java} (93%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/HomePageMapping.java => controller/HomePageController.java} (87%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping => controller}/Path.java (87%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/StaticFileMapping.java => controller/StaticFileController.java} (94%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/login/LoginMapping.java => controller/login/LoginController.java} (90%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/login/LoginPageMapping.java => controller/login/LoginPageController.java} (88%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/register/RegisterMapping.java => controller/register/RegisterController.java} (83%) rename tomcat/src/main/java/org/apache/coyote/handler/{mapping/register/RegisterPageMapping.java => controller/register/RegisterPageController.java} (82%) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 98d893a9fb..12247b2d01 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -1,34 +1,34 @@ package org.apache.coyote.handler; -import org.apache.coyote.handler.mapping.HomePageMapping; -import org.apache.coyote.handler.mapping.StaticFileMapping; -import org.apache.coyote.handler.mapping.login.LoginMapping; -import org.apache.coyote.handler.mapping.login.LoginPageMapping; -import org.apache.coyote.handler.mapping.register.RegisterMapping; -import org.apache.coyote.handler.mapping.register.RegisterPageMapping; +import org.apache.coyote.handler.controller.HomePageController; +import org.apache.coyote.handler.controller.StaticFileController; +import org.apache.coyote.handler.controller.login.LoginController; +import org.apache.coyote.handler.controller.login.LoginPageController; +import org.apache.coyote.handler.controller.register.RegisterController; +import org.apache.coyote.handler.controller.register.RegisterPageController; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import java.util.HashSet; import java.util.Set; -import static org.apache.coyote.handler.mapping.Path.NOT_FOUND; +import static org.apache.coyote.handler.controller.Path.NOT_FOUND; public class FrontHandler { - private static final Set requestControllers = new HashSet<>(); + private static final Set requestControllers = new HashSet<>(); static { - requestControllers.add(new HomePageMapping()); - requestControllers.add(new StaticFileMapping()); - requestControllers.add(new LoginMapping()); - requestControllers.add(new LoginPageMapping()); - requestControllers.add(new RegisterMapping()); - requestControllers.add(new RegisterPageMapping()); + requestControllers.add(new HomePageController()); + requestControllers.add(new StaticFileController()); + requestControllers.add(new LoginController()); + requestControllers.add(new LoginPageController()); + requestControllers.add(new RegisterController()); + requestControllers.add(new RegisterPageController()); } public void handle(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception { - for (final AbstractController mapping : requestControllers) { + for (final RequestController mapping : requestControllers) { if (mapping.supports(httpRequest)) { mapping.service(httpRequest, httpResponse); return; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/handler/RequestController.java similarity index 93% rename from tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java rename to tomcat/src/main/java/org/apache/coyote/handler/RequestController.java index fe06a89217..2db05dbbc2 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/AbstractController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/RequestController.java @@ -4,7 +4,7 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; -public abstract class AbstractController implements Controller { +public abstract class RequestController implements Controller { @Override public void service(final HttpRequest request, final HttpResponse response) throws Exception { @@ -22,6 +22,7 @@ public void service(final HttpRequest request, final HttpResponse response) thro } protected abstract boolean supports(final HttpRequest httpRequest); + protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java similarity index 87% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java index 00b52c5fee..fa5b4eece5 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/HomePageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java @@ -1,6 +1,6 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.controller; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -10,7 +10,7 @@ import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class HomePageMapping extends AbstractController { +public class HomePageController extends RequestController { private static final String HOME_MESSAGE = "Hello world!"; private static final String TARGET_URI = "/"; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java similarity index 87% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java index 489f6ce33d..85d5af71d8 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/Path.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java @@ -1,4 +1,4 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.controller; public enum Path { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java similarity index 94% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java index debeb005fd..4915904d9e 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/StaticFileMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java @@ -1,6 +1,6 @@ -package org.apache.coyote.handler.mapping; +package org.apache.coyote.handler.controller; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -16,7 +16,7 @@ import static org.apache.coyote.http.common.ContentType.JS; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class StaticFileMapping extends AbstractController { +public class StaticFileController extends RequestController { @Override public boolean supports(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java similarity index 90% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java index 5e6105c9a8..203520a865 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java @@ -1,8 +1,8 @@ -package org.apache.coyote.handler.mapping.login; +package org.apache.coyote.handler.controller.login; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeader; @@ -18,15 +18,15 @@ import java.util.Map; import java.util.UUID; -import static org.apache.coyote.handler.mapping.Path.MAIN; -import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; +import static org.apache.coyote.handler.controller.Path.MAIN; +import static org.apache.coyote.handler.controller.Path.UNAUTHORIZED; -public class LoginMapping extends AbstractController { +public class LoginController extends RequestController { private static final LoginManager loginManager = new SessionManager(); private static final String TARGET_URI = "login"; - private static final Logger log = LoggerFactory.getLogger(LoginMapping.class); + private static final Logger log = LoggerFactory.getLogger(LoginController.class); @Override public boolean supports(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java similarity index 88% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java index f23ffea483..fec19f558b 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/login/LoginPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java @@ -1,8 +1,8 @@ -package org.apache.coyote.handler.mapping.login; +package org.apache.coyote.handler.controller.login; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; @@ -16,19 +16,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.coyote.handler.mapping.Path.LOGIN; -import static org.apache.coyote.handler.mapping.Path.MAIN; -import static org.apache.coyote.handler.mapping.Path.UNAUTHORIZED; +import static org.apache.coyote.handler.controller.Path.LOGIN; +import static org.apache.coyote.handler.controller.Path.MAIN; +import static org.apache.coyote.handler.controller.Path.UNAUTHORIZED; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; import static org.apache.coyote.http.common.HttpHeader.COOKIE; -public class LoginPageMapping extends AbstractController { +public class LoginPageController extends RequestController { private static final LoginManager loginManager = new SessionManager(); private static final String TARGET_URI = "login"; - private static final Logger log = LoggerFactory.getLogger(LoginPageMapping.class); + private static final Logger log = LoggerFactory.getLogger(LoginPageController.class); @Override public boolean supports(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java similarity index 83% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java index 640ec319b4..08f33835ba 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java @@ -1,16 +1,16 @@ -package org.apache.coyote.handler.mapping.register; +package org.apache.coyote.handler.controller.register; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import java.util.Map; -import static org.apache.coyote.handler.mapping.Path.MAIN; +import static org.apache.coyote.handler.controller.Path.MAIN; -public class RegisterMapping extends AbstractController { +public class RegisterController extends RequestController { private static final String TARGET_URI = "register"; @Override diff --git a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java similarity index 82% rename from tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java index 3ce070afc8..0e6a3a61ad 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/mapping/register/RegisterPageMapping.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java @@ -1,6 +1,6 @@ -package org.apache.coyote.handler.mapping.register; +package org.apache.coyote.handler.controller.register; -import org.apache.coyote.handler.AbstractController; +import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -8,10 +8,10 @@ import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; -import static org.apache.coyote.handler.mapping.Path.REGISTER; +import static org.apache.coyote.handler.controller.Path.REGISTER; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -public class RegisterPageMapping extends AbstractController { +public class RegisterPageController extends RequestController { private static final String TARGET_URI = "register"; From 83a2309382021737fae0a2d7bfd9f55ceb07d66a Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 08:40:06 +0900 Subject: [PATCH 21/43] =?UTF-8?q?refactor:=20Login=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EB=A5=BC=20=ED=95=98?= =?UTF-8?q?=EB=82=98=EB=A1=9C=20=ED=95=A9=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/handler/FrontHandler.java | 2 - .../controller/login/LoginController.java | 58 +++++++++++-- .../controller/login/LoginPageController.java | 85 ------------------- 3 files changed, 51 insertions(+), 94 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 12247b2d01..86777c1231 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -3,7 +3,6 @@ import org.apache.coyote.handler.controller.HomePageController; import org.apache.coyote.handler.controller.StaticFileController; import org.apache.coyote.handler.controller.login.LoginController; -import org.apache.coyote.handler.controller.login.LoginPageController; import org.apache.coyote.handler.controller.register.RegisterController; import org.apache.coyote.handler.controller.register.RegisterPageController; import org.apache.coyote.http.request.HttpRequest; @@ -22,7 +21,6 @@ public class FrontHandler { requestControllers.add(new HomePageController()); requestControllers.add(new StaticFileController()); requestControllers.add(new LoginController()); - requestControllers.add(new LoginPageController()); requestControllers.add(new RegisterController()); requestControllers.add(new RegisterPageController()); } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java index 203520a865..bc9063594c 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java @@ -4,9 +4,12 @@ import nextstep.jwp.model.User; import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.LoginManager; +import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.common.HttpHeader; +import org.apache.coyote.http.request.HttpCookie; import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.QueryString; import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; @@ -18,8 +21,11 @@ import java.util.Map; import java.util.UUID; +import static org.apache.coyote.handler.controller.Path.LOGIN; import static org.apache.coyote.handler.controller.Path.MAIN; import static org.apache.coyote.handler.controller.Path.UNAUTHORIZED; +import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; +import static org.apache.coyote.http.common.HttpHeader.COOKIE; public class LoginController extends RequestController { @@ -30,7 +36,7 @@ public class LoginController extends RequestController { @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isPostRequest() && httpRequest.containsRequestUri(TARGET_URI); + return httpRequest.containsRequestUri(TARGET_URI); } @Override @@ -63,16 +69,54 @@ protected void doPost(final HttpRequest request, final HttpResponse response) th response.changeBody(HttpBody.empty()); } - @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { - throw new UnsupportedOperationException(); - } - - protected void setSession(final String jSessionId, final Map sessionData) { + private void setSession(final String jSessionId, final Map sessionData) { final Session session = new Session(jSessionId); for (final Map.Entry entry : sessionData.entrySet()) { session.add(entry.getKey(), entry.getValue()); } loginManager.add(session); } + + @Override + protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + if (request.containsHeader(COOKIE)) { + final HttpCookie cookies = HttpCookie.from(request.getHeader(COOKIE)); + if (isAlreadyLogined(cookies.get("JSESSIONID"))) { + response.mapToRedirect(MAIN.getPath()); + return; + } + } + + if (request.hasQueryString()) { + final QueryString queryString = request.getQueryString(); + + final String account = queryString.get("account"); + final String password = queryString.get("password"); + + try { + final User user = InMemoryUserRepository.findByAccount(account) + .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); + + if (!user.checkPassword(password)) { + throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); + } + log.info("로그인 성공! user = {}", user); + } catch (final IllegalArgumentException e) { + log.warn("login error = {}", e); + response.mapToRedirect(UNAUTHORIZED.getPath()); + return; + } + + response.mapToRedirect(MAIN.getPath()); + return; + } + + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(HttpBody.file(LOGIN.getPath())); + } + + private boolean isAlreadyLogined(final String jSessionId) { + return loginManager.isAlreadyLogined(jSessionId); + } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java deleted file mode 100644 index fec19f558b..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginPageController.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.apache.coyote.handler.controller.login; - -import nextstep.jwp.db.InMemoryUserRepository; -import nextstep.jwp.model.User; -import org.apache.coyote.handler.RequestController; -import org.apache.coyote.http.LoginManager; -import org.apache.coyote.http.common.ContentType; -import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.request.HttpCookie; -import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.request.QueryString; -import org.apache.coyote.http.response.HttpResponse; -import org.apache.coyote.http.response.StatusCode; -import org.apache.coyote.http.response.StatusLine; -import org.apache.coyote.http.session.SessionManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static org.apache.coyote.handler.controller.Path.LOGIN; -import static org.apache.coyote.handler.controller.Path.MAIN; -import static org.apache.coyote.handler.controller.Path.UNAUTHORIZED; -import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; -import static org.apache.coyote.http.common.HttpHeader.COOKIE; - -public class LoginPageController extends RequestController { - - private static final LoginManager loginManager = new SessionManager(); - - private static final String TARGET_URI = "login"; - - private static final Logger log = LoggerFactory.getLogger(LoginPageController.class); - - @Override - public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && httpRequest.containsRequestUri(TARGET_URI); - } - - @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { - if (request.containsHeader(COOKIE)) { - final HttpCookie cookies = HttpCookie.from(request.getHeader(COOKIE)); - if (isAlreadyLogined(cookies.get("JSESSIONID"))) { - response.mapToRedirect(MAIN.getPath()); - return; - } - } - - if (request.hasQueryString()) { - final QueryString queryString = request.getQueryString(); - - final String account = queryString.get("account"); - final String password = queryString.get("password"); - - try { - final User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); - - if (!user.checkPassword(password)) { - throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); - } - log.info("로그인 성공! user = {}", user); - } catch (final IllegalArgumentException e) { - log.warn("login error = {}", e); - response.mapToRedirect(UNAUTHORIZED.getPath()); - return; - } - - response.mapToRedirect(MAIN.getPath()); - return; - } - - response.changeStatusLine(StatusLine.from(StatusCode.OK)); - response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); - response.changeBody(HttpBody.file(LOGIN.getPath())); - } - - protected boolean isAlreadyLogined(final String jSessionId) { - return loginManager.isAlreadyLogined(jSessionId); - } -} From 3beba19a19c475186e4d3531085d75fa4fbeecf2 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 08:42:04 +0900 Subject: [PATCH 22/43] =?UTF-8?q?refactor:=20Register=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=EC=9D=84=20=ED=95=98=EB=82=98=EB=A1=9C=20?= =?UTF-8?q?=ED=95=A9=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/coyote/handler/FrontHandler.java | 2 -- .../register/RegisterController.java | 12 +++++-- .../register/RegisterPageController.java | 34 ------------------- 3 files changed, 10 insertions(+), 38 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 86777c1231..29516de8d8 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -4,7 +4,6 @@ import org.apache.coyote.handler.controller.StaticFileController; import org.apache.coyote.handler.controller.login.LoginController; import org.apache.coyote.handler.controller.register.RegisterController; -import org.apache.coyote.handler.controller.register.RegisterPageController; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; @@ -22,7 +21,6 @@ public class FrontHandler { requestControllers.add(new StaticFileController()); requestControllers.add(new LoginController()); requestControllers.add(new RegisterController()); - requestControllers.add(new RegisterPageController()); } public void handle(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java index 08f33835ba..ab0decb36a 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java @@ -3,19 +3,25 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; import org.apache.coyote.handler.RequestController; +import org.apache.coyote.http.common.ContentType; +import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; +import org.apache.coyote.http.response.StatusCode; +import org.apache.coyote.http.response.StatusLine; import java.util.Map; import static org.apache.coyote.handler.controller.Path.MAIN; +import static org.apache.coyote.handler.controller.Path.REGISTER; +import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; public class RegisterController extends RequestController { private static final String TARGET_URI = "register"; @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isPostRequest() && httpRequest.containsRequestUri(TARGET_URI); + return httpRequest.containsRequestUri(TARGET_URI); } @Override @@ -34,6 +40,8 @@ protected void doPost(final HttpRequest request, final HttpResponse response) th @Override protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { - throw new UnsupportedOperationException(); + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(HttpBody.file(REGISTER.getPath())); } } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java deleted file mode 100644 index 0e6a3a61ad..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterPageController.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.apache.coyote.handler.controller.register; - -import org.apache.coyote.handler.RequestController; -import org.apache.coyote.http.common.ContentType; -import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.HttpResponse; -import org.apache.coyote.http.response.StatusCode; -import org.apache.coyote.http.response.StatusLine; - -import static org.apache.coyote.handler.controller.Path.REGISTER; -import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; - -public class RegisterPageController extends RequestController { - - private static final String TARGET_URI = "register"; - - @Override - public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && httpRequest.containsRequestUri(TARGET_URI); - } - - @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { - response.changeStatusLine(StatusLine.from(StatusCode.OK)); - response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); - response.changeBody(HttpBody.file(REGISTER.getPath())); - } -} From 708cad56ac725168ee171309b8a31d2eb46406b6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 08:42:51 +0900 Subject: [PATCH 23/43] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/apache/coyote/handler/FrontHandler.java | 4 ++-- .../handler/controller/{login => }/LoginController.java | 2 +- .../handler/controller/{register => }/RegisterController.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename tomcat/src/main/java/org/apache/coyote/handler/controller/{login => }/LoginController.java (98%) rename tomcat/src/main/java/org/apache/coyote/handler/controller/{register => }/RegisterController.java (96%) diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java index 29516de8d8..1241cf8e32 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java @@ -1,9 +1,9 @@ package org.apache.coyote.handler; import org.apache.coyote.handler.controller.HomePageController; +import org.apache.coyote.handler.controller.LoginController; +import org.apache.coyote.handler.controller.RegisterController; import org.apache.coyote.handler.controller.StaticFileController; -import org.apache.coyote.handler.controller.login.LoginController; -import org.apache.coyote.handler.controller.register.RegisterController; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java similarity index 98% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java index bc9063594c..82043b9506 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/login/LoginController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java @@ -1,4 +1,4 @@ -package org.apache.coyote.handler.controller.login; +package org.apache.coyote.handler.controller; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java similarity index 96% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java rename to tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java index ab0decb36a..800edf76c5 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/register/RegisterController.java +++ b/tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java @@ -1,4 +1,4 @@ -package org.apache.coyote.handler.controller.register; +package org.apache.coyote.handler.controller; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; From 6d188b40523da0fbc69741554b640c7d0a4339e6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 08:47:22 +0900 Subject: [PATCH 24/43] =?UTF-8?q?refactor:=20example=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20CacheBustingWebConfig=EC=9D=98=20=EC=83=81=EC=88=98?= =?UTF-8?q?=EC=9D=98=20=EC=A0=91=EA=B7=BC=EC=A0=9C=ED=95=9C=EC=9E=90=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cache/com/example/version/CacheBustingWebConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java index 2571acd023..b8f07e263a 100644 --- a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java +++ b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java @@ -11,13 +11,13 @@ @Configuration public class CacheBustingWebConfig implements WebMvcConfigurer { - private static final String PREFIX_STATIC_RESOURCES = "/resources"; + public static final String PREFIX_STATIC_RESOURCES = "/resources"; private static final Long MAX_AGE = 365L; private final ResourceVersion version; @Autowired - public CacheBustingWebConfig(ResourceVersion version) { + public CacheBustingWebConfig(final ResourceVersion version) { this.version = version; } From 937e0f707f17b51828008895e89f3f8d6c1f9d40 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 09:21:59 +0900 Subject: [PATCH 25/43] =?UTF-8?q?refactor:=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=20=EB=81=8A=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=9D=B8=EC=8A=A4?= =?UTF-8?q?=ED=84=B4=EC=8A=A4=20=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/nextstep/Application.java | 5 ++- .../jwp/controller/FrontController.java | 39 +++++++++++++++++++ .../jwp}/controller/HomePageController.java | 3 +- .../jwp}/controller/LoginController.java | 9 ++--- .../jwp}/controller/Path.java | 2 +- .../jwp}/controller/RegisterController.java | 7 ++-- .../jwp/controller}/RequestController.java | 5 +-- .../jwp}/controller/StaticFileController.java | 3 +- .../apache/catalina/connector/Connector.java | 23 ++++++----- .../org/apache/catalina/startup/Tomcat.java | 11 +++++- .../{handler => controller}/Controller.java | 4 +- .../apache/coyote/handler/FrontHandler.java | 36 ----------------- .../apache/coyote/http11/Http11Processor.java | 10 ++--- .../coyote/http11/Http11ProcessorTest.java | 15 +++---- 14 files changed, 92 insertions(+), 80 deletions(-) create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/FrontController.java rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp}/controller/HomePageController.java (92%) rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp}/controller/LoginController.java (94%) rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp}/controller/Path.java (87%) rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp}/controller/RegisterController.java (87%) rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp/controller}/RequestController.java (89%) rename tomcat/src/main/java/{org/apache/coyote/handler => nextstep/jwp}/controller/StaticFileController.java (96%) rename tomcat/src/main/java/org/apache/coyote/{handler => controller}/Controller.java (71%) delete mode 100644 tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java diff --git a/tomcat/src/main/java/nextstep/Application.java b/tomcat/src/main/java/nextstep/Application.java index 3dd7593507..0c0761f1f5 100644 --- a/tomcat/src/main/java/nextstep/Application.java +++ b/tomcat/src/main/java/nextstep/Application.java @@ -1,11 +1,12 @@ package nextstep; +import nextstep.jwp.controller.FrontController; import org.apache.catalina.startup.Tomcat; public class Application { - public static void main(String[] args) { - final var tomcat = new Tomcat(); + public static void main(final String[] args) { + final var tomcat = new Tomcat(new FrontController()); tomcat.start(); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/FrontController.java b/tomcat/src/main/java/nextstep/jwp/controller/FrontController.java new file mode 100644 index 0000000000..415126bba3 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/FrontController.java @@ -0,0 +1,39 @@ +package nextstep.jwp.controller; + +import org.apache.coyote.controller.Controller; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.response.HttpResponse; + +import java.util.HashSet; +import java.util.Set; + +import static nextstep.jwp.controller.Path.NOT_FOUND; + +public class FrontController implements Controller { + + private static final Set requestControllers = new HashSet<>(); + + static { + requestControllers.add(new HomePageController()); + requestControllers.add(new StaticFileController()); + requestControllers.add(new LoginController()); + requestControllers.add(new RegisterController()); + } + + @Override + public boolean supports(final HttpRequest httpRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public void service(final HttpRequest request, final HttpResponse response) throws Exception { + for (final Controller controller : requestControllers) { + if (controller.supports(request)) { + controller.service(request, response); + return; + } + } + + response.mapToRedirect(NOT_FOUND.getPath()); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java b/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java similarity index 92% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java rename to tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java index fa5b4eece5..70ce0ea20d 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/HomePageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java @@ -1,6 +1,5 @@ -package org.apache.coyote.handler.controller; +package nextstep.jwp.controller; -import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java similarity index 94% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java rename to tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 82043b9506..d502c4b409 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -1,8 +1,7 @@ -package org.apache.coyote.handler.controller; +package nextstep.jwp.controller; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; @@ -21,9 +20,9 @@ import java.util.Map; import java.util.UUID; -import static org.apache.coyote.handler.controller.Path.LOGIN; -import static org.apache.coyote.handler.controller.Path.MAIN; -import static org.apache.coyote.handler.controller.Path.UNAUTHORIZED; +import static nextstep.jwp.controller.Path.LOGIN; +import static nextstep.jwp.controller.Path.MAIN; +import static nextstep.jwp.controller.Path.UNAUTHORIZED; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; import static org.apache.coyote.http.common.HttpHeader.COOKIE; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java b/tomcat/src/main/java/nextstep/jwp/controller/Path.java similarity index 87% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java rename to tomcat/src/main/java/nextstep/jwp/controller/Path.java index 85d5af71d8..29fc253737 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/Path.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/Path.java @@ -1,4 +1,4 @@ -package org.apache.coyote.handler.controller; +package nextstep.jwp.controller; public enum Path { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java similarity index 87% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java rename to tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index 800edf76c5..2adc74a068 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -1,8 +1,7 @@ -package org.apache.coyote.handler.controller; +package nextstep.jwp.controller; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; @@ -12,8 +11,8 @@ import java.util.Map; -import static org.apache.coyote.handler.controller.Path.MAIN; -import static org.apache.coyote.handler.controller.Path.REGISTER; +import static nextstep.jwp.controller.Path.MAIN; +import static nextstep.jwp.controller.Path.REGISTER; import static org.apache.coyote.http.common.HttpHeader.CONTENT_TYPE; public class RegisterController extends RequestController { diff --git a/tomcat/src/main/java/org/apache/coyote/handler/RequestController.java b/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java similarity index 89% rename from tomcat/src/main/java/org/apache/coyote/handler/RequestController.java rename to tomcat/src/main/java/nextstep/jwp/controller/RequestController.java index 2db05dbbc2..7213b3e715 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/RequestController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java @@ -1,5 +1,6 @@ -package org.apache.coyote.handler; +package nextstep.jwp.controller; +import org.apache.coyote.controller.Controller; import org.apache.coyote.http.request.HttpMethod; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; @@ -21,8 +22,6 @@ public void service(final HttpRequest request, final HttpResponse response) thro throw new UnsupportedOperationException("지원하지 않는 HTTP Method 입니다."); } - protected abstract boolean supports(final HttpRequest httpRequest); - protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; diff --git a/tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java similarity index 96% rename from tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java rename to tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java index 4915904d9e..697c33a5b6 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/controller/StaticFileController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java @@ -1,6 +1,5 @@ -package org.apache.coyote.handler.controller; +package nextstep.jwp.controller; -import org.apache.coyote.handler.RequestController; import org.apache.coyote.http.common.ContentType; import org.apache.coyote.http.common.HttpBody; import org.apache.coyote.http.request.HttpRequest; 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..b32199a7e7 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,6 @@ package org.apache.catalina.connector; +import org.apache.coyote.controller.Controller; import org.apache.coyote.http11.Http11Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,13 +18,15 @@ public class Connector implements Runnable { private static final int DEFAULT_ACCEPT_COUNT = 100; private final ServerSocket serverSocket; + private final Controller controller; private boolean stopped; - public Connector() { - this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + public Connector(final Controller controller) { + this(controller, DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); } - public Connector(final int port, final int acceptCount) { + public Connector(final Controller controller, final int port, final int acceptCount) { + this.controller = controller; this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; } @@ -33,13 +36,13 @@ private ServerSocket createServerSocket(final int port, final int acceptCount) { final int checkedPort = checkPort(port); final int checkedAcceptCount = checkAcceptCount(acceptCount); return new ServerSocket(checkedPort, checkedAcceptCount); - } catch (IOException e) { + } catch (final IOException e) { throw new UncheckedIOException(e); } } public void start() { - var thread = new Thread(this); + final var thread = new Thread(this); thread.setDaemon(true); thread.start(); stopped = false; @@ -56,17 +59,17 @@ public void run() { private void connect() { try { - process(serverSocket.accept()); - } catch (IOException e) { + process(serverSocket.accept(), controller); + } catch (final IOException e) { log.error(e.getMessage(), e); } } - private void process(final Socket connection) { + private void process(final Socket connection, final Controller controller) { if (connection == null) { return; } - var processor = new Http11Processor(connection); + final var processor = new Http11Processor(connection, controller); new Thread(processor).start(); } @@ -74,7 +77,7 @@ public void stop() { stopped = true; try { serverSocket.close(); - } catch (IOException e) { + } catch (final IOException e) { log.error(e.getMessage(), e); } } diff --git a/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java b/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java index 205159e95b..f2edb99857 100644 --- a/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java +++ b/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java @@ -1,6 +1,7 @@ package org.apache.catalina.startup; import org.apache.catalina.connector.Connector; +import org.apache.coyote.controller.Controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,14 +11,20 @@ public class Tomcat { private static final Logger log = LoggerFactory.getLogger(Tomcat.class); + private final Controller controller; + + public Tomcat(final Controller controller) { + this.controller = controller; + } + public void start() { - var connector = new Connector(); + final var connector = new Connector(controller); connector.start(); try { // make the application wait until we press any key. System.in.read(); - } catch (IOException e) { + } catch (final IOException e) { log.error(e.getMessage(), e); } finally { log.info("web server stop."); diff --git a/tomcat/src/main/java/org/apache/coyote/handler/Controller.java b/tomcat/src/main/java/org/apache/coyote/controller/Controller.java similarity index 71% rename from tomcat/src/main/java/org/apache/coyote/handler/Controller.java rename to tomcat/src/main/java/org/apache/coyote/controller/Controller.java index 9e590eb157..d20592063e 100644 --- a/tomcat/src/main/java/org/apache/coyote/handler/Controller.java +++ b/tomcat/src/main/java/org/apache/coyote/controller/Controller.java @@ -1,9 +1,11 @@ -package org.apache.coyote.handler; +package org.apache.coyote.controller; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; public interface Controller { + boolean supports(final HttpRequest httpRequest); + void service(final HttpRequest request, final HttpResponse response) throws Exception; } diff --git a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java b/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java deleted file mode 100644 index 1241cf8e32..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/handler/FrontHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.apache.coyote.handler; - -import org.apache.coyote.handler.controller.HomePageController; -import org.apache.coyote.handler.controller.LoginController; -import org.apache.coyote.handler.controller.RegisterController; -import org.apache.coyote.handler.controller.StaticFileController; -import org.apache.coyote.http.request.HttpRequest; -import org.apache.coyote.http.response.HttpResponse; - -import java.util.HashSet; -import java.util.Set; - -import static org.apache.coyote.handler.controller.Path.NOT_FOUND; - -public class FrontHandler { - - private static final Set requestControllers = new HashSet<>(); - - static { - requestControllers.add(new HomePageController()); - requestControllers.add(new StaticFileController()); - requestControllers.add(new LoginController()); - requestControllers.add(new RegisterController()); - } - - public void handle(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception { - for (final RequestController mapping : requestControllers) { - if (mapping.supports(httpRequest)) { - mapping.service(httpRequest, httpResponse); - return; - } - } - - httpResponse.mapToRedirect(NOT_FOUND.getPath()); - } -} 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 96fa1a0043..477a9c47c4 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,7 +1,7 @@ package org.apache.coyote.http11; import org.apache.coyote.Processor; -import org.apache.coyote.handler.FrontHandler; +import org.apache.coyote.controller.Controller; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import org.slf4j.Logger; @@ -16,12 +16,12 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private final Socket connection; - private final FrontHandler frontHandler; + private final Controller controller; private final HttpRequestParser httpRequestParser; - public Http11Processor(final Socket connection) { + public Http11Processor(final Socket connection, final Controller controller) { this.connection = connection; - this.frontHandler = new FrontHandler(); + this.controller = controller; this.httpRequestParser = new HttpRequestParser(); } @@ -43,7 +43,7 @@ public void process(final Socket connection) { } final HttpResponse httpResponse = new HttpResponse(); - frontHandler.handle(httpRequest, httpResponse); + controller.service(httpRequest, httpResponse); outputStream.write(httpResponse.serialize().getBytes()); outputStream.flush(); 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 512b919f09..a98f6260de 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 @@ -1,8 +1,9 @@ package nextstep.org.apache.coyote.http11; -import support.StubSocket; +import nextstep.jwp.controller.FrontController; import org.apache.coyote.http11.Http11Processor; import org.junit.jupiter.api.Test; +import support.StubSocket; import java.io.File; import java.io.IOException; @@ -17,13 +18,13 @@ class Http11ProcessorTest { void process() { // given final var socket = new StubSocket(); - final var processor = new Http11Processor(socket); + final var processor = new Http11Processor(socket, new FrontController()); // when processor.process(socket); // then - var expected = String.join("\r\n", + final var expected = String.join("\r\n", "HTTP/1.1 200 OK ", "Content-Type: text/html;charset=utf-8 ", "Content-Length: 12 ", @@ -36,7 +37,7 @@ void process() { @Test void index() throws IOException { // given - final String httpRequest= String.join("\r\n", + final String httpRequest = String.join("\r\n", "GET /index.html HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", @@ -44,17 +45,17 @@ void index() throws IOException { ""); final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket); + final Http11Processor processor = new Http11Processor(socket, new FrontController()); // when processor.process(socket); // then final URL resource = getClass().getClassLoader().getResource("static/index.html"); - var expected = "HTTP/1.1 200 OK \r\n" + + final 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"+ + "\r\n" + new String(Files.readAllBytes(new File(resource.getFile()).toPath())); assertThat(socket.output()).isEqualTo(expected); From 4a2e9855c77221bdfc36448ae69ed8a6163a553c Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 09:29:17 +0900 Subject: [PATCH 26/43] =?UTF-8?q?refactor:=20FrontController=20=EB=A5=BC?= =?UTF-8?q?=20FrontHandler=20=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/java/nextstep/Application.java | 4 ++-- ...{FrontController.java => FrontHandler.java} | 10 +++------- .../apache/catalina/connector/Connector.java | 18 +++++++++--------- .../org/apache/catalina/startup/Tomcat.java | 10 +++++----- .../coyote/controller/RequestHandler.java | 9 +++++++++ .../apache/coyote/http11/Http11Processor.java | 10 +++++----- .../coyote/http11/Http11ProcessorTest.java | 6 +++--- 7 files changed, 36 insertions(+), 31 deletions(-) rename tomcat/src/main/java/nextstep/jwp/controller/{FrontController.java => FrontHandler.java} (76%) create mode 100644 tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java diff --git a/tomcat/src/main/java/nextstep/Application.java b/tomcat/src/main/java/nextstep/Application.java index 0c0761f1f5..393b2027d3 100644 --- a/tomcat/src/main/java/nextstep/Application.java +++ b/tomcat/src/main/java/nextstep/Application.java @@ -1,12 +1,12 @@ package nextstep; -import nextstep.jwp.controller.FrontController; +import nextstep.jwp.controller.FrontHandler; import org.apache.catalina.startup.Tomcat; public class Application { public static void main(final String[] args) { - final var tomcat = new Tomcat(new FrontController()); + final var tomcat = new Tomcat(new FrontHandler()); tomcat.start(); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/FrontController.java b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java similarity index 76% rename from tomcat/src/main/java/nextstep/jwp/controller/FrontController.java rename to tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java index 415126bba3..bd3841ccbc 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/FrontController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java @@ -1,6 +1,7 @@ package nextstep.jwp.controller; import org.apache.coyote.controller.Controller; +import org.apache.coyote.controller.RequestHandler; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; @@ -9,7 +10,7 @@ import static nextstep.jwp.controller.Path.NOT_FOUND; -public class FrontController implements Controller { +public class FrontHandler implements RequestHandler { private static final Set requestControllers = new HashSet<>(); @@ -21,12 +22,7 @@ public class FrontController implements Controller { } @Override - public boolean supports(final HttpRequest httpRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public void service(final HttpRequest request, final HttpResponse response) throws Exception { + public void handle(final HttpRequest request, final HttpResponse response) throws Exception { for (final Controller controller : requestControllers) { if (controller.supports(request)) { controller.service(request, response); 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 b32199a7e7..e4697f7635 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -1,6 +1,6 @@ package org.apache.catalina.connector; -import org.apache.coyote.controller.Controller; +import org.apache.coyote.controller.RequestHandler; import org.apache.coyote.http11.Http11Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,15 +18,15 @@ public class Connector implements Runnable { private static final int DEFAULT_ACCEPT_COUNT = 100; private final ServerSocket serverSocket; - private final Controller controller; + private final RequestHandler requestHandler; private boolean stopped; - public Connector(final Controller controller) { - this(controller, DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + public Connector(final RequestHandler requestHandler) { + this(requestHandler, DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); } - public Connector(final Controller controller, final int port, final int acceptCount) { - this.controller = controller; + public Connector(final RequestHandler requestHandler, final int port, final int acceptCount) { + this.requestHandler = requestHandler; this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; } @@ -59,17 +59,17 @@ public void run() { private void connect() { try { - process(serverSocket.accept(), controller); + process(serverSocket.accept(), requestHandler); } catch (final IOException e) { log.error(e.getMessage(), e); } } - private void process(final Socket connection, final Controller controller) { + private void process(final Socket connection, final RequestHandler requestHandler) { if (connection == null) { return; } - final var processor = new Http11Processor(connection, controller); + final var processor = new Http11Processor(connection, requestHandler); new Thread(processor).start(); } diff --git a/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java b/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java index f2edb99857..3c4d20e1b5 100644 --- a/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java +++ b/tomcat/src/main/java/org/apache/catalina/startup/Tomcat.java @@ -1,7 +1,7 @@ package org.apache.catalina.startup; import org.apache.catalina.connector.Connector; -import org.apache.coyote.controller.Controller; +import org.apache.coyote.controller.RequestHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,14 +11,14 @@ public class Tomcat { private static final Logger log = LoggerFactory.getLogger(Tomcat.class); - private final Controller controller; + private final RequestHandler requestHandler; - public Tomcat(final Controller controller) { - this.controller = controller; + public Tomcat(final RequestHandler requestHandler) { + this.requestHandler = requestHandler; } public void start() { - final var connector = new Connector(controller); + final var connector = new Connector(requestHandler); connector.start(); try { diff --git a/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java b/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java new file mode 100644 index 0000000000..1551797b18 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java @@ -0,0 +1,9 @@ +package org.apache.coyote.controller; + +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.response.HttpResponse; + +public interface RequestHandler { + + void handle(final HttpRequest request, final HttpResponse response) throws Exception; +} 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 477a9c47c4..440dd4a6fa 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,7 +1,7 @@ package org.apache.coyote.http11; import org.apache.coyote.Processor; -import org.apache.coyote.controller.Controller; +import org.apache.coyote.controller.RequestHandler; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; import org.slf4j.Logger; @@ -16,12 +16,12 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private final Socket connection; - private final Controller controller; + private final RequestHandler requestHandler; private final HttpRequestParser httpRequestParser; - public Http11Processor(final Socket connection, final Controller controller) { + public Http11Processor(final Socket connection, final RequestHandler requestHandler) { this.connection = connection; - this.controller = controller; + this.requestHandler = requestHandler; this.httpRequestParser = new HttpRequestParser(); } @@ -43,7 +43,7 @@ public void process(final Socket connection) { } final HttpResponse httpResponse = new HttpResponse(); - controller.service(httpRequest, httpResponse); + requestHandler.handle(httpRequest, httpResponse); outputStream.write(httpResponse.serialize().getBytes()); outputStream.flush(); 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 a98f6260de..6bb8ff0735 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 @@ -1,6 +1,6 @@ package nextstep.org.apache.coyote.http11; -import nextstep.jwp.controller.FrontController; +import nextstep.jwp.controller.FrontHandler; import org.apache.coyote.http11.Http11Processor; import org.junit.jupiter.api.Test; import support.StubSocket; @@ -18,7 +18,7 @@ class Http11ProcessorTest { void process() { // given final var socket = new StubSocket(); - final var processor = new Http11Processor(socket, new FrontController()); + final var processor = new Http11Processor(socket, new FrontHandler()); // when processor.process(socket); @@ -45,7 +45,7 @@ void index() throws IOException { ""); final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontController()); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler()); // when processor.process(socket); From cabedbae9397621d1a8cb2e1add1fcd9a06b13b1 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 09:35:09 +0900 Subject: [PATCH 27/43] =?UTF-8?q?refactor:=20HttpResponseBuilder=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 --- .../coyote/http/response/HttpResponse.java | 13 ------ .../http/response/HttpResponseBuilder.java | 40 ------------------- .../coyote/http11/Http11ProcessorTest.java | 2 + 3 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java index e42ac9dc10..087d452d0d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java @@ -17,15 +17,6 @@ public class HttpResponse { private HttpHeaders httpHeaders; private HttpBody body; - public HttpResponse() { - } - - HttpResponse(final StatusLine statusLine, final HttpHeaders httpHeaders, final HttpBody body) { - this.statusLine = statusLine; - this.httpHeaders = httpHeaders; - this.body = body; - } - public void mapToRedirect(final String redirectUri) { changeStatusLine(StatusLine.from(StatusCode.FOUND)); addHeader(HttpHeader.LOCATION, redirectUri); @@ -48,10 +39,6 @@ public void changeBody(final HttpBody body) { this.body = body; } - public static HttpResponseBuilder builder() { - return new HttpResponseBuilder(); - } - public String serialize() { final StringBuilder response = new StringBuilder(); diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java deleted file mode 100644 index 82ceae9459..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponseBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.apache.coyote.http.response; - -import org.apache.coyote.http.common.HttpBody; -import org.apache.coyote.http.common.HttpHeader; -import org.apache.coyote.http.common.HttpHeaders; - -import java.util.EnumMap; - -public class HttpResponseBuilder { - - private StatusLine statusLine; - private HttpHeaders httpHeaders; - private HttpBody body; - - HttpResponseBuilder() { - } - - public HttpResponseBuilder statusLine(final StatusLine statusLine) { - this.statusLine = statusLine; - return this; - } - - public HttpResponseBuilder httpHeaders(final HttpHeader key, final String value) { - if (httpHeaders == null) { - this.httpHeaders = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - } - - httpHeaders.add(key, value); - return this; - } - - public HttpResponseBuilder body(final HttpBody body) { - this.body = body; - return this; - } - - public HttpResponse build() { - return new HttpResponse(statusLine, httpHeaders, 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 6bb8ff0735..a247680f1d 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 @@ -1,6 +1,7 @@ package nextstep.org.apache.coyote.http11; import nextstep.jwp.controller.FrontHandler; +import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http11.Http11Processor; import org.junit.jupiter.api.Test; import support.StubSocket; @@ -24,6 +25,7 @@ void process() { processor.process(socket); // then + new HttpResponse() final var expected = String.join("\r\n", "HTTP/1.1 200 OK ", "Content-Type: text/html;charset=utf-8 ", From cbc9455537646e03565c7422eed7a4ccd06f5418 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 09:53:18 +0900 Subject: [PATCH 28/43] =?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=84=9C=EB=93=9C=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 --- .../nextstep/jwp/controller/StaticFileController.java | 2 +- .../java/org/apache/coyote/http/request/HttpRequest.java | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java index 697c33a5b6..c8040cf1ca 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java @@ -19,7 +19,7 @@ public class StaticFileController extends RequestController { @Override public boolean supports(final HttpRequest httpRequest) { - return httpRequest.isGetRequest() && isStaticFile(httpRequest); + return isStaticFile(httpRequest); } private static boolean isStaticFile(final HttpRequest httpRequest) { diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index 3e637831da..d8d9257cca 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -22,14 +22,6 @@ public boolean isSameRequestMethod(final HttpMethod httpMethod) { return requestLine.isSameRequestMethod(httpMethod); } - public boolean isPostRequest() { - return requestLine.isPostMethod(); - } - - public boolean isGetRequest() { - return requestLine.isGetMethod(); - } - public boolean containsRequestUri(final String uri) { return requestLine.containsRequestUri(uri); } From 954862aa62dda225abfd09661839ccb8a3afa938 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 12:11:40 +0900 Subject: [PATCH 29/43] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20HttpRequest,=20HttpResponse=20=EB=A1=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http/request/HttpRequest.java | 12 +++ .../coyote/http/request/RequestLine.java | 4 + .../coyote/http11/Http11ProcessorTest.java | 100 +++++++++++++----- tomcat/src/test/java/support/StubSocket.java | 8 +- 4 files changed, 94 insertions(+), 30 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index d8d9257cca..a795a7855c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -53,4 +53,16 @@ public Map getParsedBody() { public RequestUri getRequestUri() { return requestLine.getRequestUri(); } + + public RequestLine getRequestLine() { + return requestLine; + } + + public HttpHeaders getHeaders() { + return headers; + } + + public HttpBody getHttpBody() { + return httpBody; + } } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index 8ff726cc48..6c9950fbe3 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -42,6 +42,10 @@ public QueryString getQueryString() { return requestUri.getQueryString(); } + public Protocol getProtocol() { + return protocol; + } + public RequestUri getRequestUri() { return requestUri; } 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 a247680f1d..33d6103ba6 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 @@ -1,20 +1,34 @@ package nextstep.org.apache.coyote.http11; import nextstep.jwp.controller.FrontHandler; +import org.apache.coyote.http.common.ContentType; +import org.apache.coyote.http.common.HttpBody; +import org.apache.coyote.http.common.HttpHeader; +import org.apache.coyote.http.common.HttpHeaders; +import org.apache.coyote.http.common.Protocol; +import org.apache.coyote.http.request.HttpMethod; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.RequestLine; +import org.apache.coyote.http.request.RequestUri; import org.apache.coyote.http.response.HttpResponse; +import org.apache.coyote.http.response.StatusCode; +import org.apache.coyote.http.response.StatusLine; import org.apache.coyote.http11.Http11Processor; import org.junit.jupiter.api.Test; import support.StubSocket; -import java.io.File; import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; +import java.util.EnumMap; import static org.assertj.core.api.Assertions.assertThat; class Http11ProcessorTest { + private static final String SPACE = " "; + private static final String HEADER_DELIMETER = ": "; + private static final String CRLF = "\r\n"; + private static final String BLANK_LINE = ""; + @Test void process() { // given @@ -25,41 +39,71 @@ void process() { processor.process(socket); // then - new HttpResponse() - final 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); + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(new HttpBody("Hello world!")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); } @Test void index() throws IOException { // given - final String httpRequest = String.join("\r\n", - "GET /index.html HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - "", - ""); - - final var socket = new StubSocket(httpRequest); + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/index.html"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONNECTION, "keep-alive"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final var socket = new StubSocket(serialize(httpRequest)); final Http11Processor processor = new Http11Processor(socket, new FrontHandler()); // when processor.process(socket); // then - final URL resource = getClass().getClassLoader().getResource("static/index.html"); - final 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); + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(HttpBody.file("/index.html")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); + } + + private String serialize(final HttpRequest request) { + final StringBuilder builder = new StringBuilder(); + + serializeRequestLine(request, builder); + serializeHeaders(request, builder); + + if (request.getHttpBody() == null || request.getHttpBody().getValue().isEmpty()) { + builder.append(CRLF); + return builder.toString(); + } + + builder.append(HttpHeader.CONTENT_LENGTH.getValue()) + .append(HEADER_DELIMETER) + .append(request.getHttpBody().getValue().getBytes().length) + .append(SPACE).append(CRLF); + + serializeBody(request, builder); + return builder.toString(); + } + + private void serializeRequestLine(final HttpRequest request, final StringBuilder builder) { + builder.append(request.getRequestLine().getHttpMethod().name()).append(SPACE); + builder.append(request.getRequestLine().getRequestUri().getRequestUri()).append(SPACE); + builder.append(request.getRequestLine().getProtocol().getName()).append(SPACE).append(CRLF); + } + + private void serializeHeaders(final HttpRequest request, final StringBuilder builder) { + request.getHeaders().getHeaders() + .forEach((key, value) -> builder.append(key.getValue()).append(HEADER_DELIMETER).append(value).append(SPACE).append(CRLF)); + } + + private void serializeBody(final HttpRequest request, final StringBuilder builder) { + builder.append(BLANK_LINE).append(CRLF); + builder.append(request.getHttpBody().getValue()); } } diff --git a/tomcat/src/test/java/support/StubSocket.java b/tomcat/src/test/java/support/StubSocket.java index 6ba8ba5ef9..eb7dbe2b01 100644 --- a/tomcat/src/test/java/support/StubSocket.java +++ b/tomcat/src/test/java/support/StubSocket.java @@ -23,26 +23,30 @@ public StubSocket() { this("GET / HTTP/1.1\r\nHost: localhost:8080\r\n\r\n"); } + @Override public InetAddress getInetAddress() { try { return InetAddress.getLocalHost(); - } catch (UnknownHostException ignored) { + } catch (final UnknownHostException ignored) { return null; } } + @Override public int getPort() { return 8080; } + @Override public InputStream getInputStream() { return new ByteArrayInputStream(request.getBytes()); } + @Override public OutputStream getOutputStream() { return new OutputStream() { @Override - public void write(int b) { + public void write(final int b) { outputStream.write(b); } }; From 694cca83a37df8e22309d0f670c9cec96d058604 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 12:19:01 +0900 Subject: [PATCH 30/43] =?UTF-8?q?test:=20StubSockect=20=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20serialize=20=EC=BD=94=EB=93=9C=20=EC=98=AE=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/Http11ProcessorTest.java | 43 +----------- tomcat/src/test/java/support/StubSocket.java | 66 +++++++++++++++++-- 2 files changed, 63 insertions(+), 46 deletions(-) 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 33d6103ba6..d093486f68 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 @@ -24,11 +24,6 @@ class Http11ProcessorTest { - private static final String SPACE = " "; - private static final String HEADER_DELIMETER = ": "; - private static final String CRLF = "\r\n"; - private static final String BLANK_LINE = ""; - @Test void process() { // given @@ -56,7 +51,7 @@ void index() throws IOException { headers.add(HttpHeader.CONNECTION, "keep-alive"); final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); - final var socket = new StubSocket(serialize(httpRequest)); + final var socket = new StubSocket(httpRequest); final Http11Processor processor = new Http11Processor(socket, new FrontHandler()); // when @@ -70,40 +65,4 @@ void index() throws IOException { assertThat(socket.output()).isEqualTo(expected.serialize()); } - - private String serialize(final HttpRequest request) { - final StringBuilder builder = new StringBuilder(); - - serializeRequestLine(request, builder); - serializeHeaders(request, builder); - - if (request.getHttpBody() == null || request.getHttpBody().getValue().isEmpty()) { - builder.append(CRLF); - return builder.toString(); - } - - builder.append(HttpHeader.CONTENT_LENGTH.getValue()) - .append(HEADER_DELIMETER) - .append(request.getHttpBody().getValue().getBytes().length) - .append(SPACE).append(CRLF); - - serializeBody(request, builder); - return builder.toString(); - } - - private void serializeRequestLine(final HttpRequest request, final StringBuilder builder) { - builder.append(request.getRequestLine().getHttpMethod().name()).append(SPACE); - builder.append(request.getRequestLine().getRequestUri().getRequestUri()).append(SPACE); - builder.append(request.getRequestLine().getProtocol().getName()).append(SPACE).append(CRLF); - } - - private void serializeHeaders(final HttpRequest request, final StringBuilder builder) { - request.getHeaders().getHeaders() - .forEach((key, value) -> builder.append(key.getValue()).append(HEADER_DELIMETER).append(value).append(SPACE).append(CRLF)); - } - - private void serializeBody(final HttpRequest request, final StringBuilder builder) { - builder.append(BLANK_LINE).append(CRLF); - builder.append(request.getHttpBody().getValue()); - } } diff --git a/tomcat/src/test/java/support/StubSocket.java b/tomcat/src/test/java/support/StubSocket.java index eb7dbe2b01..8702c44a71 100644 --- a/tomcat/src/test/java/support/StubSocket.java +++ b/tomcat/src/test/java/support/StubSocket.java @@ -1,5 +1,14 @@ package support; +import org.apache.coyote.http.common.HttpBody; +import org.apache.coyote.http.common.HttpHeader; +import org.apache.coyote.http.common.HttpHeaders; +import org.apache.coyote.http.common.Protocol; +import org.apache.coyote.http.request.HttpMethod; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.RequestLine; +import org.apache.coyote.http.request.RequestUri; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -8,19 +17,32 @@ import java.net.Socket; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; +import java.util.EnumMap; public class StubSocket extends Socket { + + private static final String SPACE = " "; + private static final String HEADER_DELIMETER = ": "; + private static final String CRLF = "\r\n"; + private static final String BLANK_LINE = ""; - private final String request; + private final HttpRequest request; private final ByteArrayOutputStream outputStream; - public StubSocket(final String request) { + public StubSocket(final HttpRequest request) { this.request = request; this.outputStream = new ByteArrayOutputStream(); } public StubSocket() { - this("GET / HTTP/1.1\r\nHost: localhost:8080\r\n\r\n"); + this(createDefaultRequest()); + } + + private static HttpRequest createDefaultRequest() { + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + return new HttpRequest(requestLine, headers, HttpBody.empty()); } @Override @@ -39,7 +61,7 @@ public int getPort() { @Override public InputStream getInputStream() { - return new ByteArrayInputStream(request.getBytes()); + return new ByteArrayInputStream(serialize(request).getBytes()); } @Override @@ -55,4 +77,40 @@ public void write(final int b) { public String output() { return outputStream.toString(StandardCharsets.UTF_8); } + + private String serialize(final HttpRequest request) { + final StringBuilder builder = new StringBuilder(); + + serializeRequestLine(request, builder); + serializeHeaders(request, builder); + + if (request.getHttpBody() == null || request.getHttpBody().getValue().isEmpty()) { + builder.append(CRLF); + return builder.toString(); + } + + builder.append(HttpHeader.CONTENT_LENGTH.getValue()) + .append(HEADER_DELIMETER) + .append(request.getHttpBody().getValue().getBytes().length) + .append(SPACE).append(CRLF); + + serializeBody(request, builder); + return builder.toString(); + } + + private void serializeRequestLine(final HttpRequest request, final StringBuilder builder) { + builder.append(request.getRequestLine().getHttpMethod().name()).append(SPACE); + builder.append(request.getRequestLine().getRequestUri().getRequestUri()).append(SPACE); + builder.append(request.getRequestLine().getProtocol().getName()).append(SPACE).append(CRLF); + } + + private void serializeHeaders(final HttpRequest request, final StringBuilder builder) { + request.getHeaders().getHeaders() + .forEach((key, value) -> builder.append(key.getValue()).append(HEADER_DELIMETER).append(value).append(SPACE).append(CRLF)); + } + + private void serializeBody(final HttpRequest request, final StringBuilder builder) { + builder.append(BLANK_LINE).append(CRLF); + builder.append(request.getHttpBody().getValue()); + } } From 0ecf383356ae3d153fb4802ef2d1060cc288e5bd Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 14:55:13 +0900 Subject: [PATCH 31/43] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=95=98=EA=B8=B0=20=EC=89=AC?= =?UTF-8?q?=EC=9A=B4=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/java/nextstep/Application.java | 3 ++- .../main/java/nextstep/jwp/controller/FrontHandler.java | 5 +++-- .../java/nextstep/jwp/controller/LoginController.java | 9 ++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tomcat/src/main/java/nextstep/Application.java b/tomcat/src/main/java/nextstep/Application.java index 393b2027d3..c531ff5bfc 100644 --- a/tomcat/src/main/java/nextstep/Application.java +++ b/tomcat/src/main/java/nextstep/Application.java @@ -2,11 +2,12 @@ import nextstep.jwp.controller.FrontHandler; import org.apache.catalina.startup.Tomcat; +import org.apache.coyote.http.session.SessionManager; public class Application { public static void main(final String[] args) { - final var tomcat = new Tomcat(new FrontHandler()); + final var tomcat = new Tomcat(new FrontHandler(new SessionManager())); tomcat.start(); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java index bd3841ccbc..b4b1b4542c 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java @@ -2,6 +2,7 @@ import org.apache.coyote.controller.Controller; import org.apache.coyote.controller.RequestHandler; +import org.apache.coyote.http.LoginManager; import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; @@ -14,10 +15,10 @@ public class FrontHandler implements RequestHandler { private static final Set requestControllers = new HashSet<>(); - static { + public FrontHandler(final LoginManager loginManager) { requestControllers.add(new HomePageController()); requestControllers.add(new StaticFileController()); - requestControllers.add(new LoginController()); + requestControllers.add(new LoginController(loginManager)); requestControllers.add(new RegisterController()); } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index d502c4b409..b6f0273bec 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -13,7 +13,6 @@ import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; import org.apache.coyote.http.session.Session; -import org.apache.coyote.http.session.SessionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,11 +27,15 @@ public class LoginController extends RequestController { - private static final LoginManager loginManager = new SessionManager(); - private static final String TARGET_URI = "login"; private static final Logger log = LoggerFactory.getLogger(LoginController.class); + private final LoginManager loginManager; + + public LoginController(final LoginManager loginManager) { + this.loginManager = loginManager; + } + @Override public boolean supports(final HttpRequest httpRequest) { return httpRequest.containsRequestUri(TARGET_URI); From 1994cc3662761e336a9378f428cdc664eb6045c5 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 14:56:22 +0900 Subject: [PATCH 32/43] =?UTF-8?q?test:=20E2E=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/Http11ProcessorTest.java | 156 +++++++++++++++++- tomcat/src/test/java/support/StubSocket.java | 4 +- 2 files changed, 154 insertions(+), 6 deletions(-) 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 d093486f68..c1a3890a8e 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 @@ -13,7 +13,10 @@ import org.apache.coyote.http.response.HttpResponse; import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; +import org.apache.coyote.http.session.SessionManager; import org.apache.coyote.http11.Http11Processor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import support.StubSocket; @@ -21,6 +24,9 @@ import java.util.EnumMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; class Http11ProcessorTest { @@ -28,7 +34,7 @@ class Http11ProcessorTest { void process() { // given final var socket = new StubSocket(); - final var processor = new Http11Processor(socket, new FrontHandler()); + final var processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); // when processor.process(socket); @@ -43,16 +49,15 @@ void process() { } @Test - void index() throws IOException { + void index_html을_GET_요청하면_해당_페이지로_이동한다() throws IOException { // given final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/index.html"), Protocol.HTTP_1_1); final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); headers.add(HttpHeader.HOST, "localhost:8080"); - headers.add(HttpHeader.CONNECTION, "keep-alive"); final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler()); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); // when processor.process(socket); @@ -65,4 +70,147 @@ void index() throws IOException { assertThat(socket.output()).isEqualTo(expected.serialize()); } + + @DisplayName("로그인 관련 테스트") + @Nested + class Login { + + @Test + void login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(HttpBody.file("/login.html")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); + } + + @Test + void 정상_로그인_정보를_입력하고_login으로_POST_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&password=password")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + + @Test + void 비정상_로그인_정보를_입력하고_login으로_POST_요청하면_401페이지로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=invalid&password=invalid")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/401.html"); + } + + @Test + void 로그인된_상태로_login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.COOKIE, "JSESSIONID=AlreadyLogined"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final SessionManager spySessionManager = spy(SessionManager.class); + given(spySessionManager.isAlreadyLogined(anyString())).willReturn(true); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(spySessionManager)); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + } + + @DisplayName("회원가입 관련 테스트") + @Nested + class Register { + + @Test + void register으로_POST_요청하면_해당_페이지로_이동한다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/register"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&email=gugu@gugu.com&password=password")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + + @Test + void register으로_GET_요청하면_register_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(HttpBody.file("/login.html")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); + } + } } diff --git a/tomcat/src/test/java/support/StubSocket.java b/tomcat/src/test/java/support/StubSocket.java index 8702c44a71..7fa00925f2 100644 --- a/tomcat/src/test/java/support/StubSocket.java +++ b/tomcat/src/test/java/support/StubSocket.java @@ -20,7 +20,7 @@ import java.util.EnumMap; public class StubSocket extends Socket { - + private static final String SPACE = " "; private static final String HEADER_DELIMETER = ": "; private static final String CRLF = "\r\n"; @@ -92,7 +92,7 @@ private String serialize(final HttpRequest request) { builder.append(HttpHeader.CONTENT_LENGTH.getValue()) .append(HEADER_DELIMETER) .append(request.getHttpBody().getValue().getBytes().length) - .append(SPACE).append(CRLF); + .append(CRLF); serializeBody(request, builder); return builder.toString(); From f3cfa28e12b18321f3c0083eeb8bc88a9991e7bf Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 14:57:50 +0900 Subject: [PATCH 33/43] =?UTF-8?q?test:=20Processor=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http11/Http11ProcessorLoginTest.java | 126 +++++++++++++++ .../http11/Http11ProcessorRegisterTest.java | 78 +++++++++ .../coyote/http11/Http11ProcessorTest.java | 148 ------------------ 3 files changed, 204 insertions(+), 148 deletions(-) create mode 100644 tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorLoginTest.java create mode 100644 tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorLoginTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorLoginTest.java new file mode 100644 index 0000000000..049e490f22 --- /dev/null +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorLoginTest.java @@ -0,0 +1,126 @@ +package nextstep.org.apache.coyote.http11; + +import nextstep.jwp.controller.FrontHandler; +import org.apache.coyote.http.common.ContentType; +import org.apache.coyote.http.common.HttpBody; +import org.apache.coyote.http.common.HttpHeader; +import org.apache.coyote.http.common.HttpHeaders; +import org.apache.coyote.http.common.Protocol; +import org.apache.coyote.http.request.HttpMethod; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.RequestLine; +import org.apache.coyote.http.request.RequestUri; +import org.apache.coyote.http.response.HttpResponse; +import org.apache.coyote.http.response.StatusCode; +import org.apache.coyote.http.response.StatusLine; +import org.apache.coyote.http.session.SessionManager; +import org.apache.coyote.http11.Http11Processor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import support.StubSocket; + +import java.io.IOException; +import java.util.EnumMap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; + +class Http11ProcessorLoginTest { + + @DisplayName("로그인 관련 테스트") + @Nested + class Login { + + @Test + void login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(HttpBody.file("/login.html")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); + } + + @Test + void 정상_로그인_정보를_입력하고_login으로_POST_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&password=password")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + + @Test + void 비정상_로그인_정보를_입력하고_login으로_POST_요청하면_401페이지로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=invalid&password=invalid")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/401.html"); + } + + @Test + void 로그인된_상태로_login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.COOKIE, "JSESSIONID=AlreadyLogined"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final SessionManager spySessionManager = spy(SessionManager.class); + given(spySessionManager.isAlreadyLogined(anyString())).willReturn(true); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(spySessionManager)); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + } +} diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java new file mode 100644 index 0000000000..c14b8a7d10 --- /dev/null +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java @@ -0,0 +1,78 @@ +package nextstep.org.apache.coyote.http11; + +import nextstep.jwp.controller.FrontHandler; +import org.apache.coyote.http.common.ContentType; +import org.apache.coyote.http.common.HttpBody; +import org.apache.coyote.http.common.HttpHeader; +import org.apache.coyote.http.common.HttpHeaders; +import org.apache.coyote.http.common.Protocol; +import org.apache.coyote.http.request.HttpMethod; +import org.apache.coyote.http.request.HttpRequest; +import org.apache.coyote.http.request.RequestLine; +import org.apache.coyote.http.request.RequestUri; +import org.apache.coyote.http.response.HttpResponse; +import org.apache.coyote.http.response.StatusCode; +import org.apache.coyote.http.response.StatusLine; +import org.apache.coyote.http.session.SessionManager; +import org.apache.coyote.http11.Http11Processor; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import support.StubSocket; + +import java.io.IOException; +import java.util.EnumMap; + +import static org.assertj.core.api.Assertions.assertThat; + +class Http11ProcessorRegisterTest { + + @DisplayName("회원가입 관련 테스트") + @Nested + class Register { + + @Test + void register으로_POST_요청하면_해당_페이지로_이동한다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/register"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&email=gugu@gugu.com&password=password")); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + assertThat(socket.output()) + .contains(StatusCode.FOUND.name()) + .contains("/index.html"); + } + + @Test + void register으로_GET_요청하면_register_html로_리다이렉트_된다() throws IOException { + // given + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); + headers.add(HttpHeader.HOST, "localhost:8080"); + final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); + + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); + + // when + processor.process(socket); + + // then + final HttpResponse expected = new HttpResponse(); + expected.changeStatusLine(StatusLine.from(StatusCode.OK)); + expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); + expected.changeBody(HttpBody.file("/login.html")); + + assertThat(socket.output()).isEqualTo(expected.serialize()); + } + } +} 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 c1a3890a8e..086b67719c 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 @@ -15,8 +15,6 @@ import org.apache.coyote.http.response.StatusLine; import org.apache.coyote.http.session.SessionManager; import org.apache.coyote.http11.Http11Processor; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import support.StubSocket; @@ -24,9 +22,6 @@ import java.util.EnumMap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.spy; class Http11ProcessorTest { @@ -70,147 +65,4 @@ void process() { assertThat(socket.output()).isEqualTo(expected.serialize()); } - - @DisplayName("로그인 관련 테스트") - @Nested - class Login { - - @Test - void login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); - - // when - processor.process(socket); - - // then - final HttpResponse expected = new HttpResponse(); - expected.changeStatusLine(StatusLine.from(StatusCode.OK)); - expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); - expected.changeBody(HttpBody.file("/login.html")); - - assertThat(socket.output()).isEqualTo(expected.serialize()); - } - - @Test - void 정상_로그인_정보를_입력하고_login으로_POST_요청하면_index_html로_리다이렉트_된다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&password=password")); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); - - // when - processor.process(socket); - - // then - assertThat(socket.output()) - .contains(StatusCode.FOUND.name()) - .contains("/index.html"); - } - - @Test - void 비정상_로그인_정보를_입력하고_login으로_POST_요청하면_401페이지로_리다이렉트_된다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/login"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=invalid&password=invalid")); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); - - // when - processor.process(socket); - - // then - assertThat(socket.output()) - .contains(StatusCode.FOUND.name()) - .contains("/401.html"); - } - - @Test - void 로그인된_상태로_login으로_GET_요청하면_index_html로_리다이렉트_된다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - headers.add(HttpHeader.COOKIE, "JSESSIONID=AlreadyLogined"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); - - final SessionManager spySessionManager = spy(SessionManager.class); - given(spySessionManager.isAlreadyLogined(anyString())).willReturn(true); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(spySessionManager)); - - // when - processor.process(socket); - - // then - assertThat(socket.output()) - .contains(StatusCode.FOUND.name()) - .contains("/index.html"); - } - } - - @DisplayName("회원가입 관련 테스트") - @Nested - class Register { - - @Test - void register으로_POST_요청하면_해당_페이지로_이동한다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/register"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - headers.add(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, new HttpBody("account=gugu&email=gugu@gugu.com&password=password")); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); - - // when - processor.process(socket); - - // then - assertThat(socket.output()) - .contains(StatusCode.FOUND.name()) - .contains("/index.html"); - } - - @Test - void register으로_GET_요청하면_register_html로_리다이렉트_된다() throws IOException { - // given - final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); - final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); - headers.add(HttpHeader.HOST, "localhost:8080"); - final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); - - final var socket = new StubSocket(httpRequest); - final Http11Processor processor = new Http11Processor(socket, new FrontHandler(new SessionManager())); - - // when - processor.process(socket); - - // then - final HttpResponse expected = new HttpResponse(); - expected.changeStatusLine(StatusLine.from(StatusCode.OK)); - expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); - expected.changeBody(HttpBody.file("/login.html")); - - assertThat(socket.output()).isEqualTo(expected.serialize()); - } - } } From c91cd6d85e69d5b1795c2dbd568335755e5b7653 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 16:58:23 +0900 Subject: [PATCH 34/43] =?UTF-8?q?fix:=20=EC=9E=90=EC=9B=90=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java index b4b1b4542c..81fdb4f8c9 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java @@ -13,7 +13,7 @@ public class FrontHandler implements RequestHandler { - private static final Set requestControllers = new HashSet<>(); + private final Set requestControllers = new HashSet<>(); public FrontHandler(final LoginManager loginManager) { requestControllers.add(new HomePageController()); From 8ff9c92f29c55a617905e70e4394a2326446e7b7 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 17:24:32 +0900 Subject: [PATCH 35/43] =?UTF-8?q?refactor:=20LoginController=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/LoginController.java | 139 ++++++++++++------ 1 file changed, 92 insertions(+), 47 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index b6f0273bec..e882cd21e4 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -16,6 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.Map; import java.util.UUID; @@ -43,82 +44,126 @@ public boolean supports(final HttpRequest httpRequest) { @Override protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { - final Map bodyParams = request.getParsedBody(); - final String account = bodyParams.get("account"); - final String password = bodyParams.get("password"); - - User user = null; try { - user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); + final User user = getValidateUser(request); - if (!user.checkPassword(password)) { - throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); - } log.info("로그인 성공! user = {}", user); + final UUID uuid = createSessionToUser(user); + + setCookieAndRedirectToMain(response, uuid); } catch (final IllegalArgumentException e) { log.warn("login error = {}", e); - response.mapToRedirect(UNAUTHORIZED.getPath()); - return; + redirectToUnAuthorized(response); } + } - final UUID uuid = UUID.randomUUID(); - setSession(uuid.toString(), Map.of("account", user.getAccount())); + private static User getValidateUser(final HttpRequest request) { + final Map bodyParams = request.getParsedBody(); + final String account = bodyParams.get("account"); + final String password = bodyParams.get("password"); - response.changeStatusLine(StatusLine.from(StatusCode.FOUND)); - response.addHeader(HttpHeader.LOCATION, MAIN.getPath()); - response.addHeader(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid); - response.changeBody(HttpBody.empty()); + final User user = InMemoryUserRepository.findByAccount(account) + .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); + + if (!user.checkPassword(password)) { + throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); + } + + return user; } - private void setSession(final String jSessionId, final Map sessionData) { - final Session session = new Session(jSessionId); + private UUID createSessionToUser(final User user) { + final UUID uuid = UUID.randomUUID(); + + final Map sessionData = Map.of("account", user.getAccount()); + final Session session = new Session(uuid.toString()); for (final Map.Entry entry : sessionData.entrySet()) { session.add(entry.getKey(), entry.getValue()); } + loginManager.add(session); + + return uuid; + } + + private static void setCookieAndRedirectToMain(final HttpResponse response, final UUID uuid) { + response.changeStatusLine(StatusLine.from(StatusCode.FOUND)); + response.addHeader(HttpHeader.LOCATION, MAIN.getPath()); + response.addHeader(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid); + response.changeBody(HttpBody.empty()); } @Override protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { - if (request.containsHeader(COOKIE)) { - final HttpCookie cookies = HttpCookie.from(request.getHeader(COOKIE)); - if (isAlreadyLogined(cookies.get("JSESSIONID"))) { - response.mapToRedirect(MAIN.getPath()); - return; - } + if (isAlreadyLogined(request)) { + redirectToMain(response); + return; } - if (request.hasQueryString()) { - final QueryString queryString = request.getQueryString(); + if (wantToLogin(request)) { + doLoginProcess(request, response); + return; + } + + redirectToLoginPage(response); + } - final String account = queryString.get("account"); - final String password = queryString.get("password"); + private boolean isAlreadyLogined(final HttpRequest request) { + if (!request.containsHeader(COOKIE)) { + return false; + } + + final HttpCookie cookies = HttpCookie.from(request.getHeader(COOKIE)); - try { - final User user = InMemoryUserRepository.findByAccount(account) - .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); + return checkLogin(cookies.get("JSESSIONID")); + } - if (!user.checkPassword(password)) { - throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); - } - log.info("로그인 성공! user = {}", user); - } catch (final IllegalArgumentException e) { - log.warn("login error = {}", e); - response.mapToRedirect(UNAUTHORIZED.getPath()); - return; - } + private void redirectToMain(final HttpResponse response) { + response.mapToRedirect(MAIN.getPath()); + } - response.mapToRedirect(MAIN.getPath()); + private static boolean wantToLogin(final HttpRequest request) { + return request.hasQueryString(); + } + + private void doLoginProcess(final HttpRequest request, final HttpResponse response) { + final QueryString queryString = request.getQueryString(); + + final String account = queryString.get("account"); + final String password = queryString.get("password"); + + try { + validateUserCredentials(account, password); + log.info("로그인 성공! account = {}", account); + } catch (final IllegalArgumentException e) { + log.warn("login error = {}", e); + redirectToUnAuthorized(response); return; } - response.changeStatusLine(StatusLine.from(StatusCode.OK)); - response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); - response.changeBody(HttpBody.file(LOGIN.getPath())); + redirectToMain(response); + } + + private void redirectToUnAuthorized(final HttpResponse response) { + response.mapToRedirect(UNAUTHORIZED.getPath()); + } + + private void validateUserCredentials(final String account, final String password) { + final User user = InMemoryUserRepository.findByAccount(account) + .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); + + if (!user.checkPassword(password)) { + throw new IllegalArgumentException("잘못된 비밀번호입니다. 다시 입력해주세요."); + } } - private boolean isAlreadyLogined(final String jSessionId) { + private boolean checkLogin(final String jSessionId) { return loginManager.isAlreadyLogined(jSessionId); } + + private void redirectToLoginPage(final HttpResponse response) throws IOException { + response.changeStatusLine(StatusLine.from(StatusCode.OK)); + response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); + response.changeBody(HttpBody.file(LOGIN.getPath())); + } } From 86b6d327af03073509ee1755a12fe091f18b00d2 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 21:50:42 +0900 Subject: [PATCH 36/43] =?UTF-8?q?feat:=20Default=20Max=20Thread=20Size=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 --- .../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 e4697f7635..32c365b843 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -9,6 +9,8 @@ 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 { @@ -16,19 +18,22 @@ 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_SIZE = 250; private final ServerSocket serverSocket; private final RequestHandler requestHandler; private boolean stopped; + private final ExecutorService executorService; public Connector(final RequestHandler requestHandler) { - this(requestHandler, DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + this(requestHandler, DEFAULT_PORT, DEFAULT_ACCEPT_COUNT, DEFAULT_MAX_THREADS_SIZE); } - public Connector(final RequestHandler requestHandler, final int port, final int acceptCount) { + public Connector(final RequestHandler requestHandler, final int port, final int acceptCount, final int maxThreads) { this.requestHandler = requestHandler; this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; + this.executorService = Executors.newFixedThreadPool(maxThreads); } private ServerSocket createServerSocket(final int port, final int acceptCount) { @@ -70,7 +75,7 @@ private void process(final Socket connection, final RequestHandler requestHandle return; } final var processor = new Http11Processor(connection, requestHandler); - new Thread(processor).start(); + executorService.execute(processor); } public void stop() { From 207e696a94d73c167bddce32bc34dc9dbfadb425 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 21:51:54 +0900 Subject: [PATCH 37/43] =?UTF-8?q?refactor:=20SessionManager=EC=97=90=20Con?= =?UTF-8?q?currentHashMap=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http/session/SessionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http/session/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http/session/SessionManager.java index c3dada960c..12c9fee1b0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/session/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/http/session/SessionManager.java @@ -2,12 +2,12 @@ import org.apache.coyote.http.LoginManager; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public class SessionManager implements LoginManager { - private static final Map SESSIONS = new HashMap<>(); + private static final Map SESSIONS = new ConcurrentHashMap<>(); @Override public void add(final Session session) { From 73966b1dc1f11db83021fd0a127bca3de4e7ede4 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 8 Sep 2023 23:16:09 +0900 Subject: [PATCH 38/43] =?UTF-8?q?refactor:=20code=20smell=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nextstep/jwp/controller/FrontHandler.java | 5 ++-- .../jwp/controller/HomePageController.java | 4 +-- .../jwp/controller/LoginController.java | 28 ++++++++++--------- .../java/nextstep/jwp/controller/Path.java | 10 +++---- .../jwp/controller/RegisterController.java | 9 +++--- .../jwp/controller/RequestController.java | 8 ++++-- .../jwp/controller/StaticFileController.java | 4 +-- .../apache/coyote/controller/Controller.java | 4 ++- .../coyote/controller/RequestHandler.java | 4 ++- .../coyote/http/common/HttpHeaders.java | 6 ++-- 10 files changed, 46 insertions(+), 36 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java index 81fdb4f8c9..82656d58e6 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/FrontHandler.java @@ -6,6 +6,7 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; +import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -23,7 +24,7 @@ public FrontHandler(final LoginManager loginManager) { } @Override - public void handle(final HttpRequest request, final HttpResponse response) throws Exception { + public void handle(final HttpRequest request, final HttpResponse response) throws IOException { for (final Controller controller : requestControllers) { if (controller.supports(request)) { controller.service(request, response); @@ -31,6 +32,6 @@ public void handle(final HttpRequest request, final HttpResponse response) throw } } - response.mapToRedirect(NOT_FOUND.getPath()); + response.mapToRedirect(NOT_FOUND.getValue()); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java b/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java index 70ce0ea20d..fef538dbf4 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/HomePageController.java @@ -20,12 +20,12 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doPost(final HttpRequest request, final HttpResponse response) { throw new UnsupportedOperationException(); } @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doGet(final HttpRequest request, final HttpResponse response) { response.changeStatusLine(StatusLine.from(StatusCode.OK)); response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); response.changeBody(new HttpBody(HOME_MESSAGE)); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index e882cd21e4..a254d2c6ba 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -30,6 +30,8 @@ public class LoginController extends RequestController { private static final String TARGET_URI = "login"; private static final Logger log = LoggerFactory.getLogger(LoginController.class); + private static final String CREDENTIALS = "account"; + private static final String PASSWORD = "password"; private final LoginManager loginManager; @@ -43,7 +45,7 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doPost(final HttpRequest request, final HttpResponse response) { try { final User user = getValidateUser(request); @@ -52,15 +54,15 @@ protected void doPost(final HttpRequest request, final HttpResponse response) th setCookieAndRedirectToMain(response, uuid); } catch (final IllegalArgumentException e) { - log.warn("login error = {}", e); + log.warn("login error = {}", e.getMessage()); redirectToUnAuthorized(response); } } private static User getValidateUser(final HttpRequest request) { final Map bodyParams = request.getParsedBody(); - final String account = bodyParams.get("account"); - final String password = bodyParams.get("password"); + final String account = bodyParams.get(CREDENTIALS); + final String password = bodyParams.get(PASSWORD); final User user = InMemoryUserRepository.findByAccount(account) .orElseThrow(() -> new IllegalArgumentException("잘못된 계정입니다. 다시 입력해주세요.")); @@ -75,7 +77,7 @@ private static User getValidateUser(final HttpRequest request) { private UUID createSessionToUser(final User user) { final UUID uuid = UUID.randomUUID(); - final Map sessionData = Map.of("account", user.getAccount()); + final Map sessionData = Map.of(CREDENTIALS, user.getAccount()); final Session session = new Session(uuid.toString()); for (final Map.Entry entry : sessionData.entrySet()) { session.add(entry.getKey(), entry.getValue()); @@ -88,13 +90,13 @@ private UUID createSessionToUser(final User user) { private static void setCookieAndRedirectToMain(final HttpResponse response, final UUID uuid) { response.changeStatusLine(StatusLine.from(StatusCode.FOUND)); - response.addHeader(HttpHeader.LOCATION, MAIN.getPath()); + response.addHeader(HttpHeader.LOCATION, MAIN.getValue()); response.addHeader(HttpHeader.SET_COOKIE, "JSESSIONID=" + uuid); response.changeBody(HttpBody.empty()); } @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doGet(final HttpRequest request, final HttpResponse response) throws IOException { if (isAlreadyLogined(request)) { redirectToMain(response); return; @@ -119,7 +121,7 @@ private boolean isAlreadyLogined(final HttpRequest request) { } private void redirectToMain(final HttpResponse response) { - response.mapToRedirect(MAIN.getPath()); + response.mapToRedirect(MAIN.getValue()); } private static boolean wantToLogin(final HttpRequest request) { @@ -129,14 +131,14 @@ private static boolean wantToLogin(final HttpRequest request) { private void doLoginProcess(final HttpRequest request, final HttpResponse response) { final QueryString queryString = request.getQueryString(); - final String account = queryString.get("account"); - final String password = queryString.get("password"); + final String account = queryString.get(CREDENTIALS); + final String password = queryString.get(PASSWORD); try { validateUserCredentials(account, password); log.info("로그인 성공! account = {}", account); } catch (final IllegalArgumentException e) { - log.warn("login error = {}", e); + log.warn("login error = {}", e.getMessage()); redirectToUnAuthorized(response); return; } @@ -145,7 +147,7 @@ private void doLoginProcess(final HttpRequest request, final HttpResponse respon } private void redirectToUnAuthorized(final HttpResponse response) { - response.mapToRedirect(UNAUTHORIZED.getPath()); + response.mapToRedirect(UNAUTHORIZED.getValue()); } private void validateUserCredentials(final String account, final String password) { @@ -164,6 +166,6 @@ private boolean checkLogin(final String jSessionId) { private void redirectToLoginPage(final HttpResponse response) throws IOException { response.changeStatusLine(StatusLine.from(StatusCode.OK)); response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); - response.changeBody(HttpBody.file(LOGIN.getPath())); + response.changeBody(HttpBody.file(LOGIN.getValue())); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/Path.java b/tomcat/src/main/java/nextstep/jwp/controller/Path.java index 29fc253737..82b9c32a52 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/Path.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/Path.java @@ -9,13 +9,13 @@ public enum Path { UNAUTHORIZED("/401.html"), NOT_FOUND("/404.html"); - private final String path; + private final String value; - Path(final String path) { - this.path = path; + Path(final String value) { + this.value = value; } - public String getPath() { - return path; + public String getValue() { + return value; } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index 2adc74a068..08787f75fb 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -9,6 +9,7 @@ import org.apache.coyote.http.response.StatusCode; import org.apache.coyote.http.response.StatusLine; +import java.io.IOException; import java.util.Map; import static nextstep.jwp.controller.Path.MAIN; @@ -24,7 +25,7 @@ public boolean supports(final HttpRequest httpRequest) { } @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doPost(final HttpRequest request, final HttpResponse response) { final Map bodyParams = request.getParsedBody(); final String account = bodyParams.get("account"); @@ -34,13 +35,13 @@ protected void doPost(final HttpRequest request, final HttpResponse response) th final User user = new User(account, password, email); InMemoryUserRepository.save(user); - response.mapToRedirect(MAIN.getPath()); + response.mapToRedirect(MAIN.getValue()); } @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doGet(final HttpRequest request, final HttpResponse response) throws IOException { response.changeStatusLine(StatusLine.from(StatusCode.OK)); response.addHeader(CONTENT_TYPE, ContentType.HTML.getValue()); - response.changeBody(HttpBody.file(REGISTER.getPath())); + response.changeBody(HttpBody.file(REGISTER.getValue())); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java b/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java index 7213b3e715..e4d397e201 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RequestController.java @@ -5,10 +5,12 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; +import java.io.IOException; + public abstract class RequestController implements Controller { @Override - public void service(final HttpRequest request, final HttpResponse response) throws Exception { + public void service(final HttpRequest request, final HttpResponse response) throws IOException { if (request.isSameRequestMethod(HttpMethod.GET)) { doGet(request, response); return; @@ -22,7 +24,7 @@ public void service(final HttpRequest request, final HttpResponse response) thro throw new UnsupportedOperationException("지원하지 않는 HTTP Method 입니다."); } - protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; + protected abstract void doPost(final HttpRequest request, final HttpResponse response); - protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; + protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws IOException; } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java index c8040cf1ca..c3c586d18e 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java @@ -30,12 +30,12 @@ private static boolean isStaticFile(final HttpRequest httpRequest) { } @Override - protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doPost(final HttpRequest request, final HttpResponse response) { throw new UnsupportedOperationException(); } @Override - protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { + protected void doGet(final HttpRequest request, final HttpResponse response) throws IOException { final String filePath = request.getRequestUri().getRequestUri(); if (request.isRequestUriEndsWith(HTML.getFileExtension())) { diff --git a/tomcat/src/main/java/org/apache/coyote/controller/Controller.java b/tomcat/src/main/java/org/apache/coyote/controller/Controller.java index d20592063e..da6da0b363 100644 --- a/tomcat/src/main/java/org/apache/coyote/controller/Controller.java +++ b/tomcat/src/main/java/org/apache/coyote/controller/Controller.java @@ -3,9 +3,11 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; +import java.io.IOException; + public interface Controller { boolean supports(final HttpRequest httpRequest); - void service(final HttpRequest request, final HttpResponse response) throws Exception; + void service(final HttpRequest request, final HttpResponse response) throws IOException; } diff --git a/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java b/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java index 1551797b18..a98f2d7824 100644 --- a/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/controller/RequestHandler.java @@ -3,7 +3,9 @@ import org.apache.coyote.http.request.HttpRequest; import org.apache.coyote.http.response.HttpResponse; +import java.io.IOException; + public interface RequestHandler { - void handle(final HttpRequest request, final HttpResponse response) throws Exception; + void handle(final HttpRequest request, final HttpResponse response) throws IOException; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java b/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java index 06002541ef..0d439dad5a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java +++ b/tomcat/src/main/java/org/apache/coyote/http/common/HttpHeaders.java @@ -1,13 +1,12 @@ package org.apache.coyote.http.common; -import java.util.EnumMap; import java.util.Map; public class HttpHeaders { - private final EnumMap headers; + private final Map headers; - public HttpHeaders(final EnumMap headers) { + public HttpHeaders(final Map headers) { this.headers = headers; } @@ -30,6 +29,7 @@ public void add(final HttpHeader key, final String value) { public void add(final HttpHeaders httpHeaders) { headers.putAll(httpHeaders.getHeaders()); } + public Map getHeaders() { return headers; } From ed006cb7e31c73fcd13f01fd76504e868a784487 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 12 Sep 2023 09:28:20 +0900 Subject: [PATCH 39/43] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20static=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/jwp/controller/LoginController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index a254d2c6ba..dd6235a2d7 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -59,7 +59,7 @@ protected void doPost(final HttpRequest request, final HttpResponse response) { } } - private static User getValidateUser(final HttpRequest request) { + private User getValidateUser(final HttpRequest request) { final Map bodyParams = request.getParsedBody(); final String account = bodyParams.get(CREDENTIALS); final String password = bodyParams.get(PASSWORD); @@ -124,7 +124,7 @@ private void redirectToMain(final HttpResponse response) { response.mapToRedirect(MAIN.getValue()); } - private static boolean wantToLogin(final HttpRequest request) { + private boolean wantToLogin(final HttpRequest request) { return request.hasQueryString(); } From 93513c95fffa53504edc5707300b6b4b06de4045 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 12 Sep 2023 09:31:39 +0900 Subject: [PATCH 40/43] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/StaticFileController.java | 16 ++++++++-------- .../apache/coyote/http/request/HttpRequest.java | 4 ++-- .../apache/coyote/http/request/RequestLine.java | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java index c3c586d18e..07930b7bd0 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java @@ -23,10 +23,10 @@ public boolean supports(final HttpRequest httpRequest) { } private static boolean isStaticFile(final HttpRequest httpRequest) { - return httpRequest.isRequestUriEndsWith(HTML.getFileExtension()) || - httpRequest.isRequestUriEndsWith(JS.getFileExtension()) || - httpRequest.isRequestUriEndsWith(CSS.getFileExtension()) || - httpRequest.isRequestUriEndsWith(ICO.getFileExtension()); + return httpRequest.isEndsWithRequestUri(HTML.getFileExtension()) || + httpRequest.isEndsWithRequestUri(JS.getFileExtension()) || + httpRequest.isEndsWithRequestUri(CSS.getFileExtension()) || + httpRequest.isEndsWithRequestUri(ICO.getFileExtension()); } @Override @@ -38,22 +38,22 @@ protected void doPost(final HttpRequest request, final HttpResponse response) { protected void doGet(final HttpRequest request, final HttpResponse response) throws IOException { final String filePath = request.getRequestUri().getRequestUri(); - if (request.isRequestUriEndsWith(HTML.getFileExtension())) { + if (request.isEndsWithRequestUri(HTML.getFileExtension())) { createHttpResponseByContentTypeAndPath(response, HTML, filePath); return; } - if (request.isRequestUriEndsWith(JS.getFileExtension())) { + if (request.isEndsWithRequestUri(JS.getFileExtension())) { createHttpResponseByContentTypeAndPath(response, JS, filePath); return; } - if (request.isRequestUriEndsWith(CSS.getFileExtension())) { + if (request.isEndsWithRequestUri(CSS.getFileExtension())) { createHttpResponseByContentTypeAndPath(response, CSS, filePath); return; } - if (request.isRequestUriEndsWith(ICO.getFileExtension())) { + if (request.isEndsWithRequestUri(ICO.getFileExtension())) { createHttpResponseByContentTypeAndPath(response, ICO, filePath); return; } diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java index a795a7855c..353360be2a 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/HttpRequest.java @@ -30,8 +30,8 @@ public boolean hasQueryString() { return requestLine.containsRequestUri("?"); } - public boolean isRequestUriEndsWith(final String uri) { - return requestLine.endsWithRequestUri(uri); + public boolean isEndsWithRequestUri(final String uri) { + return requestLine.isEndsWithRequestUri(uri); } public boolean containsHeader(final HttpHeader headerName) { diff --git a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java index 6c9950fbe3..edd52ebe5c 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/http/request/RequestLine.java @@ -34,7 +34,7 @@ public boolean containsRequestUri(final String uri) { return requestUri.contains(uri); } - public boolean endsWithRequestUri(final String uri) { + public boolean isEndsWithRequestUri(final String uri) { return requestUri.endsWith(uri); } From f3c9cb788c17012ed25b0e572b92dc165a248a18 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 12 Sep 2023 09:32:37 +0900 Subject: [PATCH 41/43] =?UTF-8?q?refactor:=20HttpResponse=20serialize=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 --- .../java/org/apache/coyote/http/response/HttpResponse.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java index 087d452d0d..dd499c6715 100644 --- a/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http/response/HttpResponse.java @@ -49,7 +49,11 @@ public String serialize() { return response.toString(); } - response.append(HttpHeader.CONTENT_LENGTH.getValue()).append(HEADER_DELIMETER).append(body.getValue().getBytes().length).append(SPACE).append(CRLF); + response.append(HttpHeader.CONTENT_LENGTH.getValue()) + .append(HEADER_DELIMETER) + .append(body.getValue().getBytes().length) + .append(SPACE) + .append(CRLF); serializeBody(response); return response.toString(); From 5f735eb9332eafa7a9f3b96306ccd161826e0244 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 12 Sep 2023 09:50:15 +0900 Subject: [PATCH 42/43] =?UTF-8?q?refactor:=20=EB=B6=84=EA=B8=B0=EB=AC=B8?= =?UTF-8?q?=EC=9D=84=20stream=20=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/StaticFileController.java | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java index 07930b7bd0..3ad845946a 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticFileController.java @@ -8,6 +8,7 @@ import org.apache.coyote.http.response.StatusLine; import java.io.IOException; +import java.util.Arrays; import static org.apache.coyote.http.common.ContentType.CSS; import static org.apache.coyote.http.common.ContentType.HTML; @@ -38,27 +39,21 @@ protected void doPost(final HttpRequest request, final HttpResponse response) { protected void doGet(final HttpRequest request, final HttpResponse response) throws IOException { final String filePath = request.getRequestUri().getRequestUri(); - if (request.isEndsWithRequestUri(HTML.getFileExtension())) { - createHttpResponseByContentTypeAndPath(response, HTML, filePath); - return; - } - - if (request.isEndsWithRequestUri(JS.getFileExtension())) { - createHttpResponseByContentTypeAndPath(response, JS, filePath); - return; - } - - if (request.isEndsWithRequestUri(CSS.getFileExtension())) { - createHttpResponseByContentTypeAndPath(response, CSS, filePath); - return; - } + Arrays.stream(ContentType.values()) + .filter(contentType -> request.isEndsWithRequestUri(contentType.getFileExtension())) + .findAny() + .ifPresentOrElse( + contenttype -> createHttpResponse(response, contenttype, filePath), + () -> response.mapToRedirect("/404.html") + ); + } - if (request.isEndsWithRequestUri(ICO.getFileExtension())) { - createHttpResponseByContentTypeAndPath(response, ICO, filePath); - return; + private void createHttpResponse(final HttpResponse response, final ContentType contenttype, final String filePath) { + try { + createHttpResponseByContentTypeAndPath(response, contenttype, filePath); + } catch (final IOException e) { + throw new IllegalStateException(e); } - - response.mapToRedirect("/404.html"); } private void createHttpResponseByContentTypeAndPath(final HttpResponse response, final ContentType contentType, final String filePath) throws IOException { From e2b96bb0f686c2c5d79ae564551f4999acfaa521 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 13 Sep 2023 10:36:57 +0900 Subject: [PATCH 43/43] =?UTF-8?q?test:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=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/Http11ProcessorRegisterTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java index c14b8a7d10..f88308a0b4 100644 --- a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorRegisterTest.java @@ -32,7 +32,7 @@ class Http11ProcessorRegisterTest { class Register { @Test - void register으로_POST_요청하면_해당_페이지로_이동한다() throws IOException { + void register으로_POST_요청하면_index_html_페이지로_이동한다() throws IOException { // given final RequestLine requestLine = new RequestLine(HttpMethod.POST, new RequestUri("/register"), Protocol.HTTP_1_1); final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); @@ -53,9 +53,9 @@ class Register { } @Test - void register으로_GET_요청하면_register_html로_리다이렉트_된다() throws IOException { + void register으로_GET_요청하면_register_html로_이동한다() throws IOException { // given - final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/login"), Protocol.HTTP_1_1); + final RequestLine requestLine = new RequestLine(HttpMethod.GET, new RequestUri("/register"), Protocol.HTTP_1_1); final HttpHeaders headers = new HttpHeaders(new EnumMap<>(HttpHeader.class)); headers.add(HttpHeader.HOST, "localhost:8080"); final HttpRequest httpRequest = new HttpRequest(requestLine, headers, HttpBody.empty()); @@ -70,7 +70,7 @@ class Register { final HttpResponse expected = new HttpResponse(); expected.changeStatusLine(StatusLine.from(StatusCode.OK)); expected.addHeader(HttpHeader.CONTENT_TYPE, ContentType.HTML.getValue()); - expected.changeBody(HttpBody.file("/login.html")); + expected.changeBody(HttpBody.file("/register.html")); assertThat(socket.output()).isEqualTo(expected.serialize()); }