diff --git a/study/src/main/java/cache/com/example/GreetingController.java b/study/src/main/java/cache/com/example/GreetingController.java index 9c2e9239ce..97840b0cdc 100644 --- a/study/src/main/java/cache/com/example/GreetingController.java +++ b/study/src/main/java/cache/com/example/GreetingController.java @@ -1,18 +1,12 @@ package cache.com.example; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; + import org.springframework.http.CacheControl; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Scanner; @Controller public class GreetingController { @@ -22,16 +16,6 @@ public String index() { return "index"; } - @GetMapping("/index.html") - public String indexHtml() { - return "index"; - } - - @GetMapping("/login") - public String login() { - return "login"; - } - /** * 인터셉터를 쓰지 않고 response에 직접 헤더값을 지정할 수도 있다. */ diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Response.java b/tomcat/src/main/java/org/apache/coyote/http11/Response.java index b1e52365fc..e69de29bb2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Response.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Response.java @@ -1,34 +0,0 @@ -package org.apache.coyote.http11; - -import org.apache.coyote.http11.cookie.HttpCookie; - -public class Response { - - public static String of(final String contentType, final String responseBody) { - return String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: " + contentType + "charset=utf-8 ", - "Content-Length: " + responseBody.getBytes().length + " ", - "", - responseBody); - } - - public static String of(final String contentType, final String responseBody, final String status) { - return String.join("\r\n", - "HTTP/1.1 " + status + " ", - "Content-Type: " + contentType + "charset=utf-8 ", - "Content-Length: " + responseBody.getBytes().length + " ", - "", - responseBody); - } - - public static String of(final String contentType, final String responseBody, final HttpCookie httpCookie) { - return String.join("\r\n", - "HTTP/1.1 200 OK ", - "Set-Cookie: " + "JSESSIONID=" + httpCookie.getJSessionId() + " ", - "Content-Type: " + contentType + "charset=utf-8 ", - "Content-Length: " + responseBody.getBytes().length + " ", - "", - responseBody); - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/cookie/HttpCookie.java b/tomcat/src/main/java/org/apache/coyote/http11/cookie/HttpCookie.java index 54613929c9..e69de29bb2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/cookie/HttpCookie.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/cookie/HttpCookie.java @@ -1,32 +0,0 @@ -package org.apache.coyote.http11.cookie; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public class HttpCookie { - private final Map cookies = new ConcurrentHashMap<>(); - - public HttpCookie() { - } - - // JSESSIONID 값 설정 - public void addJSessionId(String sessionId) { - cookies.put("JSESSIONID", sessionId); - } - - // JSESSIONID 값 가져오기 - public String getJSessionId() { - return cookies.get("JSESSIONID"); - } - - // 서버 응답 헤더에 Set-Cookie 추가 - public String addCookieInResponseHeader() { - StringBuilder header = new StringBuilder(); - header.append("HTTP/1.1 200 OK\r\n"); - header.append("Content-Length: 5571\r\n"); - header.append("Content-Type: text/html;charset=utf-8\r\n"); - header.append("Set-Cookie: JSESSIONID=").append(getJSessionId()).append("\r\n"); - return header.toString(); - } -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/cookie/SessionManager.java b/tomcat/src/main/java/org/apache/coyote/http11/cookie/SessionManager.java index 1b914e772e..6e538d73b5 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/cookie/SessionManager.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/cookie/SessionManager.java @@ -1,32 +1,19 @@ -package org.apache.coyote.http11.cookie; +package org.apache.coyote.http; import nextstep.jwp.model.User; -import java.util.HashMap; import java.util.Map; -import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; public class SessionManager { - private static final Map sessions = new HashMap<>(); + private static final Map SESSIONS = new ConcurrentHashMap<>(); - public static void add(final User user, String jsessionId) { - sessions.put(user, jsessionId); + public static void add(String sessionId, User user) { + SESSIONS.put(sessionId, user); } - public static boolean validUser(final User user) { - if(sessions.containsKey(user)) { - return true; - } - - return false; - } - - public static boolean validJsession(final String jsession) { - if(sessions.containsValue(jsession)) { - return true; - } - - return false; + public static boolean isAlreadyLogin(String sessionId) { + return SESSIONS.containsKey(sessionId); } -} +} \ No newline at end of file diff --git a/tomcat/src/main/java/org/apache/coyote/http11/enums/ContentType.java b/tomcat/src/main/java/org/apache/coyote/http11/enums/ContentType.java index 8b3992d10c..1a16d9bbb6 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/enums/ContentType.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/enums/ContentType.java @@ -1,34 +1,36 @@ -package org.apache.coyote.http11.enums; +package org.apache.coyote.http; -public enum ContentType { +import java.util.Arrays; - JS(".js","Application/javascript;"), - CSS(".css","text/css;"), - HTML(".html","text/html;"); +public enum ContentType { + CSS(".css", "text/css"), + ICO(".ico", "text/css"), + JS(".js", "text/javascript"), + SVG(".svg", "image/svg+xml"), + HTML(".html", "text/html; charset=utf-8"); - private final String fileType; - private final String path; + private final String extension; + private final String type; - ContentType(final String fileType, final String path) { - this.fileType = fileType; - this.path = path; + ContentType(String extension, String type) { + this.extension = extension; + this.type = type; } - public static String getContentType(final String path) { - if (path.endsWith(JS.getFileType())) { - return JS.getPath(); - } - if (path.endsWith(CSS.getFileType())) { - return CSS.getPath(); - } - return HTML.getPath(); + public static String findType(String path) { + return Arrays.stream(values()) + .filter(contentType -> path.endsWith(contentType.extension)) + .map(contentType -> contentType.type) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("지원하지 않는 Content Type 입니다.")); } - public String getFileType() { - return fileType; + public static boolean isStaticFile(String type) { + return Arrays.stream(values()) + .anyMatch(contentType -> contentType.getType().equals(type)); } - public String getPath() { - return path; + public String getType() { + return type; } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/enums/Path.java b/tomcat/src/main/java/org/apache/coyote/http11/enums/Path.java index 40da938b72..e69de29bb2 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/enums/Path.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/enums/Path.java @@ -1,29 +0,0 @@ -package org.apache.coyote.http11.enums; - -public enum Path { - - INDEX_URL("static/index.html"), - LOGIN_URL("/login"), - LOGIN_WITH_PARAM_URL("/login?"), - REGISTER_URL("/register"), - - LOGIN_HTML("static/login.html"), - UNAUTHORIZED_HTML("static/401.html"), - REGISTER_HTML("static/register.html"), - - STATIC("static"); - - private final String value; - - Path(final String value) { - this.value = value; - } - - public static boolean isContainParam(String path) { - return path.contains("?"); - } - - public String getValue() { - return value; - } -} diff --git a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java index dd6ccf7000..6b9a42470b 100644 --- a/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java +++ b/tomcat/src/test/java/nextstep/org/apache/coyote/http11/Http11ProcessorTest.java @@ -1,9 +1,6 @@ -package nextstep.org.apache.coyote.http11; +package coyote.http11; -import nextstep.jwp.model.User; import org.apache.coyote.http11.Http11Processor; -import org.apache.coyote.http11.cookie.HttpCookie; -import org.apache.coyote.http11.cookie.SessionManager; import org.junit.jupiter.api.Test; import support.StubSocket; @@ -13,235 +10,54 @@ import java.nio.file.Files; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; class Http11ProcessorTest { @Test - void index() throws IOException { + void process() { // given final var socket = new StubSocket(); final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/index.html"); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8charset=utf-8 ", - "Content-Length: 5564 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).contains(expected); - } - - @Test - void index_css() { - // given - final String request = String.join("\r\n", "GET /css/styles.css HTTP/1.1 ", - "Host: localhost:8080 ", - "Accept: text/css,*/*;q=0.1 ", - "Connection: keep-alive ", - "", - ""); - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/css;charset=utf-8 "); - - assertThat(socket.output()).contains(expected); - } - - @Test - void index_js() { - // given - final String request = String.join("\r\n", "GET scripts.js HTTP/1.1 ", - "Host: localhost:8080 ", - "Accept: text/css,*/*;q=0.1 ", - "Connection: keep-alive ", - "", - ""); - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: Application/javascript;charset=utf-8 "); - - assertThat(socket.output()).contains(expected); - } - - @Test - void login_success_redirect_index() throws IOException { - // given - final String request = String.join("\r\n", "GET /login?account=gugu&password=password HTTP/1.1\r\nHost: localhost:8080\r\n\r\n"); - - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/index.html"); // when processor.process(socket); // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 5564 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).isEqualTo(expected); + String output = socket.output(); + assertAll( + () -> assertThat(output).contains("HTTP/1.1 200 OK"), + () -> assertThat(output).contains("Content-Length: 12"), + () -> assertThat(output).contains("Content-Type: text/html; charset=utf-8"), + () -> assertThat(output).contains("Hello world!") + ); } @Test - void login_failed_redirect_401() throws IOException { - // given - final String request = String.join("\r\n", "GET /login?account=judy&password=j HTTP/1.1\r\nHost: localhost:8080\r\n\r\n"); - - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/401.html"); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 401 Unauthorized ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 2426 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).isEqualTo(expected); - } - - @Test - void register_redirect_index() throws IOException { - // given - final var socket = new StubSocket("GET /register HTTP/1.1\r\nHost: localhost:8080\r\n\r\n"); - final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/register.html"); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 4319 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).contains(expected); - } - - @Test - void login_not_saved_jsession() throws IOException { - // given - final String request = String.join("\r\n", "GET /login HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - "Cookie: JSESSIONID=74262fcd-872c-4bcb-ace8-4bb003882817", - "Content-Type: application/x-www-form-urlencoded ", - "Accept: */* ", - "", - ""); - - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/login.html"); - - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 3796 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).isEqualTo(expected); - } - - @Test - void login_saved_jsession_redirect_index() throws IOException { + void index() throws IOException { // given - final User judy = new User("judy", "judy", "judy@naver.com"); - final HttpCookie httpCookie = new HttpCookie(); - httpCookie.changeJSessionId("74262fcd-872c-4bcb-ace8-4bb003882818"); - SessionManager.add(judy, httpCookie); - - final String request = String.join("\r\n", "GET /login HTTP/1.1 ", + final String httpRequest= String.join("\r\n", + "GET /index.html HTTP/1.1 ", "Host: localhost:8080 ", "Connection: keep-alive ", - "Cookie: JSESSIONID=74262fcd-872c-4bcb-ace8-4bb003882818", - "Content-Type: application/x-www-form-urlencoded ", - "Accept: */* ", "", ""); - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); - final URL resource = getClass().getClassLoader().getResource("static/index.html"); + final var socket = new StubSocket(httpRequest); + final Http11Processor processor = new Http11Processor(socket); // when processor.process(socket); // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 5564 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).isEqualTo(expected); - } - - @Test - void register_post() throws IOException { - // given - final String request = String.join("\r\n", "POST /register HTTP/1.1 ", - "Host: localhost:8080 ", - "Connection: keep-alive ", - "Content-Length: 80 ", - "Content-Type: application/x-www-form-urlencoded ", - "Accept: */* ", - "", - "account=gugu&password=password&email=hkkang%40woowahan.com "); - - final var socket = new StubSocket(request); - final var processor = new Http11Processor(socket); final URL resource = getClass().getClassLoader().getResource("static/index.html"); - // when - processor.process(socket); - - // then - var expected = String.join("\r\n", - "HTTP/1.1 200 OK ", - "Content-Type: text/html;charset=utf-8 ", - "Content-Length: 5564 ", - "", - new String(Files.readAllBytes(new File(resource.getFile()).toPath()))); - - assertThat(socket.output()).contains(expected); + String output = socket.output(); + assertAll( + () -> assertThat(output).contains("HTTP/1.1 200 OK"), + () -> assertThat(output).contains("Content-Length: 5564"), + () -> assertThat(output).contains("Content-Type: text/html; charset=utf-8"), + () -> assertThat(output).contains(new String(Files.readAllBytes(new File(resource.getFile()).toPath())) + )); } }