Skip to content

Commit

Permalink
[톰캣 구현하기 1, 2단계] 오도(문민혁) 미션 제출합니다. (#344)
Browse files Browse the repository at this point in the history
* test: IOStream 학습 테스트 성공하도록 구현

* feat: GET /index.html 응답하기 구현

* feat: CSS 지원하기 구현

* feat: Query String 파싱 구현

* feat: 로그인 성공시 302, 실패시 401 반환 구현

* refactor: 로그인 부분 분리

* feat: POST 방식으로 회원가입 구현

* feat: 로그인 버튼 클릭 시 GET 방식 -> POST 방식으로 변경

* feat: Session 구현하기 구현

* refactor: HttpRequest 분리

* refactor: HttpResponse 분리

* refactor: Processor 메서드 중복 제거

* refactor: Request에서 Body 파싱하지 않도록 변경

* feat: ExceptionHandler 추가

* refactor: HttpResponse Builder 구현

* refactor: HttpResponse 빌드시 bytes 같이 생성되도록 변경

* refactor: log 내에서 메서드 실행 제거

* refactor: loadResourceAsString -> load 메서드명 개선

* refactor: SessionManager 필드로 변경

* refactor: 파라미터명 간소화
  • Loading branch information
odo27 authored Sep 7, 2023
1 parent 68db530 commit adc6725
Show file tree
Hide file tree
Showing 16 changed files with 706 additions and 22 deletions.
37 changes: 32 additions & 5 deletions study/src/test/java/study/IOStreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.io.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.in;
import static org.mockito.Mockito.*;

/**
Expand Down Expand Up @@ -54,6 +55,7 @@ class OutputStream_학습_테스트 {
* OutputStream 객체의 write 메서드를 사용해서 테스트를 통과시킨다
*/

outputStream.write(bytes);
final String actual = outputStream.toString();

assertThat(actual).isEqualTo("nextstep");
Expand All @@ -79,6 +81,8 @@ class OutputStream_학습_테스트 {
* ByteArrayOutputStream과 어떤 차이가 있을까?
*/

outputStream.flush();

verify(outputStream, atLeastOnce()).flush();
outputStream.close();
}
Expand All @@ -97,6 +101,9 @@ class OutputStream_학습_테스트 {
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
*/

try (outputStream) {
}

verify(outputStream, atLeastOnce()).close();
}
}
Expand Down Expand Up @@ -128,7 +135,13 @@ class InputStream_학습_테스트 {
* todo
* inputStream에서 바이트로 반환한 값을 문자열로 어떻게 바꿀까?
*/
final String actual = "";

OutputStream outputStream = new ByteArrayOutputStream();
for (int data = inputStream.read(); data != -1; data = inputStream.read()) {
outputStream.write(data);
}
String actual = outputStream.toString();
outputStream.close();

assertThat(actual).isEqualTo("🤩");
assertThat(inputStream.read()).isEqualTo(-1);
Expand All @@ -149,6 +162,9 @@ class InputStream_학습_테스트 {
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
*/

try (inputStream) {
}

verify(inputStream, atLeastOnce()).close();
}
}
Expand All @@ -169,12 +185,14 @@ class FilterStream_학습_테스트 {
* 버퍼 크기를 지정하지 않으면 버퍼의 기본 사이즈는 얼마일까?
*/
@Test
void 필터인_BufferedInputStream_사용해보자() {
void 필터인_BufferedInputStream_사용해보자() throws IOException {
final String text = "필터에 연결해보자.";
final InputStream inputStream = new ByteArrayInputStream(text.getBytes());
final InputStream bufferedInputStream = null;
byte[] bytes = text.getBytes();
final InputStream inputStream = new ByteArrayInputStream(bytes);
final InputStream bufferedInputStream = new BufferedInputStream(inputStream);

final byte[] actual = new byte[0];
final byte[] actual = new byte[bytes.length];
bufferedInputStream.read(actual);

assertThat(bufferedInputStream).isInstanceOf(FilterInputStream.class);
assertThat(actual).isEqualTo("필터에 연결해보자.".getBytes());
Expand Down Expand Up @@ -204,8 +222,17 @@ class InputStreamReader_학습_테스트 {
"😋😛😝😜🤪🤨🧐🤓😎🥸🤩",
"");
final InputStream inputStream = new ByteArrayInputStream(emoji.getBytes());
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

final StringBuilder actual = new StringBuilder();
try {
for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) {
actual.append(line);
actual.append("\r\n");
}
} catch (IOException e) {
}

assertThat(actual).hasToString(emoji);
}
Expand Down
34 changes: 34 additions & 0 deletions tomcat/src/main/java/org/apache/catalina/Session.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.apache.catalina;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class Session {

private final String id;
private final Map<String, Object> values = new HashMap<>();

public Session(String id) {
this.id = id;
}

public String getId() {
return id;
}

public Optional<Object> getAttribute(String name) {
if (values.containsKey(name)) {
return Optional.of(values.get(name));
}
return Optional.empty();
}

public void setAttribute(String name, Object value) {
values.put(name, value);
}

public void removeAttribute(String name) {
values.remove(name);
}
}
25 changes: 25 additions & 0 deletions tomcat/src/main/java/org/apache/catalina/SessionManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.apache.catalina;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class SessionManager {

private static final Map<String, Session> SESSIONS = new HashMap<>();

public void add(Session session) {
SESSIONS.put(session.getId(), session);
}

public Optional<Session> findSession(String id) {
if (SESSIONS.containsKey(id)) {
return Optional.of(SESSIONS.get(id));
}
return Optional.empty();
}

public void remove(Session session) {
SESSIONS.remove(session.getId());
}
}
18 changes: 18 additions & 0 deletions tomcat/src/main/java/org/apache/coyote/http11/ContentType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.apache.coyote.http11;

public enum ContentType {

TEXT_HTML("text/html;charset=utf-8"),
TEXT_CSS("text/css;charset=utf-8"),
;

private final String value;

ContentType(String value) {
this.value = value;
}

public String value() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.apache.coyote.http11;

import static org.apache.coyote.http11.ContentType.TEXT_HTML;

import java.io.IOException;

public class ExceptionHandler {

private static final String RESOURCE_PATH_FORMAT = "static/%s.html";

public HttpResponse handleException(HttpException e) throws IOException {
HttpStatus httpStatus = e.httpStatus();
int code = httpStatus.statusCode();
ResourceLoader resourceLoader = new ResourceLoader();
String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code));
return HttpResponse.status(httpStatus)
.contentType(TEXT_HTML)
.body(body)
.build();
}
}
37 changes: 37 additions & 0 deletions tomcat/src/main/java/org/apache/coyote/http11/FormData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.apache.coyote.http11;

import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST;

import java.util.HashMap;
import java.util.Map;

public class FormData {

private static final String AND = "&";
private static final String EQUAL = "=";

private final Map<String, String> formTable;

private FormData(Map<String, String> formTable) {
this.formTable = formTable;
}

public static FormData from(String formData) {
Map<String, String> formTable = new HashMap<>();
String[] splitByAnd = formData.split(AND);
for (String pair : splitByAnd) {
String[] splitByEqual = pair.split(EQUAL, 2);
String key = splitByEqual[0];
String value = splitByEqual[1];
formTable.put(key, value);
}
return new FormData(formTable);
}

public String get(String key) {
if (formTable.containsKey(key)) {
return formTable.get(key);
}
throw new HttpException(BAD_REQUEST, "데이터가 존재하지 않습니다");
}
}
Loading

0 comments on commit adc6725

Please sign in to comment.