diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 473cb85..f912013 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -43,7 +43,8 @@ public void run() { RequestHeader requestHeader = RequestHeader.from(requestMessages.toString()); - int contentLength = Integer.parseInt(requestHeader.getAttributes().getOrDefault("Content-Length", "0")); + // Request 에서 contentLength를 바로 가져올 수 있게는 못할까? 생각... + int contentLength = requestHeader.getContentLength(); String requestBody = IOUtils.readData(br, contentLength); requestMessages.add(System.lineSeparator() + requestBody); diff --git a/src/main/java/webserver/http/Request.java b/src/main/java/webserver/http/Request.java index e99c1ec..e706466 100644 --- a/src/main/java/webserver/http/Request.java +++ b/src/main/java/webserver/http/Request.java @@ -40,4 +40,8 @@ public String getPathExtension() { return extension; } + + public int getContentLength() { + return requestMessage.getHeader().getContentLength(); + } } diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index eff3e46..78f34ea 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -30,21 +30,27 @@ public static Attributes from(String headerText) { } public Attributes add(String key, String value) { - attributes.put(key, value); + attributes.put(key.toUpperCase(), value); return this; } public Attributes addAll(Map attributes) { - this.attributes.putAll(attributes); + Map upperAttributes = new LinkedHashMap<>(); + + for (String key : attributes.keySet()) { + upperAttributes.put(key.toUpperCase(), attributes.get(key)); + } + + this.attributes.putAll(upperAttributes); return this; } public String get(String key) { - return attributes.get(key); + return attributes.get(key.toUpperCase()); } public String getOrDefault(String key, String defaultValue) { - return attributes.getOrDefault(key, defaultValue); + return attributes.getOrDefault(key.toUpperCase(), defaultValue); } public String toHeaderText() { diff --git a/src/main/java/webserver/http/header/RequestHeader.java b/src/main/java/webserver/http/header/RequestHeader.java index 6ec0a36..8302b7a 100644 --- a/src/main/java/webserver/http/header/RequestHeader.java +++ b/src/main/java/webserver/http/header/RequestHeader.java @@ -41,4 +41,8 @@ protected String getStatusLine() { public String getQueryString() { return statusLine.getQueryString(); } + + public int getContentLength() { + return Integer.parseInt(super.getAttributes().getOrDefault("Content-Length", "0")); + } } diff --git a/src/test/java/webserver/http/RequestTest.java b/src/test/java/webserver/http/RequestTest.java index a31974f..1e95987 100644 --- a/src/test/java/webserver/http/RequestTest.java +++ b/src/test/java/webserver/http/RequestTest.java @@ -1,6 +1,7 @@ package webserver.http; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -31,12 +32,12 @@ static Stream from() { return Stream.of( Arguments.of( "GET /user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net HTTP/1.1" + System.lineSeparator() + - "Host: localhost:8080" + System.lineSeparator() + - "Connection: keep-alive" + System.lineSeparator() + - "Content-Length: 59" + System.lineSeparator() + - "Content-Type: application/x-www-form-urlencoded" + System.lineSeparator() + - "Accept: */*" + System.lineSeparator() + - "" + System.lineSeparator(), + "Host: localhost:8080" + System.lineSeparator() + + "Connection: keep-alive" + System.lineSeparator() + + "Content-Length: 59" + System.lineSeparator() + + "Content-Type: application/x-www-form-urlencoded" + System.lineSeparator() + + "Accept: */*" + System.lineSeparator() + + "" + System.lineSeparator(), new GetMessage(RequestHeader.of( Arrays.asList( "GET", @@ -53,13 +54,13 @@ static Stream from() { )) ), Arguments.of( "POST /user/create HTTP/1.1" + System.lineSeparator() + - "Host: localhost:8080" + System.lineSeparator() + - "Connection: keep-alive" + System.lineSeparator() + - "Content-Length: 59" + System.lineSeparator() + - "Content-Type: application/x-www-form-urlencoded" + System.lineSeparator() + - "Accept: */*" + System.lineSeparator() + - "" + System.lineSeparator() + - "userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net", + "Host: localhost:8080" + System.lineSeparator() + + "Connection: keep-alive" + System.lineSeparator() + + "Content-Length: 59" + System.lineSeparator() + + "Content-Type: application/x-www-form-urlencoded" + System.lineSeparator() + + "Accept: */*" + System.lineSeparator() + + "" + System.lineSeparator() + + "userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net", new PostMessage( RequestHeader.of( Arrays.asList( @@ -87,7 +88,7 @@ void getPath(String desc, GetMessage getMessage, String expectedPath) { String actualPath = new Request(getMessage).getPath(); assertThat(actualPath).as(desc) - .isEqualTo(expectedPath); + .isEqualTo(expectedPath); } static Stream getPath() { @@ -135,8 +136,8 @@ static Stream getPath() { @MethodSource("getPathExtension") void getPathExtension(String desc, Request request, String expectedExtension) { Assertions.assertThat(request.getPathExtension()) - .as("status line에서 path의 확장자 가져오기 : %s", desc) - .isEqualTo(expectedExtension); + .as("status line에서 path의 확장자 가져오기 : %s", desc) + .isEqualTo(expectedExtension); } static Stream getPathExtension() { @@ -280,4 +281,25 @@ static Stream getPathExtension() { ) ); } + + + @Test + void getContentLength() { + Request request = new Request(new GetMessage(RequestHeader.of( + Arrays.asList( + "GET", + "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net", + "HTTP/1.1" + ), + Attributes.from(new HashMap() {{ + put("Host", "localhost:8080"); + put("Connection", "keep-alive"); + put("Content-Length", "59"); + put("Content-Type", "application/x-www-form-urlencoded"); + put("Accept", "*/*"); + }}) + ))); + + assertThat(request.getContentLength()).isEqualTo(59); + } } diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index ce04955..416a334 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -1,5 +1,6 @@ package webserver.http.attribute; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -11,6 +12,8 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; class AttributesTest { @@ -40,12 +43,20 @@ void fromHeaderText() { } @Test + @DisplayName("add 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") void add() { Attributes attributes = new Attributes(); attributes.add("key", "value"); + + assertAll( + () -> assertEquals("value", attributes.get("KEY")), + () -> assertEquals("value", attributes.get("key")), + () -> assertEquals("value", attributes.get("kEy")) + ); } @Test + @DisplayName("addAll 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") void addAll() { Attributes attributes = new Attributes(); Map attributeMap = new LinkedHashMap<>(); @@ -55,7 +66,11 @@ void addAll() { Attributes expectedAttributes = new Attributes(); expectedAttributes.add("key", "value"); - assertThat(attributes).isEqualTo(expectedAttributes); + assertAll( + () -> assertEquals(expectedAttributes.get("key"), attributes.get("KEY")), + () -> assertEquals(expectedAttributes.get("KEY"), attributes.get("kEY")), + () -> assertEquals(expectedAttributes.get("kEy"), attributes.get("key")) + ); } @Test diff --git a/src/test/java/webserver/http/header/RequestHeaderTest.java b/src/test/java/webserver/http/header/RequestHeaderTest.java index 6617731..1a33312 100644 --- a/src/test/java/webserver/http/header/RequestHeaderTest.java +++ b/src/test/java/webserver/http/header/RequestHeaderTest.java @@ -237,4 +237,54 @@ static Stream getPath() { ) ); } + + @ParameterizedTest + @MethodSource("getContentLength") + void getContentLength(String desc, RequestHeader requestHeader, int expectContentLength) { + int actualContentLength = requestHeader.getContentLength(); + + assertThat(actualContentLength).as(desc) + .isEqualTo(expectContentLength); + } + + static Stream getContentLength() { + return Stream.of( + Arguments.of( + "단일 헤더: Content-Length 파싱", + new RequestHeader(null, new Attributes().add("Content-Length", "10")), + 10 + ), + Arguments.of( + "단일 헤더: CONTENT-LENGTH 파싱", + new RequestHeader(null, new Attributes().add("CONTENT-LENGTH", "10")), + 10 + ), + Arguments.of( + "단일 헤더: content-length 파싱", + new RequestHeader(null, new Attributes().add("content-length", "10")), + 10 + ), + Arguments.of( + "단일 헤더: CONTENT-length 파싱", + new RequestHeader(null, new Attributes().add("CONTENT-length", "10")), + 10 + ), + Arguments.of( + "복수 헤더: CONTENT-LENGTH 파싱", + new RequestHeader(null, new Attributes().addAll(new HashMap() {{ + put("Host", "localhost:8080"); + put("CONTENT-length", "15"); + }})), + 15 + ), + Arguments.of( + "복수 헤더: Content-Length 파싱", + new RequestHeader(null, new Attributes().addAll(new HashMap() {{ + put("Host", "localhost:8080"); + put("Content-Length", "15"); + }})), + 15 + ) + ); + } }