From 2ceb3b488021d1dd95c35759483578ebc15e09b4 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 00:03:45 +0900 Subject: [PATCH 01/13] =?UTF-8?q?refactor:=20ResponseHeader=EA=B0=80=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EC=88=9C=EC=84=9C=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/RequestProcessor.java | 34 ++++++++++--------- .../nextstep/jwp/request/RequestLine.java | 2 +- .../java/nextstep/jwp/request/RequestUri.java | 6 ++-- .../nextstep/jwp/response/HttpResponse.java | 4 +-- .../jwp/response/ResponseHeaders.java | 7 ++-- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java b/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java index 9516299fe6..3ac69129fa 100644 --- a/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java +++ b/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java @@ -6,6 +6,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -49,15 +50,15 @@ public HttpResponse process(final HttpRequest httpRequest) throws URISyntaxExcep if (requestUri.isEmpty()) { final String content = "Hello world!"; return HttpResponse.of(version, HttpStatus.OK, content, - Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length))); + new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), + CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); } if (requestUri.equals("register")) { final String content = makeResponseBody(requestUri); return HttpResponse.of(version, HttpStatus.OK, content, - Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length))); + new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), + CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); } if (requestUri.equals("login")) { @@ -65,19 +66,19 @@ public HttpResponse process(final HttpRequest httpRequest) throws URISyntaxExcep final Session session = SessionManager.findSession(sessionId); if (session != null) { return HttpResponse.of(version, HttpStatus.FOUND, null, - Map.of(LOCATION_HEADER, INDEX_PAGE)); + new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE))); } final String content = makeResponseBody(requestUri); return HttpResponse.of(version, HttpStatus.OK, content, - Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length))); + new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), + CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); } if (ContentType.isSupportedType(requestUri)) { final String content = makeResponseBody(requestUri); return HttpResponse.of(version, HttpStatus.OK, content, - Map.of(CONTENT_TYPE_HEADER, ContentType.getTypeByExtension(requestUri), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length))); + new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.getTypeByExtension(requestUri), + CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); } } @@ -91,13 +92,14 @@ public HttpResponse process(final HttpRequest httpRequest) throws URISyntaxExcep if (InMemoryUserRepository.findByAccount(registerInfo.get("account")).isPresent()) { return HttpResponse.of(version, HttpStatus.FOUND, null, - Map.of(LOCATION_HEADER, REGISTER_PAGE)); + new LinkedHashMap<>(Map.of(LOCATION_HEADER, REGISTER_PAGE))); } final User newUser = new User(registerInfo.get("account"), registerInfo.get("password"), registerInfo.get("email")); InMemoryUserRepository.save(newUser); - return HttpResponse.of(version, HttpStatus.FOUND, null, Map.of(LOCATION_HEADER, INDEX_PAGE)); + return HttpResponse.of(version, HttpStatus.FOUND, null, + new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE))); } if (requestUri.equals("login")) { @@ -116,20 +118,20 @@ public HttpResponse process(final HttpRequest httpRequest) throws URISyntaxExcep cookies.save(JAVA_SESSION_NAME, session.getId()); final String cookieInfo = cookies.cookieInfo(JAVA_SESSION_NAME); return HttpResponse.of(version, HttpStatus.FOUND, null, - Map.of(LOCATION_HEADER, INDEX_PAGE, - "Set-Cookie", cookieInfo)); + new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE, + "Set-Cookie", cookieInfo))); } } return HttpResponse.of(version, HttpStatus.FOUND, null, - Map.of(LOCATION_HEADER, UNAUTHORIZED_PAGE)); + new LinkedHashMap<>(Map.of(LOCATION_HEADER, UNAUTHORIZED_PAGE))); } } final String content = SERVER_ERROR_PAGE; return HttpResponse.of(version, HttpStatus.NOT_FOUND, content, - Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length))); + new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), + CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); } private String makeResponseBody(String requestUri) throws URISyntaxException, IOException { diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java b/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java index 3cdd2f7044..90128f0b90 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java +++ b/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java @@ -23,7 +23,7 @@ private RequestLine(HttpMethod httpMethod, RequestUri requestURI, HttpVersion ht public static RequestLine from(final String requestLine) { final String[] params = requestLine.split(" "); final HttpMethod httpMethod = HttpMethod.from(params[METHOD_INDEX]); - final RequestUri uri = RequestUri.from(params[1].substring(URI_INDEX)); + final RequestUri uri = RequestUri.from(params[URI_INDEX].substring(1)); final HttpVersion httpVersion = HttpVersion.from(params[VERSION_INDEX]); return new RequestLine(httpMethod, uri, httpVersion); } diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java b/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java index 4dae00f5e0..67582f2d92 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java +++ b/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java @@ -16,7 +16,7 @@ private RequestUri(final String uri, final Map queryParams) { } public static RequestUri from(final String requestUri) { - if (notExistQueryParametersIn(requestUri)) { + if (existQueryParametersIn(requestUri)) { final int queryParamStartIndex = requestUri.indexOf("?"); final String uri = requestUri.substring(0, queryParamStartIndex); final Map params = parseParams(requestUri.substring(queryParamStartIndex+1)); @@ -25,8 +25,8 @@ public static RequestUri from(final String requestUri) { return new RequestUri(requestUri, Collections.emptyMap()); } - private static boolean notExistQueryParametersIn(final String uri) { - return !uri.contains("?"); + private static boolean existQueryParametersIn(final String uri) { + return uri.contains("?"); } private static Map parseParams(final String params) { diff --git a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java index d1ca0a7810..e21643c224 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java +++ b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java @@ -1,6 +1,6 @@ package nextstep.jwp.response; -import java.util.Map; +import java.util.LinkedHashMap; import nextstep.jwp.common.HttpStatus; import nextstep.jwp.common.HttpVersion; @@ -21,7 +21,7 @@ private HttpResponse(final StatusLine statusLine, final ResponseHeaders response public static HttpResponse of(final HttpVersion httpVersion, final HttpStatus httpStatus, final String responseBody, - final Map headers) { + final LinkedHashMap headers) { final StatusLine statusLine = StatusLine.of(httpVersion, httpStatus); final ResponseHeaders responseHeaders = ResponseHeaders.from(headers); return new HttpResponse(statusLine, responseHeaders, responseBody); diff --git a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java b/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java index 8db3f771e0..e4a0d72ebe 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java +++ b/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java @@ -1,5 +1,6 @@ package nextstep.jwp.response; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -8,13 +9,13 @@ public class ResponseHeaders { private static final String DELIMITER = "\r\n"; - private final Map headers; + private final LinkedHashMap headers; - private ResponseHeaders(final Map headers) { + private ResponseHeaders(final LinkedHashMap headers) { this.headers = headers; } - public static ResponseHeaders from(final Map headers) { + public static ResponseHeaders from(final LinkedHashMap headers) { return new ResponseHeaders(headers); } From 97b8a82dfafde07888908aed95f30999381e5150 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 02:30:23 +0900 Subject: [PATCH 02/13] =?UTF-8?q?refactor:=20HttpResponse=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=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 --- .../nextstep/jwp/response/HttpResponse.java | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java index e21643c224..2d30009074 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java +++ b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java @@ -1,30 +1,41 @@ package nextstep.jwp.response; -import java.util.LinkedHashMap; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.common.HttpVersion; +import nextstep.jwp.model.HttpCookies; public class HttpResponse { private static final String DELIMITER = "\r\n"; - private final StatusLine statusLine; - private final ResponseHeaders responseHeaders; - private final String responseBody; + private final ResponseHeaders responseHeaders = new ResponseHeaders(); + private final HttpCookies cookies = new HttpCookies(); + private StatusLine statusLine; + private String responseBody; - private HttpResponse(final StatusLine statusLine, final ResponseHeaders responseHeaders, - final String responseBody) { + public HttpResponse() { + } + + public void setStatusLine(final StatusLine statusLine) { this.statusLine = statusLine; - this.responseHeaders = responseHeaders; - this.responseBody = responseBody; } - public static HttpResponse of(final HttpVersion httpVersion, final HttpStatus httpStatus, - final String responseBody, - final LinkedHashMap headers) { - final StatusLine statusLine = StatusLine.of(httpVersion, httpStatus); - final ResponseHeaders responseHeaders = ResponseHeaders.from(headers); - return new HttpResponse(statusLine, responseHeaders, responseBody); + public void setResponseBody(final String body) { + this.responseBody = body; + setContentLengthHeader(body); + } + + private void setContentLengthHeader(final String content) { + if (content == null) { + return; + } + responseHeaders.save("Content-Length", String.valueOf(content.getBytes().length)); + } + + public void addHeader(final String name, final String value) { + responseHeaders.save(name, value); + } + + public void addCookie(final String name, final String value) { + cookies.save(name, value); } public String toResponse() { From 730c324496d3f66ca1709075a3e96b44c38bbf91 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 03:15:52 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat:=20=EC=9B=B9=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20Controller?= =?UTF-8?q?=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=83=81=EC=86=8D=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commandcontroller/AbstractController.java | 38 +++++++++++++++ .../jwp/commandcontroller/Controller.java | 10 ++++ .../ErrorPageController.java | 23 +++++++++ .../commandcontroller/LoginController.java | 48 +++++++++++++++++++ .../LoginPageController.java | 35 ++++++++++++++ .../commandcontroller/MainPageController.java | 25 ++++++++++ .../commandcontroller/RegisterController.java | 42 ++++++++++++++++ .../RegisterPageController.java | 26 ++++++++++ .../StaticResourceController.java | 26 ++++++++++ .../{HttpCookie.java => HttpCookies.java} | 18 ++++--- .../nextstep/jwp/request/HttpRequest.java | 10 ++-- .../jwp/response/ResponseHeaders.java | 10 ++-- 12 files changed, 294 insertions(+), 17 deletions(-) create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java create mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java rename tomcat/src/main/java/nextstep/jwp/model/{HttpCookie.java => HttpCookies.java} (64%) diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java new file mode 100644 index 0000000000..c23e223159 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java @@ -0,0 +1,38 @@ +package nextstep.jwp.commandcontroller; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; + +public class AbstractController implements Controller { + + protected static final String DEFAULT_FILE_LOCATION = "static/"; + + @Override + public boolean canHandle(HttpRequest request) { + return false; + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + // http method 분기문 + } + + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } + + protected String readResponseBody(final String requestUri) throws IOException, URISyntaxException { + final URL url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri); + if (url == null) { + URL notFoundUrl = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + "404.html"); + final var path = Paths.get(notFoundUrl.toURI()); + return Files.readString(path); + } + final var path = Paths.get(url.toURI()); + return Files.readString(path); + } +}` diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java new file mode 100644 index 0000000000..50acfeaf36 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java @@ -0,0 +1,10 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; + +public interface Controller { + + boolean canHandle(HttpRequest httpRequest); + void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception; +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java new file mode 100644 index 0000000000..6f080e0b66 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java @@ -0,0 +1,23 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; + +public class ErrorPageController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + return super.canHandle(request); + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.NOT_FOUND)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + final String content = readResponseBody("500.html"); + response.setResponseBody(content); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java new file mode 100644 index 0000000000..7183d70d98 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java @@ -0,0 +1,48 @@ +package nextstep.jwp.commandcontroller; + +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.Session; +import nextstep.jwp.model.User; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; +import org.apache.catalina.SessionManager; + +public class LoginController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.POST) && uri.equals("login"); + } + + @Override + public void service(HttpRequest request, HttpResponse response) { + final Map logInfo = Arrays.stream(request.getRequestBody().split("&")) + .map(input -> input.split("=")) + .collect(Collectors.toMap(info -> info[0], info -> info[1])); + + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); + final Optional savedUser = InMemoryUserRepository.findByAccount(logInfo.get("account")); + if (savedUser.isPresent()) { + final User user = savedUser.get(); + if (user.checkPassword(logInfo.get("password"))) { + response.addHeader("Location", "index.html"); + final Session session = new Session(UUID.randomUUID().toString()); + session.setAttribute("user", user); + SessionManager.add(session); + response.addCookie("JESSIONID", session.getId()); + return; + } + } + response.addHeader("Location", "401.html"); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java new file mode 100644 index 0000000000..6012e79c67 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java @@ -0,0 +1,35 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.model.Session; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; +import org.apache.catalina.SessionManager; + +public class LoginPageController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.GET) && uri.equals("login"); + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + final String sessionId = request.getCookies().ofSessionId("JSESSIONID"); + final Session session = SessionManager.findSession(sessionId); + if (session != null) { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); + response.addHeader("Location", "index.html"); + return; + } + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ".html"); + response.setResponseBody(content); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java new file mode 100644 index 0000000000..696a980bc2 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java @@ -0,0 +1,25 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; + +public class MainPageController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.GET) && uri.isEmpty(); + } + + @Override + public void service(HttpRequest request, HttpResponse response) { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + response.setResponseBody("Hello world!"); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java new file mode 100644 index 0000000000..80d7f04ebc --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java @@ -0,0 +1,42 @@ +package nextstep.jwp.commandcontroller; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.User; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; + +public class RegisterController extends AbstractController{ + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.POST) && uri.equals("register"); + } + + @Override + public void service(HttpRequest request, HttpResponse response) { + final Map registerInfo = Arrays.stream(request.getRequestBody().split("&")) + .map(input -> input.split("=")) + .collect(Collectors.toMap(info -> info[0], info -> info[1])); + + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); + if (InMemoryUserRepository.findByAccount(registerInfo.get("account")).isPresent()) { + response.addHeader("Location", "register.html"); + return; + } + + final User newUser = new User(registerInfo.get("account"), registerInfo.get("password"), + registerInfo.get("email")); + InMemoryUserRepository.save(newUser); + response.addHeader("Location", "index.html"); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java new file mode 100644 index 0000000000..058954e706 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java @@ -0,0 +1,26 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; + +public class RegisterPageController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.GET) && uri.equals("register"); + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ".html"); + response.setResponseBody(content); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java new file mode 100644 index 0000000000..7fca85d075 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java @@ -0,0 +1,26 @@ +package nextstep.jwp.commandcontroller; + +import nextstep.jwp.common.ContentType; +import nextstep.jwp.common.HttpMethod; +import nextstep.jwp.common.HttpStatus; +import nextstep.jwp.request.HttpRequest; +import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.response.StatusLine; + +public class StaticResourceController extends AbstractController { + + @Override + public boolean canHandle(HttpRequest request) { + final HttpMethod method = request.getHttpMethod(); + final String uri = request.getRequestUri(); + return method.equals(HttpMethod.GET) && ContentType.isSupportedType(uri); + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.getTypeByExtension(request.getRequestUri())); + final String content = readResponseBody(request.getRequestUri()); + response.setResponseBody(content); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/model/HttpCookie.java b/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java similarity index 64% rename from tomcat/src/main/java/nextstep/jwp/model/HttpCookie.java rename to tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java index 159ba9ee7f..00c3474467 100644 --- a/tomcat/src/main/java/nextstep/jwp/model/HttpCookie.java +++ b/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java @@ -2,27 +2,31 @@ import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; -public class HttpCookie { +public class HttpCookies { - private final Map cookies; + private final Map cookies = new LinkedHashMap<>(); - private HttpCookie(final Map cookies) { - this.cookies = cookies; + public HttpCookies() { } - public static HttpCookie from(final String cookieHeader) { + public HttpCookies(final Map cookies) { + this.cookies.putAll(cookies); + } + + public static HttpCookies from(final String cookieHeader) { if (cookieHeader == null) { - return new HttpCookie(Collections.emptyMap()); + return new HttpCookies(Collections.emptyMap()); } final Map cookieMap = Arrays.stream(cookieHeader.split(";")) .map(cookie -> cookie.split("=")) .collect(Collectors.toMap(cookie -> cookie[0].trim(), cookie -> cookie[1].trim())); - return new HttpCookie(cookieMap); + return new HttpCookies(cookieMap); } public void save(final String cookie, final String value) { diff --git a/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java b/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java index 6d43df738c..f57ccb1a45 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java +++ b/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java @@ -4,17 +4,17 @@ import java.io.IOException; import nextstep.jwp.common.HttpMethod; import nextstep.jwp.common.HttpVersion; -import nextstep.jwp.model.HttpCookie; +import nextstep.jwp.model.HttpCookies; public class HttpRequest { private final RequestLine requestLine; private final RequestHeaders requestHeaders; - private final HttpCookie cookies; + private final HttpCookies cookies; private final RequestBody requestBody; private HttpRequest(final RequestLine requestLine, final RequestHeaders requestHeaders, - final HttpCookie cookies, final RequestBody requestBody) { + final HttpCookies cookies, final RequestBody requestBody) { this.requestLine = requestLine; this.requestHeaders = requestHeaders; this.cookies = cookies; @@ -24,7 +24,7 @@ private HttpRequest(final RequestLine requestLine, final RequestHeaders requestH public static HttpRequest from(final BufferedReader reader) throws IOException { final RequestLine requestLine = RequestLine.from(reader.readLine()); final RequestHeaders requestHeader = RequestHeaders.from(reader); - final HttpCookie cookies = HttpCookie.from(requestHeader.getHeaderValue("Cookie")); + final HttpCookies cookies = HttpCookies.from(requestHeader.getHeaderValue("Cookie")); final RequestBody requestBody = readRequestBody(reader, requestHeader); return new HttpRequest(requestLine, requestHeader, cookies, requestBody); @@ -55,7 +55,7 @@ public String getHeaderValue(final String header) { return requestHeaders.getHeaderValue(header); } - public HttpCookie getCookies() { + public HttpCookies getCookies() { return cookies; } diff --git a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java b/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java index e4a0d72ebe..0e47a2711a 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java +++ b/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java @@ -9,14 +9,14 @@ public class ResponseHeaders { private static final String DELIMITER = "\r\n"; - private final LinkedHashMap headers; + private final Map headers; - private ResponseHeaders(final LinkedHashMap headers) { - this.headers = headers; + public ResponseHeaders() { + this.headers = new LinkedHashMap<>(); } - public static ResponseHeaders from(final LinkedHashMap headers) { - return new ResponseHeaders(headers); + public void save(final String name, final String value) { + headers.put(name, value); } public Map getHeaders() { From 88595667fd8045f6ee9ea88b629eebe23f63bfb2 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 04:43:59 +0900 Subject: [PATCH 04/13] =?UTF-8?q?feat:=20=EC=98=AC=EB=B0=94=EB=A5=B8=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/RequestMapping.java | 27 +++ .../java/nextstep/jwp/RequestProcessor.java | 161 ------------------ 2 files changed, 27 insertions(+), 161 deletions(-) create mode 100644 tomcat/src/main/java/nextstep/jwp/RequestMapping.java delete mode 100644 tomcat/src/main/java/nextstep/jwp/RequestProcessor.java diff --git a/tomcat/src/main/java/nextstep/jwp/RequestMapping.java b/tomcat/src/main/java/nextstep/jwp/RequestMapping.java new file mode 100644 index 0000000000..f3b2f632b2 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/RequestMapping.java @@ -0,0 +1,27 @@ +package nextstep.jwp; + +import java.util.ArrayList; +import java.util.List; +import nextstep.jwp.commandcontroller.Controller; +import nextstep.jwp.request.HttpRequest; + +public class RequestMapping { + + private final List controllers = new ArrayList<>(); + private Controller defaultController; + + public RequestMapping(final List controllers) { + this.controllers.addAll(controllers); + } + + public void setDefaultController(final Controller controller) { + this.defaultController = controller; + } + + public Controller getController(final HttpRequest request) { + return controllers.stream() + .filter(controller -> controller.canHandle(request)) + .findAny() + .orElse(defaultController); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java b/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java deleted file mode 100644 index 3ac69129fa..0000000000 --- a/tomcat/src/main/java/nextstep/jwp/RequestProcessor.java +++ /dev/null @@ -1,161 +0,0 @@ -package nextstep.jwp; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.common.HttpVersion; -import nextstep.jwp.db.InMemoryUserRepository; -import nextstep.jwp.model.HttpCookie; -import nextstep.jwp.model.Session; -import nextstep.jwp.model.User; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import org.apache.catalina.SessionManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RequestProcessor { - - private static final String CONTENT_TYPE_HEADER = "Content-Type"; - private static final String CONTENT_LENGTH_HEADER = "Content-Length"; - private static final String LOCATION_HEADER = "Location"; - private static final String DEFAULT_FILE_LOCATION = "static/"; - private static final String INDEX_PAGE = "index.html"; - private static final String REGISTER_PAGE = "register.html"; - private static final String UNAUTHORIZED_PAGE = "401.html"; - private static final String SERVER_ERROR_PAGE = "500.html"; - private static final String JAVA_SESSION_NAME = "JSESSIONID"; - - private static final Logger log = LoggerFactory.getLogger(RequestProcessor.class); - - public HttpResponse process(final HttpRequest httpRequest) throws URISyntaxException, IOException { - - final HttpVersion version = httpRequest.getHttpVersion(); - final HttpMethod method = httpRequest.getHttpMethod(); - final String requestUri = httpRequest.getRequestUri(); - final HttpCookie cookies = httpRequest.getCookies(); - - if (method.equals(HttpMethod.GET)) { - if (requestUri.isEmpty()) { - final String content = "Hello world!"; - return HttpResponse.of(version, HttpStatus.OK, content, - new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); - } - - if (requestUri.equals("register")) { - final String content = makeResponseBody(requestUri); - return HttpResponse.of(version, HttpStatus.OK, content, - new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); - } - - if (requestUri.equals("login")) { - final String sessionId = cookies.ofSessionId(JAVA_SESSION_NAME); - final Session session = SessionManager.findSession(sessionId); - if (session != null) { - return HttpResponse.of(version, HttpStatus.FOUND, null, - new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE))); - } - final String content = makeResponseBody(requestUri); - return HttpResponse.of(version, HttpStatus.OK, content, - new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); - } - - if (ContentType.isSupportedType(requestUri)) { - final String content = makeResponseBody(requestUri); - return HttpResponse.of(version, HttpStatus.OK, content, - new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.getTypeByExtension(requestUri), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); - } - } - - if (method.equals(HttpMethod.POST)) { - final String requestBody = httpRequest.getRequestBody(); - - if (requestUri.equals("register")) { - final Map registerInfo = Arrays.stream(requestBody.split("&")) - .map(input -> input.split("=")) - .collect(Collectors.toMap(info -> info[0], info -> info[1])); - - if (InMemoryUserRepository.findByAccount(registerInfo.get("account")).isPresent()) { - return HttpResponse.of(version, HttpStatus.FOUND, null, - new LinkedHashMap<>(Map.of(LOCATION_HEADER, REGISTER_PAGE))); - } - - final User newUser = new User(registerInfo.get("account"), registerInfo.get("password"), - registerInfo.get("email")); - InMemoryUserRepository.save(newUser); - return HttpResponse.of(version, HttpStatus.FOUND, null, - new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE))); - } - - if (requestUri.equals("login")) { - final Map logInfo = Arrays.stream(requestBody.split("&")) - .map(input -> input.split("=")) - .collect(Collectors.toMap(info -> info[0], info -> info[1])); - - final Optional findedUser = InMemoryUserRepository.findByAccount(logInfo.get("account")); - if (findedUser.isPresent()) { - User user = findedUser.get(); - if (user.checkPassword(logInfo.get("password"))) { - log.info(user.toString()); - final Session session = new Session(UUID.randomUUID().toString()); - session.setAttribute("user", user); - SessionManager.add(session); - cookies.save(JAVA_SESSION_NAME, session.getId()); - final String cookieInfo = cookies.cookieInfo(JAVA_SESSION_NAME); - return HttpResponse.of(version, HttpStatus.FOUND, null, - new LinkedHashMap<>(Map.of(LOCATION_HEADER, INDEX_PAGE, - "Set-Cookie", cookieInfo))); - } - } - - return HttpResponse.of(version, HttpStatus.FOUND, null, - new LinkedHashMap<>(Map.of(LOCATION_HEADER, UNAUTHORIZED_PAGE))); - } - } - - final String content = SERVER_ERROR_PAGE; - return HttpResponse.of(version, HttpStatus.NOT_FOUND, content, - new LinkedHashMap<>(Map.of(CONTENT_TYPE_HEADER, ContentType.HTML.getType(), - CONTENT_LENGTH_HEADER, String.valueOf(content.getBytes().length)))); - } - - private String makeResponseBody(String requestUri) throws URISyntaxException, IOException { - final URL url; - - if (requestUri.equals("login")) { - url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri + ".html"); - final var path = Paths.get(url.toURI()); - return Files.readString(path); - } - - if (requestUri.equals("register")) { - url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri + ".html"); - final var path = Paths.get(url.toURI()); - return Files.readString(path); - } - - url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri); - if (url == null) { - URL notFoundUrl = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + "404.html"); - final var path = Paths.get(notFoundUrl.toURI()); - return Files.readString(path); - } - final var path = Paths.get(url.toURI()); - return Files.readString(path); - } -} \ No newline at end of file From c70952c355bc2aac53aba69efb2f8cb242680098 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 04:44:57 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor:=20=EC=9B=B9=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=ED=8F=AC=EB=A7=A4=ED=8C=85=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commandcontroller/AbstractController.java | 5 +-- .../commandcontroller/LoginController.java | 2 +- .../java/nextstep/jwp/model/HttpCookies.java | 15 +++++++- .../nextstep/jwp/response/HttpResponse.java | 4 +- .../apache/coyote/http11/Http11Processor.java | 38 ++++++++++++++----- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java index c23e223159..16e92ca681 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java @@ -22,9 +22,6 @@ public void service(HttpRequest request, HttpResponse response) throws Exception // http method 분기문 } - protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } - protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } - protected String readResponseBody(final String requestUri) throws IOException, URISyntaxException { final URL url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri); if (url == null) { @@ -35,4 +32,4 @@ protected String readResponseBody(final String requestUri) throws IOException, U final var path = Paths.get(url.toURI()); return Files.readString(path); } -}` +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java index 7183d70d98..1496a8395c 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java @@ -39,7 +39,7 @@ public void service(HttpRequest request, HttpResponse response) { final Session session = new Session(UUID.randomUUID().toString()); session.setAttribute("user", user); SessionManager.add(session); - response.addCookie("JESSIONID", session.getId()); + response.addCookie("JSESSIONID", session.getId()); return; } } diff --git a/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java b/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java index 00c3474467..71ad5aae9f 100644 --- a/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java +++ b/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java @@ -3,11 +3,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class HttpCookies { + private static final String DELIMITER = "\r\n"; private final Map cookies = new LinkedHashMap<>(); public HttpCookies() { @@ -37,7 +39,16 @@ public String ofSessionId(final String sessionId) { return cookies.get(sessionId); } - public String cookieInfo(final String sessionId) { - return sessionId + "=" + cookies.get(sessionId); + public String toResponse() { + if (cookies.isEmpty()) { + return ""; + } + + final List cookieString = cookies.keySet() + .stream() + .map(name -> "Set-Cookie: " + name + "=" + cookies.get(name) + " ") + .collect(Collectors.toList()); + + return String.join(DELIMITER, cookieString) + DELIMITER; } } diff --git a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java index 2d30009074..f12dfdaef2 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java +++ b/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java @@ -9,7 +9,7 @@ public class HttpResponse { private final ResponseHeaders responseHeaders = new ResponseHeaders(); private final HttpCookies cookies = new HttpCookies(); private StatusLine statusLine; - private String responseBody; + private String responseBody = ""; public HttpResponse() { } @@ -41,7 +41,7 @@ public void addCookie(final String name, final String value) { public String toResponse() { return String.join(DELIMITER, statusLine.toResponse(), - responseHeaders.toResponse(), + cookies.toResponse() + responseHeaders.toResponse(), "", responseBody); } 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 10e7ec390e..dcc8aa0acb 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,12 +1,18 @@ package org.apache.coyote.http11; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; -import java.net.URISyntaxException; -import nextstep.jwp.RequestProcessor; -import nextstep.jwp.exception.UncheckedServletException; +import java.util.List; +import nextstep.jwp.RequestMapping; +import nextstep.jwp.commandcontroller.Controller; +import nextstep.jwp.commandcontroller.ErrorPageController; +import nextstep.jwp.commandcontroller.LoginController; +import nextstep.jwp.commandcontroller.LoginPageController; +import nextstep.jwp.commandcontroller.MainPageController; +import nextstep.jwp.commandcontroller.RegisterController; +import nextstep.jwp.commandcontroller.RegisterPageController; +import nextstep.jwp.commandcontroller.StaticResourceController; import nextstep.jwp.request.HttpRequest; import nextstep.jwp.response.HttpResponse; import org.apache.coyote.Processor; @@ -17,9 +23,11 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); + private final RequestMapping requestMapping; private final Socket connection; public Http11Processor(final Socket connection) { + this.requestMapping = registerControllers(); this.connection = connection; } @@ -33,15 +41,27 @@ public void run() { public void process(final Socket connection) { try (final var bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); final var outputStream = connection.getOutputStream()) { - final HttpRequest httpRequest = HttpRequest.from(bufferedReader); - final RequestProcessor requestProcessor = new RequestProcessor(); - final HttpResponse httpResponse = requestProcessor.process(httpRequest); - + final HttpResponse httpResponse = new HttpResponse(); + final Controller controller = requestMapping.getController(httpRequest); + controller.service(httpRequest, httpResponse); outputStream.write(httpResponse.toResponse().getBytes()); outputStream.flush(); - } catch (IOException | UncheckedServletException | URISyntaxException e) { + } catch (Exception e) { log.error(e.getMessage(), e); } } + + private RequestMapping registerControllers() { + final RequestMapping mapper = new RequestMapping(List.of( + new LoginController(), + new LoginPageController(), + new RegisterController(), + new RegisterPageController(), + new MainPageController(), + new StaticResourceController() + )); + mapper.setDefaultController(new ErrorPageController()); + return mapper; + } } From 24e135e1853974488f3452faa4ad258b5002f7af Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 15:33:25 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20ThreadPool=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/catalina/connector/Connector.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java index 3b2c4dda7c..2b7d343f40 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -1,5 +1,7 @@ package org.apache.catalina.connector; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.apache.coyote.http11.Http11Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,17 +17,20 @@ public class Connector implements Runnable { private static final int DEFAULT_PORT = 8080; private static final int DEFAULT_ACCEPT_COUNT = 100; + private static final int DEFAULT_MAX_THREADS = 250; private final ServerSocket serverSocket; + private final ExecutorService executorService; private boolean stopped; public Connector() { - this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT, DEFAULT_MAX_THREADS); } - public Connector(final int port, final int acceptCount) { + public Connector(final int port, final int acceptCount, final int maxThreads) { this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; + this.executorService = Executors.newFixedThreadPool(maxThreads); } private ServerSocket createServerSocket(final int port, final int acceptCount) { @@ -39,9 +44,7 @@ private ServerSocket createServerSocket(final int port, final int acceptCount) { } public void start() { - var thread = new Thread(this); - thread.setDaemon(true); - thread.start(); + executorService.execute(this); stopped = false; log.info("Web Application Server started {} port.", serverSocket.getLocalPort()); } @@ -67,7 +70,7 @@ private void process(final Socket connection) { return; } var processor = new Http11Processor(connection); - new Thread(processor).start(); + executorService.execute(processor); } public void stop() { From 62644dd823d15e81320fbfbe96273c78dc84a6b3 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Mon, 11 Sep 2023 15:34:20 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20SessionManager=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EC=8A=A4=EB=A0=88=EB=93=9C=20=EC=95=88=EC=A0=95=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20ConcurrentHashMap=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tomcat/src/main/java/org/apache/catalina/SessionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tomcat/src/main/java/org/apache/catalina/SessionManager.java b/tomcat/src/main/java/org/apache/catalina/SessionManager.java index 384b4c56a1..d5215d8f91 100644 --- a/tomcat/src/main/java/org/apache/catalina/SessionManager.java +++ b/tomcat/src/main/java/org/apache/catalina/SessionManager.java @@ -1,12 +1,12 @@ package org.apache.catalina; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import nextstep.jwp.model.Session; public class SessionManager { - private static final Map sessions = new HashMap<>(); + private static final Map sessions = new ConcurrentHashMap<>(); private SessionManager() { } From ec51e20e79bed9467d4041631533f665e4c70333 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Wed, 13 Sep 2023 14:15:32 +0900 Subject: [PATCH 08/13] =?UTF-8?q?teat:=20=20=EC=BA=90=EC=8B=9C=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/cachecontrol/CacheWebConfig.java | 3 +++ .../com/example/etag/EtagFilterConfiguration.java | 15 +++++++++++---- .../example/interceptor/NocacheInterceptor.java | 15 +++++++++++++++ .../example/version/CacheBustingWebConfig.java | 5 ++++- study/src/main/resources/application.yml | 3 +++ 5 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 study/src/main/java/cache/com/example/interceptor/NocacheInterceptor.java 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..47a86fd687 100644 --- a/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java +++ b/study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java @@ -1,5 +1,6 @@ package cache.com.example.cachecontrol; +import cache.com.example.interceptor.NocacheInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -9,5 +10,7 @@ public class CacheWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(new NocacheInterceptor()) + .addPathPatterns("/"); } } 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..439a254dc1 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() { + FilterRegistrationBean filterRegistrationBean + = new FilterRegistrationBean<>( new ShallowEtagHeaderFilter()); + filterRegistrationBean.addUrlPatterns("/etag", "/resources/*"); + filterRegistrationBean.setName("etagFilter"); + return filterRegistrationBean; + } } diff --git a/study/src/main/java/cache/com/example/interceptor/NocacheInterceptor.java b/study/src/main/java/cache/com/example/interceptor/NocacheInterceptor.java new file mode 100644 index 0000000000..0636ef10e8 --- /dev/null +++ b/study/src/main/java/cache/com/example/interceptor/NocacheInterceptor.java @@ -0,0 +1,15 @@ +package cache.com.example.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +public class NocacheInterceptor implements HandlerInterceptor { + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + response.addHeader("Cache-Control", "no-cache, private"); + } +} 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..c7addcdab4 100644 --- a/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java +++ b/study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java @@ -1,7 +1,9 @@ package cache.com.example.version; +import java.time.Duration; 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; @@ -20,6 +22,7 @@ public CacheBustingWebConfig(ResourceVersion version) { @Override public void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**") - .addResourceLocations("classpath:/static/"); + .addResourceLocations("classpath:/static/") + .setCacheControl(CacheControl.maxAge(Duration.ofDays(365)).cachePublic()); } } diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 4e8655a962..7afeb4b2aa 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -7,3 +7,6 @@ server: max-connections: 1 threads: max: 2 + compression: + enabled: true + min-response-size: 10 \ No newline at end of file From 6114aa7e24212d2afef25854e1ae5829d1db5c9b Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Thu, 14 Sep 2023 19:13:08 +0900 Subject: [PATCH 09/13] =?UTF-8?q?teat:=20=EC=8A=A4=EB=A0=88=EB=93=9C=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/main/resources/application.yml | 6 +++--- .../thread/stage0/SynchronizationTest.java | 2 +- .../java/thread/stage0/ThreadPoolsTest.java | 6 +++--- .../java/thread/stage1/ConcurrencyTest.java | 18 +++++++----------- .../test/java/thread/stage2/TestHttpUtils.java | 2 +- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 7afeb4b2aa..6a10bfed7a 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -3,10 +3,10 @@ handlebars: server: tomcat: - accept-count: 1 - max-connections: 1 + accept-count: 0 + max-connections: 4 threads: - max: 2 + max: 4 compression: enabled: true min-response-size: 10 \ No newline at end of file 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()); diff --git a/study/src/test/java/thread/stage1/ConcurrencyTest.java b/study/src/test/java/thread/stage1/ConcurrencyTest.java index f5e8ee070a..c118e38ef7 100644 --- a/study/src/test/java/thread/stage1/ConcurrencyTest.java +++ b/study/src/test/java/thread/stage1/ConcurrencyTest.java @@ -1,19 +1,15 @@ package thread.stage1; -import org.junit.jupiter.api.Test; - import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; + /** - * 스레드를 다룰 때 어떤 상황을 조심해야 할까? - * - 상태를 가진 한 객체를 여러 스레드에서 동시에 접근할 경우 - * - static 변수를 가진 객체를 여러 스레드에서 동시에 접근할 경우 - * - * 위 경우는 동기화(synchronization)를 적용시키거나 객체가 상태를 갖지 않도록 한다. - * 객체를 불변 객체로 만드는 방법도 있다. - * - * 웹서버는 여러 사용자가 동시에 접속을 시도하기 때문에 동시성 이슈가 생길 수 있다. - * 어떤 사례가 있는지 아래 테스트 코드를 통해 알아보자. + * 스레드를 다룰 때 어떤 상황을 조심해야 할까? - 상태를 가진 한 객체를 여러 스레드에서 동시에 접근할 경우 - static 변수를 가진 객체를 여러 스레드에서 동시에 접근할 경우 + *

+ * 위 경우는 동기화(synchronization)를 적용시키거나 객체가 상태를 갖지 않도록 한다. 객체를 불변 객체로 만드는 방법도 있다. + *

+ * 웹서버는 여러 사용자가 동시에 접속을 시도하기 때문에 동시성 이슈가 생길 수 있다. 어떤 사례가 있는지 아래 테스트 코드를 통해 알아보자. */ class ConcurrencyTest { diff --git a/study/src/test/java/thread/stage2/TestHttpUtils.java b/study/src/test/java/thread/stage2/TestHttpUtils.java index ca37f2f8bb..3dd42521b7 100644 --- a/study/src/test/java/thread/stage2/TestHttpUtils.java +++ b/study/src/test/java/thread/stage2/TestHttpUtils.java @@ -11,7 +11,7 @@ public class TestHttpUtils { private static final HttpClient httpClient = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) - .connectTimeout(Duration.ofSeconds(1)) + .connectTimeout(Duration.ofSeconds((1))) .build(); public static HttpResponse send(final String path) { From e5e84162b1b8cb7c849f3865d14525b5c6075f56 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Thu, 14 Sep 2023 19:16:06 +0900 Subject: [PATCH 10/13] =?UTF-8?q?refactor:=20jwp=EC=99=80=20tomcat=20?= =?UTF-8?q?=EA=B0=84=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/RequestMapping.java | 27 ----------- .../jwp/commandcontroller/Controller.java | 10 ---- .../AbstractController.java | 14 +++--- .../ErrorPageController.java | 14 +++--- .../LoginController.java | 16 +++---- .../LoginPageController.java | 18 +++---- .../MainPageController.java | 14 +++--- .../RegisterController.java | 14 +++--- .../RegisterPageController.java | 14 +++--- .../jwp/controller/RequestMapping.java | 47 +++++++++++++++++++ .../StaticResourceController.java | 14 +++--- .../java/org/apache/catalina/Controller.java | 9 ++++ .../apache/coyote}/common/ContentType.java | 5 +- .../apache/coyote/common}/HttpCookies.java | 2 +- .../apache/coyote}/common/HttpMethod.java | 4 +- .../apache/coyote}/common/HttpStatus.java | 2 +- .../apache/coyote}/common/HttpVersion.java | 5 +- .../apache/coyote/common}/Session.java | 2 +- .../common}/SessionManager.java | 3 +- .../exception/InvalidHttpMethodException.java | 2 +- .../InvalidHttpVersionException.java | 2 +- .../InvalidQueryStringException.java | 2 +- .../UnSupportedContentTypeException.java | 2 +- .../apache/coyote/http11/Http11Processor.java | 35 +++----------- .../apache/coyote}/request/HttpRequest.java | 8 ++-- .../apache/coyote}/request/RequestBody.java | 2 +- .../coyote}/request/RequestHeaders.java | 2 +- .../apache/coyote}/request/RequestLine.java | 6 +-- .../apache/coyote}/request/RequestUri.java | 4 +- .../apache/coyote}/response/HttpResponse.java | 7 +-- .../coyote}/response/ResponseHeaders.java | 2 +- .../apache/coyote}/response/StatusLine.java | 6 +-- 32 files changed, 152 insertions(+), 162 deletions(-) delete mode 100644 tomcat/src/main/java/nextstep/jwp/RequestMapping.java delete mode 100644 tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/AbstractController.java (76%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/ErrorPageController.java (64%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/LoginController.java (81%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/LoginPageController.java (73%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/MainPageController.java (66%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/RegisterController.java (80%) rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/RegisterPageController.java (70%) create mode 100644 tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java rename tomcat/src/main/java/nextstep/jwp/{commandcontroller => controller}/StaticResourceController.java (71%) create mode 100644 tomcat/src/main/java/org/apache/catalina/Controller.java rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/common/ContentType.java (85%) rename tomcat/src/main/java/{nextstep/jwp/model => org/apache/coyote/common}/HttpCookies.java (97%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/common/HttpMethod.java (77%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/common/HttpStatus.java (89%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/common/HttpVersion.java (74%) rename tomcat/src/main/java/{nextstep/jwp/model => org/apache/coyote/common}/Session.java (94%) rename tomcat/src/main/java/org/apache/{catalina => coyote/common}/SessionManager.java (90%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/exception/InvalidHttpMethodException.java (82%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/exception/InvalidHttpVersionException.java (83%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/exception/InvalidQueryStringException.java (84%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/exception/UnSupportedContentTypeException.java (83%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/request/HttpRequest.java (92%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/request/RequestBody.java (94%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/request/RequestHeaders.java (96%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/request/RequestLine.java (91%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/request/RequestUri.java (93%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/response/HttpResponse.java (92%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/response/ResponseHeaders.java (95%) rename tomcat/src/main/java/{nextstep/jwp => org/apache/coyote}/response/StatusLine.java (86%) diff --git a/tomcat/src/main/java/nextstep/jwp/RequestMapping.java b/tomcat/src/main/java/nextstep/jwp/RequestMapping.java deleted file mode 100644 index f3b2f632b2..0000000000 --- a/tomcat/src/main/java/nextstep/jwp/RequestMapping.java +++ /dev/null @@ -1,27 +0,0 @@ -package nextstep.jwp; - -import java.util.ArrayList; -import java.util.List; -import nextstep.jwp.commandcontroller.Controller; -import nextstep.jwp.request.HttpRequest; - -public class RequestMapping { - - private final List controllers = new ArrayList<>(); - private Controller defaultController; - - public RequestMapping(final List controllers) { - this.controllers.addAll(controllers); - } - - public void setDefaultController(final Controller controller) { - this.defaultController = controller; - } - - public Controller getController(final HttpRequest request) { - return controllers.stream() - .filter(controller -> controller.canHandle(request)) - .findAny() - .orElse(defaultController); - } -} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java b/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java deleted file mode 100644 index 50acfeaf36..0000000000 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/Controller.java +++ /dev/null @@ -1,10 +0,0 @@ -package nextstep.jwp.commandcontroller; - -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; - -public interface Controller { - - boolean canHandle(HttpRequest httpRequest); - void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception; -} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java similarity index 76% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java rename to tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java index 16e92ca681..7921a8d4ac 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -1,21 +1,19 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; +import org.apache.catalina.Controller; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; -public class AbstractController implements Controller { +abstract class AbstractController implements Controller { protected static final String DEFAULT_FILE_LOCATION = "static/"; - @Override - public boolean canHandle(HttpRequest request) { - return false; - } + public abstract boolean canHandle(HttpRequest request); @Override public void service(HttpRequest request, HttpResponse response) throws Exception { diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java similarity index 64% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java rename to tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java index 6f080e0b66..51de178a52 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/ErrorPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java @@ -1,16 +1,16 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; public class ErrorPageController extends AbstractController { @Override public boolean canHandle(HttpRequest request) { - return super.canHandle(request); + return false; } @Override diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java similarity index 81% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java rename to tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 1496a8395c..76dda1a193 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -1,19 +1,19 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; import java.util.Arrays; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; import nextstep.jwp.db.InMemoryUserRepository; -import nextstep.jwp.model.Session; +import org.apache.coyote.common.Session; import nextstep.jwp.model.User; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; -import org.apache.catalina.SessionManager; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; +import org.apache.coyote.common.SessionManager; public class LoginController extends AbstractController { diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java similarity index 73% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java rename to tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java index 6012e79c67..4ba8cf1d7f 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/LoginPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java @@ -1,13 +1,13 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.model.Session; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; -import org.apache.catalina.SessionManager; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.common.Session; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; +import org.apache.coyote.common.SessionManager; public class LoginPageController extends AbstractController { diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java similarity index 66% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java rename to tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java index 696a980bc2..bb5f0768c6 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/MainPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java @@ -1,11 +1,11 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; public class MainPageController extends AbstractController { diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java similarity index 80% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java rename to tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index 80d7f04ebc..a20dace487 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -1,17 +1,15 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; public class RegisterController extends AbstractController{ diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java similarity index 70% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java rename to tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java index 058954e706..e48f92ae8a 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/RegisterPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java @@ -1,11 +1,11 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; public class RegisterPageController extends AbstractController { diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java b/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java new file mode 100644 index 0000000000..274bd7b93c --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java @@ -0,0 +1,47 @@ +package nextstep.jwp.controller; + +import java.util.ArrayList; +import java.util.List; +import nextstep.jwp.exception.UncheckedServletException; +import org.apache.catalina.Controller; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public class RequestMapping implements Controller { + + private final List controllers = new ArrayList<>(); + private AbstractController defaultController; + + public RequestMapping(final List controllers, final AbstractController defaultController) { + this.controllers.addAll(controllers); + this.defaultController = defaultController; + } + + // jwp에서 requestMapping에 미리 controller들을 등록한 상황이라고 가정 + public static Controller getDefault() { + return new RequestMapping(List.of( + new LoginController(), + new LoginPageController(), + new RegisterController(), + new RegisterPageController(), + new MainPageController(), + new StaticResourceController() + ), new ErrorPageController()); + } + + public Controller getController(final HttpRequest request) { + return controllers.stream() + .filter(controller -> controller.canHandle(request)) + .findAny() + .orElse(defaultController); + } + + @Override + public void service(final HttpRequest httpRequest, final HttpResponse httpResponse) { + try { + getController(httpRequest).service(httpRequest, httpResponse); + } catch (Exception e) { + throw new UncheckedServletException(e); + } + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java similarity index 71% rename from tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java rename to tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java index 7fca85d075..2c95d04038 100644 --- a/tomcat/src/main/java/nextstep/jwp/commandcontroller/StaticResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java @@ -1,11 +1,11 @@ -package nextstep.jwp.commandcontroller; +package nextstep.jwp.controller; -import nextstep.jwp.common.ContentType; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; -import nextstep.jwp.response.StatusLine; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; +import org.apache.coyote.response.StatusLine; public class StaticResourceController extends AbstractController { diff --git a/tomcat/src/main/java/org/apache/catalina/Controller.java b/tomcat/src/main/java/org/apache/catalina/Controller.java new file mode 100644 index 0000000000..66fcd1705b --- /dev/null +++ b/tomcat/src/main/java/org/apache/catalina/Controller.java @@ -0,0 +1,9 @@ +package org.apache.catalina; + +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public interface Controller { + + void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception; +} diff --git a/tomcat/src/main/java/nextstep/jwp/common/ContentType.java b/tomcat/src/main/java/org/apache/coyote/common/ContentType.java similarity index 85% rename from tomcat/src/main/java/nextstep/jwp/common/ContentType.java rename to tomcat/src/main/java/org/apache/coyote/common/ContentType.java index a708c4039f..c40cc0b1ef 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/ContentType.java +++ b/tomcat/src/main/java/org/apache/coyote/common/ContentType.java @@ -1,6 +1,7 @@ -package nextstep.jwp.common; +package org.apache.coyote.common; import java.util.Arrays; +import org.apache.coyote.exception.UnSupportedContentTypeException; public enum ContentType { HTML("text/html;charset=utf-8", ".html"), @@ -33,7 +34,7 @@ public static String getTypeByExtension(final String uri) { return Arrays.stream(ContentType.values()) .filter(type -> uri.endsWith(type.getExtension())) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("")) + .orElseThrow(UnSupportedContentTypeException::new) .getType(); } } diff --git a/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java b/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java similarity index 97% rename from tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java rename to tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java index 71ad5aae9f..5cf09c3796 100644 --- a/tomcat/src/main/java/nextstep/jwp/model/HttpCookies.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java @@ -1,4 +1,4 @@ -package nextstep.jwp.model; +package org.apache.coyote.common; import java.util.Arrays; import java.util.Collections; diff --git a/tomcat/src/main/java/nextstep/jwp/common/HttpMethod.java b/tomcat/src/main/java/org/apache/coyote/common/HttpMethod.java similarity index 77% rename from tomcat/src/main/java/nextstep/jwp/common/HttpMethod.java rename to tomcat/src/main/java/org/apache/coyote/common/HttpMethod.java index a60b7d3ae9..2389736f8f 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/HttpMethod.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpMethod.java @@ -1,7 +1,7 @@ -package nextstep.jwp.common; +package org.apache.coyote.common; import java.util.Arrays; -import nextstep.jwp.exception.InvalidHttpMethodException; +import org.apache.coyote.exception.InvalidHttpMethodException; public enum HttpMethod { GET, diff --git a/tomcat/src/main/java/nextstep/jwp/common/HttpStatus.java b/tomcat/src/main/java/org/apache/coyote/common/HttpStatus.java similarity index 89% rename from tomcat/src/main/java/nextstep/jwp/common/HttpStatus.java rename to tomcat/src/main/java/org/apache/coyote/common/HttpStatus.java index 4915f62c3b..e0e0cb85ee 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/HttpStatus.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpStatus.java @@ -1,4 +1,4 @@ -package nextstep.jwp.common; +package org.apache.coyote.common; public enum HttpStatus { OK(200), diff --git a/tomcat/src/main/java/nextstep/jwp/common/HttpVersion.java b/tomcat/src/main/java/org/apache/coyote/common/HttpVersion.java similarity index 74% rename from tomcat/src/main/java/nextstep/jwp/common/HttpVersion.java rename to tomcat/src/main/java/org/apache/coyote/common/HttpVersion.java index 61d0a6f4e6..05822feb33 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/HttpVersion.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpVersion.java @@ -1,6 +1,7 @@ -package nextstep.jwp.common; +package org.apache.coyote.common; import java.util.Arrays; +import org.apache.coyote.exception.InvalidHttpVersionException; public enum HttpVersion { HTTP_1_1("HTTP/1.1"); @@ -15,7 +16,7 @@ public static HttpVersion from(final String version) { return Arrays.stream(values()) .filter(httpVersion -> httpVersion.version.equals(version)) .findFirst() - .orElseThrow(); + .orElseThrow(InvalidHttpVersionException::new); } public String getVersion() { diff --git a/tomcat/src/main/java/nextstep/jwp/model/Session.java b/tomcat/src/main/java/org/apache/coyote/common/Session.java similarity index 94% rename from tomcat/src/main/java/nextstep/jwp/model/Session.java rename to tomcat/src/main/java/org/apache/coyote/common/Session.java index 41d442852a..d41f4d5da1 100644 --- a/tomcat/src/main/java/nextstep/jwp/model/Session.java +++ b/tomcat/src/main/java/org/apache/coyote/common/Session.java @@ -1,4 +1,4 @@ -package nextstep.jwp.model; +package org.apache.coyote.common; import java.util.HashMap; import java.util.Map; diff --git a/tomcat/src/main/java/org/apache/catalina/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/common/SessionManager.java similarity index 90% rename from tomcat/src/main/java/org/apache/catalina/SessionManager.java rename to tomcat/src/main/java/org/apache/coyote/common/SessionManager.java index d5215d8f91..cf6b12d9af 100644 --- a/tomcat/src/main/java/org/apache/catalina/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/common/SessionManager.java @@ -1,8 +1,7 @@ -package org.apache.catalina; +package org.apache.coyote.common; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import nextstep.jwp.model.Session; public class SessionManager { diff --git a/tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpMethodException.java b/tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpMethodException.java similarity index 82% rename from tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpMethodException.java rename to tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpMethodException.java index c13b83b54b..b7ee146256 100644 --- a/tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpMethodException.java +++ b/tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpMethodException.java @@ -1,4 +1,4 @@ -package nextstep.jwp.exception; +package org.apache.coyote.exception; public class InvalidHttpMethodException extends RuntimeException { diff --git a/tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpVersionException.java b/tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpVersionException.java similarity index 83% rename from tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpVersionException.java rename to tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpVersionException.java index a9983bf9ce..14c29d2531 100644 --- a/tomcat/src/main/java/nextstep/jwp/exception/InvalidHttpVersionException.java +++ b/tomcat/src/main/java/org/apache/coyote/exception/InvalidHttpVersionException.java @@ -1,4 +1,4 @@ -package nextstep.jwp.exception; +package org.apache.coyote.exception; public class InvalidHttpVersionException extends RuntimeException { diff --git a/tomcat/src/main/java/nextstep/jwp/exception/InvalidQueryStringException.java b/tomcat/src/main/java/org/apache/coyote/exception/InvalidQueryStringException.java similarity index 84% rename from tomcat/src/main/java/nextstep/jwp/exception/InvalidQueryStringException.java rename to tomcat/src/main/java/org/apache/coyote/exception/InvalidQueryStringException.java index af6623eabe..b99b927648 100644 --- a/tomcat/src/main/java/nextstep/jwp/exception/InvalidQueryStringException.java +++ b/tomcat/src/main/java/org/apache/coyote/exception/InvalidQueryStringException.java @@ -1,4 +1,4 @@ -package nextstep.jwp.exception; +package org.apache.coyote.exception; public class InvalidQueryStringException extends RuntimeException { diff --git a/tomcat/src/main/java/nextstep/jwp/exception/UnSupportedContentTypeException.java b/tomcat/src/main/java/org/apache/coyote/exception/UnSupportedContentTypeException.java similarity index 83% rename from tomcat/src/main/java/nextstep/jwp/exception/UnSupportedContentTypeException.java rename to tomcat/src/main/java/org/apache/coyote/exception/UnSupportedContentTypeException.java index 05df39f8c4..5d338647e0 100644 --- a/tomcat/src/main/java/nextstep/jwp/exception/UnSupportedContentTypeException.java +++ b/tomcat/src/main/java/org/apache/coyote/exception/UnSupportedContentTypeException.java @@ -1,4 +1,4 @@ -package nextstep.jwp.exception; +package org.apache.coyote.exception; public class UnSupportedContentTypeException extends RuntimeException { 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 dcc8aa0acb..e86a9d990e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -3,19 +3,11 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.Socket; -import java.util.List; -import nextstep.jwp.RequestMapping; -import nextstep.jwp.commandcontroller.Controller; -import nextstep.jwp.commandcontroller.ErrorPageController; -import nextstep.jwp.commandcontroller.LoginController; -import nextstep.jwp.commandcontroller.LoginPageController; -import nextstep.jwp.commandcontroller.MainPageController; -import nextstep.jwp.commandcontroller.RegisterController; -import nextstep.jwp.commandcontroller.RegisterPageController; -import nextstep.jwp.commandcontroller.StaticResourceController; -import nextstep.jwp.request.HttpRequest; -import nextstep.jwp.response.HttpResponse; +import nextstep.jwp.controller.RequestMapping; +import org.apache.catalina.Controller; import org.apache.coyote.Processor; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,11 +15,10 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); - private final RequestMapping requestMapping; + private final Controller requestMapping = RequestMapping.getDefault(); private final Socket connection; public Http11Processor(final Socket connection) { - this.requestMapping = registerControllers(); this.connection = connection; } @@ -43,25 +34,11 @@ public void process(final Socket connection) { final var outputStream = connection.getOutputStream()) { final HttpRequest httpRequest = HttpRequest.from(bufferedReader); final HttpResponse httpResponse = new HttpResponse(); - final Controller controller = requestMapping.getController(httpRequest); - controller.service(httpRequest, httpResponse); + requestMapping.service(httpRequest, httpResponse); outputStream.write(httpResponse.toResponse().getBytes()); outputStream.flush(); } catch (Exception e) { log.error(e.getMessage(), e); } } - - private RequestMapping registerControllers() { - final RequestMapping mapper = new RequestMapping(List.of( - new LoginController(), - new LoginPageController(), - new RegisterController(), - new RegisterPageController(), - new MainPageController(), - new StaticResourceController() - )); - mapper.setDefaultController(new ErrorPageController()); - return mapper; - } } diff --git a/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/request/HttpRequest.java similarity index 92% rename from tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java rename to tomcat/src/main/java/org/apache/coyote/request/HttpRequest.java index f57ccb1a45..0ebafa5459 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/request/HttpRequest.java @@ -1,10 +1,10 @@ -package nextstep.jwp.request; +package org.apache.coyote.request; import java.io.BufferedReader; import java.io.IOException; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpVersion; -import nextstep.jwp.model.HttpCookies; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpVersion; +import org.apache.coyote.common.HttpCookies; public class HttpRequest { diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestBody.java b/tomcat/src/main/java/org/apache/coyote/request/RequestBody.java similarity index 94% rename from tomcat/src/main/java/nextstep/jwp/request/RequestBody.java rename to tomcat/src/main/java/org/apache/coyote/request/RequestBody.java index 0bfef63cce..55e9930dd5 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestBody.java +++ b/tomcat/src/main/java/org/apache/coyote/request/RequestBody.java @@ -1,4 +1,4 @@ -package nextstep.jwp.request; +package org.apache.coyote.request; import java.io.BufferedReader; import java.io.IOException; diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestHeaders.java b/tomcat/src/main/java/org/apache/coyote/request/RequestHeaders.java similarity index 96% rename from tomcat/src/main/java/nextstep/jwp/request/RequestHeaders.java rename to tomcat/src/main/java/org/apache/coyote/request/RequestHeaders.java index a282f35a2a..9ad7814052 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestHeaders.java +++ b/tomcat/src/main/java/org/apache/coyote/request/RequestHeaders.java @@ -1,4 +1,4 @@ -package nextstep.jwp.request; +package org.apache.coyote.request; import java.io.BufferedReader; import java.io.IOException; diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java b/tomcat/src/main/java/org/apache/coyote/request/RequestLine.java similarity index 91% rename from tomcat/src/main/java/nextstep/jwp/request/RequestLine.java rename to tomcat/src/main/java/org/apache/coyote/request/RequestLine.java index 90128f0b90..eb3bf749cc 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestLine.java +++ b/tomcat/src/main/java/org/apache/coyote/request/RequestLine.java @@ -1,8 +1,8 @@ -package nextstep.jwp.request; +package org.apache.coyote.request; import java.util.Map; -import nextstep.jwp.common.HttpMethod; -import nextstep.jwp.common.HttpVersion; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpVersion; public class RequestLine { diff --git a/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java b/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java similarity index 93% rename from tomcat/src/main/java/nextstep/jwp/request/RequestUri.java rename to tomcat/src/main/java/org/apache/coyote/request/RequestUri.java index 67582f2d92..fc518be509 100644 --- a/tomcat/src/main/java/nextstep/jwp/request/RequestUri.java +++ b/tomcat/src/main/java/org/apache/coyote/request/RequestUri.java @@ -1,10 +1,10 @@ -package nextstep.jwp.request; +package org.apache.coyote.request; import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.stream.Collectors; -import nextstep.jwp.exception.InvalidQueryStringException; +import org.apache.coyote.exception.InvalidQueryStringException; public class RequestUri { private final String uri; diff --git a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java similarity index 92% rename from tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java rename to tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index f12dfdaef2..76335b48a4 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -1,6 +1,6 @@ -package nextstep.jwp.response; +package org.apache.coyote.response; -import nextstep.jwp.model.HttpCookies; +import org.apache.coyote.common.HttpCookies; public class HttpResponse { @@ -11,9 +11,6 @@ public class HttpResponse { private StatusLine statusLine; private String responseBody = ""; - public HttpResponse() { - } - public void setStatusLine(final StatusLine statusLine) { this.statusLine = statusLine; } diff --git a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java b/tomcat/src/main/java/org/apache/coyote/response/ResponseHeaders.java similarity index 95% rename from tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java rename to tomcat/src/main/java/org/apache/coyote/response/ResponseHeaders.java index 0e47a2711a..7427156238 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/ResponseHeaders.java +++ b/tomcat/src/main/java/org/apache/coyote/response/ResponseHeaders.java @@ -1,4 +1,4 @@ -package nextstep.jwp.response; +package org.apache.coyote.response; import java.util.LinkedHashMap; import java.util.List; diff --git a/tomcat/src/main/java/nextstep/jwp/response/StatusLine.java b/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java similarity index 86% rename from tomcat/src/main/java/nextstep/jwp/response/StatusLine.java rename to tomcat/src/main/java/org/apache/coyote/response/StatusLine.java index b6226d1c19..ab0dd2cc2e 100644 --- a/tomcat/src/main/java/nextstep/jwp/response/StatusLine.java +++ b/tomcat/src/main/java/org/apache/coyote/response/StatusLine.java @@ -1,7 +1,7 @@ -package nextstep.jwp.response; +package org.apache.coyote.response; -import nextstep.jwp.common.HttpStatus; -import nextstep.jwp.common.HttpVersion; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.common.HttpVersion; public class StatusLine { From 628ccf8d881c325508c6ae6039eb7f109de74b84 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Thu, 14 Sep 2023 19:56:46 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor:=20Controller=EB=A5=BC=20?= =?UTF-8?q?=EC=9E=90=EB=B0=94=20Servlet=EA=B3=BC=20=EB=B9=84=EC=8A=B7?= =?UTF-8?q?=ED=95=9C=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/controller/AbstractController.java | 11 +++++- .../jwp/controller/ErrorPageController.java | 2 +- .../jwp/controller/LoginController.java | 30 +++++++++++----- .../jwp/controller/LoginPageController.java | 35 ------------------- .../jwp/controller/MainPageController.java | 7 ++-- .../jwp/controller/RegisterController.java | 20 +++++++---- .../controller/RegisterPageController.java | 26 -------------- .../jwp/controller/RequestMapping.java | 10 +++--- .../controller/StaticResourceController.java | 7 ++-- .../apache/catalina/connector/Connector.java | 3 +- 10 files changed, 56 insertions(+), 95 deletions(-) delete mode 100644 tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java delete mode 100644 tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java index 7921a8d4ac..3a2b7a60fe 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -6,6 +6,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import org.apache.catalina.Controller; +import org.apache.coyote.common.HttpMethod; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -17,9 +18,17 @@ abstract class AbstractController implements Controller { @Override public void service(HttpRequest request, HttpResponse response) throws Exception { - // http method 분기문 + if (request.getHttpMethod().equals(HttpMethod.GET)) { + doGet(request, response); + } + if (request.getHttpMethod().equals(HttpMethod.POST)) { + doPost(request, response); + } } + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } + protected String readResponseBody(final String requestUri) throws IOException, URISyntaxException { final URL url = getClass().getClassLoader().getResource(DEFAULT_FILE_LOCATION + requestUri); if (url == null) { diff --git a/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java index 51de178a52..c893b4f859 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java @@ -14,7 +14,7 @@ public boolean canHandle(HttpRequest request) { } @Override - public void service(HttpRequest request, HttpResponse response) throws Exception { + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.NOT_FOUND)); response.addHeader("Content-Type", ContentType.HTML.getType()); final String content = readResponseBody("500.html"); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 76dda1a193..3817ec4a8e 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -5,27 +5,26 @@ import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; -import org.apache.coyote.common.HttpMethod; -import org.apache.coyote.common.HttpStatus; import nextstep.jwp.db.InMemoryUserRepository; -import org.apache.coyote.common.Session; import nextstep.jwp.model.User; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.common.Session; +import org.apache.coyote.common.SessionManager; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; import org.apache.coyote.response.StatusLine; -import org.apache.coyote.common.SessionManager; public class LoginController extends AbstractController { @Override public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.POST) && uri.equals("login"); + return request.getRequestUri() + .equals("login"); } @Override - public void service(HttpRequest request, HttpResponse response) { + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { final Map logInfo = Arrays.stream(request.getRequestBody().split("&")) .map(input -> input.split("=")) .collect(Collectors.toMap(info -> info[0], info -> info[1])); @@ -45,4 +44,19 @@ public void service(HttpRequest request, HttpResponse response) { } response.addHeader("Location", "401.html"); } + + @Override + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + final String sessionId = request.getCookies().ofSessionId("JSESSIONID"); + final Session session = SessionManager.findSession(sessionId); + if (session != null) { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); + response.addHeader("Location", "index.html"); + return; + } + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ".html"); + response.setResponseBody(content); + } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java deleted file mode 100644 index 4ba8cf1d7f..0000000000 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginPageController.java +++ /dev/null @@ -1,35 +0,0 @@ -package nextstep.jwp.controller; - -import org.apache.coyote.common.ContentType; -import org.apache.coyote.common.HttpMethod; -import org.apache.coyote.common.HttpStatus; -import org.apache.coyote.common.Session; -import org.apache.coyote.request.HttpRequest; -import org.apache.coyote.response.HttpResponse; -import org.apache.coyote.response.StatusLine; -import org.apache.coyote.common.SessionManager; - -public class LoginPageController extends AbstractController { - - @Override - public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.GET) && uri.equals("login"); - } - - @Override - public void service(HttpRequest request, HttpResponse response) throws Exception { - final String sessionId = request.getCookies().ofSessionId("JSESSIONID"); - final Session session = SessionManager.findSession(sessionId); - if (session != null) { - response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); - response.addHeader("Location", "index.html"); - return; - } - response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.HTML.getType()); - final String content = readResponseBody(request.getRequestUri() + ".html"); - response.setResponseBody(content); - } -} diff --git a/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java index bb5f0768c6..caa7b5ad05 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java @@ -1,7 +1,6 @@ package nextstep.jwp.controller; import org.apache.coyote.common.ContentType; -import org.apache.coyote.common.HttpMethod; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -11,13 +10,11 @@ public class MainPageController extends AbstractController { @Override public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.GET) && uri.isEmpty(); + return request.getRequestUri().isEmpty(); } @Override - public void service(HttpRequest request, HttpResponse response) { + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); response.addHeader("Content-Type", ContentType.HTML.getType()); response.setResponseBody("Hello world!"); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index a20dace487..7aae6ae159 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -3,25 +3,31 @@ import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; -import org.apache.coyote.common.HttpMethod; -import org.apache.coyote.common.HttpStatus; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; +import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; import org.apache.coyote.response.StatusLine; -public class RegisterController extends AbstractController{ +public class RegisterController extends AbstractController { @Override public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.POST) && uri.equals("register"); + return request.getRequestUri().equals("register"); + } + + @Override + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { + response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); + response.addHeader("Content-Type", ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ".html"); + response.setResponseBody(content); } @Override - public void service(HttpRequest request, HttpResponse response) { + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { final Map registerInfo = Arrays.stream(request.getRequestBody().split("&")) .map(input -> input.split("=")) .collect(Collectors.toMap(info -> info[0], info -> info[1])); diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java deleted file mode 100644 index e48f92ae8a..0000000000 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterPageController.java +++ /dev/null @@ -1,26 +0,0 @@ -package nextstep.jwp.controller; - -import org.apache.coyote.common.ContentType; -import org.apache.coyote.common.HttpMethod; -import org.apache.coyote.common.HttpStatus; -import org.apache.coyote.request.HttpRequest; -import org.apache.coyote.response.HttpResponse; -import org.apache.coyote.response.StatusLine; - -public class RegisterPageController extends AbstractController { - - @Override - public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.GET) && uri.equals("register"); - } - - @Override - public void service(HttpRequest request, HttpResponse response) throws Exception { - response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.HTML.getType()); - final String content = readResponseBody(request.getRequestUri() + ".html"); - response.setResponseBody(content); - } -} diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java b/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java index 274bd7b93c..c674157aaf 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RequestMapping.java @@ -10,20 +10,18 @@ public class RequestMapping implements Controller { private final List controllers = new ArrayList<>(); - private AbstractController defaultController; + private AbstractController errorPageController; - public RequestMapping(final List controllers, final AbstractController defaultController) { + public RequestMapping(final List controllers, final AbstractController errorPageController) { this.controllers.addAll(controllers); - this.defaultController = defaultController; + this.errorPageController = errorPageController; } // jwp에서 requestMapping에 미리 controller들을 등록한 상황이라고 가정 public static Controller getDefault() { return new RequestMapping(List.of( new LoginController(), - new LoginPageController(), new RegisterController(), - new RegisterPageController(), new MainPageController(), new StaticResourceController() ), new ErrorPageController()); @@ -33,7 +31,7 @@ public Controller getController(final HttpRequest request) { return controllers.stream() .filter(controller -> controller.canHandle(request)) .findAny() - .orElse(defaultController); + .orElse(errorPageController); } @Override diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java index 2c95d04038..4ef9df263b 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java @@ -1,7 +1,6 @@ package nextstep.jwp.controller; import org.apache.coyote.common.ContentType; -import org.apache.coyote.common.HttpMethod; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -11,13 +10,11 @@ public class StaticResourceController extends AbstractController { @Override public boolean canHandle(HttpRequest request) { - final HttpMethod method = request.getHttpMethod(); - final String uri = request.getRequestUri(); - return method.equals(HttpMethod.GET) && ContentType.isSupportedType(uri); + return ContentType.isSupportedType(request.getRequestUri()); } @Override - public void service(HttpRequest request, HttpResponse response) throws Exception { + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); response.addHeader("Content-Type", ContentType.getTypeByExtension(request.getRequestUri())); final String content = readResponseBody(request.getRequestUri()); 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 2b7d343f40..8f2393ae3a 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -17,7 +17,7 @@ public class Connector implements Runnable { private static final int DEFAULT_PORT = 8080; private static final int DEFAULT_ACCEPT_COUNT = 100; - private static final int DEFAULT_MAX_THREADS = 250; + private static final int DEFAULT_MAX_THREADS = 24; private final ServerSocket serverSocket; private final ExecutorService executorService; @@ -28,6 +28,7 @@ public Connector() { } public Connector(final int port, final int acceptCount, final int maxThreads) { + this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; this.executorService = Executors.newFixedThreadPool(maxThreads); From b7d7d2984c5a9c04168c555439c4afdf76909803 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Thu, 14 Sep 2023 20:44:42 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat:=20HTTP=20=ED=97=A4=EB=8D=94=20enum?= =?UTF-8?q?=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 --- .../jwp/controller/ErrorPageController.java | 3 ++- .../jwp/controller/LoginController.java | 13 ++++++------ .../jwp/controller/MainPageController.java | 3 ++- .../jwp/controller/RegisterController.java | 11 +++++----- .../controller/StaticResourceController.java | 3 ++- .../org/apache/coyote/common/HttpHeader.java | 21 +++++++++++++++++++ 6 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/common/HttpHeader.java diff --git a/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java index c893b4f859..ceb49bae00 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/ErrorPageController.java @@ -1,6 +1,7 @@ package nextstep.jwp.controller; import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpHeader; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -16,7 +17,7 @@ public boolean canHandle(HttpRequest request) { @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.NOT_FOUND)); - response.addHeader("Content-Type", ContentType.HTML.getType()); + response.addHeader(HttpHeader.CONTENT_TYPE.getName(), ContentType.HTML.getType()); final String content = readResponseBody("500.html"); response.setResponseBody(content); } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index 3817ec4a8e..ceeb664d65 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -8,6 +8,7 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpHeader; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.common.Session; import org.apache.coyote.common.SessionManager; @@ -24,7 +25,7 @@ public boolean canHandle(HttpRequest request) { } @Override - protected void doPost(HttpRequest request, HttpResponse response) throws Exception { + protected void doPost(HttpRequest request, HttpResponse response) { final Map logInfo = Arrays.stream(request.getRequestBody().split("&")) .map(input -> input.split("=")) .collect(Collectors.toMap(info -> info[0], info -> info[1])); @@ -34,7 +35,7 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti if (savedUser.isPresent()) { final User user = savedUser.get(); if (user.checkPassword(logInfo.get("password"))) { - response.addHeader("Location", "index.html"); + response.addHeader(HttpHeader.LOCATION.getName(), "index.html"); final Session session = new Session(UUID.randomUUID().toString()); session.setAttribute("user", user); SessionManager.add(session); @@ -42,7 +43,7 @@ protected void doPost(HttpRequest request, HttpResponse response) throws Excepti return; } } - response.addHeader("Location", "401.html"); + response.addHeader(HttpHeader.LOCATION.getName(), "401.html"); } @Override @@ -51,12 +52,12 @@ protected void doGet(HttpRequest request, HttpResponse response) throws Exceptio final Session session = SessionManager.findSession(sessionId); if (session != null) { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); - response.addHeader("Location", "index.html"); + response.addHeader(HttpHeader.LOCATION.getName(), "index.html"); return; } response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.HTML.getType()); - final String content = readResponseBody(request.getRequestUri() + ".html"); + response.addHeader(HttpHeader.CONTENT_TYPE.getName(), ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ContentType.HTML.getExtension()); response.setResponseBody(content); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java index caa7b5ad05..4db7f22413 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/MainPageController.java @@ -1,6 +1,7 @@ package nextstep.jwp.controller; import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpHeader; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -16,7 +17,7 @@ public boolean canHandle(HttpRequest request) { @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.HTML.getType()); + response.addHeader(HttpHeader.CONTENT_TYPE.getName(), ContentType.HTML.getType()); response.setResponseBody("Hello world!"); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java index 7aae6ae159..f4a05c8f6f 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java @@ -6,6 +6,7 @@ import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.model.User; import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpHeader; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -21,26 +22,26 @@ public boolean canHandle(HttpRequest request) { @Override protected void doPost(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.HTML.getType()); - final String content = readResponseBody(request.getRequestUri() + ".html"); + response.addHeader(HttpHeader.CONTENT_TYPE.getName(), ContentType.HTML.getType()); + final String content = readResponseBody(request.getRequestUri() + ContentType.HTML.getExtension()); response.setResponseBody(content); } @Override - protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + protected void doGet(HttpRequest request, HttpResponse response) { final Map registerInfo = Arrays.stream(request.getRequestBody().split("&")) .map(input -> input.split("=")) .collect(Collectors.toMap(info -> info[0], info -> info[1])); response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); if (InMemoryUserRepository.findByAccount(registerInfo.get("account")).isPresent()) { - response.addHeader("Location", "register.html"); + response.addHeader(HttpHeader.LOCATION.getName(), "register.html"); return; } final User newUser = new User(registerInfo.get("account"), registerInfo.get("password"), registerInfo.get("email")); InMemoryUserRepository.save(newUser); - response.addHeader("Location", "index.html"); + response.addHeader(HttpHeader.LOCATION.getName(), "index.html"); } } diff --git a/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java index 4ef9df263b..bc2bbbb05e 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/StaticResourceController.java @@ -1,6 +1,7 @@ package nextstep.jwp.controller; import org.apache.coyote.common.ContentType; +import org.apache.coyote.common.HttpHeader; import org.apache.coyote.common.HttpStatus; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; @@ -16,7 +17,7 @@ public boolean canHandle(HttpRequest request) { @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.OK)); - response.addHeader("Content-Type", ContentType.getTypeByExtension(request.getRequestUri())); + response.addHeader(HttpHeader.CONTENT_TYPE.getName(), ContentType.getTypeByExtension(request.getRequestUri())); final String content = readResponseBody(request.getRequestUri()); response.setResponseBody(content); } diff --git a/tomcat/src/main/java/org/apache/coyote/common/HttpHeader.java b/tomcat/src/main/java/org/apache/coyote/common/HttpHeader.java new file mode 100644 index 0000000000..b5377eac8f --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpHeader.java @@ -0,0 +1,21 @@ +package org.apache.coyote.common; + +public enum HttpHeader { + + LOCATION("Location"), + COOKIE("Cookies"), + SET_COOKIE("Set-Cookie"), + CONTENT_TYPE("Content-Type"), + CONTEENT_LENGTH("Content-Length"); + + + private final String name; + + HttpHeader(final String name) { + this.name = name; + } + + public String getName() { + return name; + } +} From 0bb3470b328f2083869b2425f8b01163f430e2c5 Mon Sep 17 00:00:00 2001 From: Ohjintaek Date: Thu, 14 Sep 2023 21:45:10 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=ED=99=94?= =?UTF-8?q?=20=EB=B0=8F=20=EB=A9=94=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 | 35 ++++++++++++------- .../org/apache/coyote/common/HttpCookies.java | 1 + .../apache/coyote/http11/Http11Processor.java | 2 +- .../apache/coyote/response/HttpResponse.java | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java index ceeb664d65..38d413cd03 100644 --- a/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/controller/LoginController.java @@ -18,6 +18,11 @@ public class LoginController extends AbstractController { + private static final String PARAM_DELIMITER = "&"; + private static final String KEY_VALUE_DELIMITER = "="; + private static final int ACCOUNT_INDEX = 0; + private static final int PASSWORD_INDEX = 1; + @Override public boolean canHandle(HttpRequest request) { return request.getRequestUri() @@ -26,26 +31,32 @@ public boolean canHandle(HttpRequest request) { @Override protected void doPost(HttpRequest request, HttpResponse response) { - final Map logInfo = Arrays.stream(request.getRequestBody().split("&")) - .map(input -> input.split("=")) - .collect(Collectors.toMap(info -> info[0], info -> info[1])); + final Map authInfo = Arrays.stream(request.getRequestBody().split(PARAM_DELIMITER)) + .map(input -> input.split(KEY_VALUE_DELIMITER)) + .collect(Collectors.toMap(info -> info[ACCOUNT_INDEX], info -> info[PASSWORD_INDEX])); response.setStatusLine(StatusLine.of(request.getHttpVersion(), HttpStatus.FOUND)); - final Optional savedUser = InMemoryUserRepository.findByAccount(logInfo.get("account")); + final Optional savedUser = findUserByLogIn(authInfo); if (savedUser.isPresent()) { final User user = savedUser.get(); - if (user.checkPassword(logInfo.get("password"))) { - response.addHeader(HttpHeader.LOCATION.getName(), "index.html"); - final Session session = new Session(UUID.randomUUID().toString()); - session.setAttribute("user", user); - SessionManager.add(session); - response.addCookie("JSESSIONID", session.getId()); - return; - } + response.addHeader(HttpHeader.LOCATION.getName(), "index.html"); + final Session session = new Session(UUID.randomUUID().toString()); + session.setAttribute("user", user); + SessionManager.add(session); + response.addCookie("JSESSIONID", session.getId()); + return; } response.addHeader(HttpHeader.LOCATION.getName(), "401.html"); } + private Optional findUserByLogIn(final Map logInfo) { + final Optional savedUser = InMemoryUserRepository.findByAccount(logInfo.get("account")); + if (savedUser.isEmpty() || savedUser.get().checkPassword(logInfo.get("password"))) { + return Optional.empty(); + } + return savedUser; + } + @Override protected void doGet(HttpRequest request, HttpResponse response) throws Exception { final String sessionId = request.getCookies().ofSessionId("JSESSIONID"); diff --git a/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java b/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java index 5cf09c3796..ad2fb61244 100644 --- a/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java +++ b/tomcat/src/main/java/org/apache/coyote/common/HttpCookies.java @@ -10,6 +10,7 @@ public class HttpCookies { private static final String DELIMITER = "\r\n"; + private final Map cookies = new LinkedHashMap<>(); public HttpCookies() { 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 e86a9d990e..dab157d9ed 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -35,7 +35,7 @@ public void process(final Socket connection) { final HttpRequest httpRequest = HttpRequest.from(bufferedReader); final HttpResponse httpResponse = new HttpResponse(); requestMapping.service(httpRequest, httpResponse); - outputStream.write(httpResponse.toResponse().getBytes()); + outputStream.write(httpResponse.cconvertToString().getBytes()); outputStream.flush(); } catch (Exception e) { log.error(e.getMessage(), e); diff --git a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java index 76335b48a4..de1a916737 100644 --- a/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/response/HttpResponse.java @@ -35,7 +35,7 @@ public void addCookie(final String name, final String value) { cookies.save(name, value); } - public String toResponse() { + public String cconvertToString() { return String.join(DELIMITER, statusLine.toResponse(), cookies.toResponse() + responseHeaders.toResponse(),