Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[톰캣 구현하기 1, 2단계] 재즈(함석명) 미션 제출합니다. #581

Merged
merged 31 commits into from
Sep 8, 2024

Conversation

seokmyungham
Copy link
Member

@seokmyungham seokmyungham commented Sep 6, 2024

낙낙씌~~~~~ 안녕하세요 😊
많이 기다리게 만들어 죄송해요 ㅠㅠ 😅

리팩토링은 다음 3단계 목표지만, 낙낙씌의 원활한 코드 리뷰를 위해 핸들러 호출 분기처리를 조금 개선해 봤어요.
아마 지금 몇십 줄씩 되는 핸들러 코드는 객체 책임 분리와 추상화를 통해 점차적으로 개선될 것 같아요.
어떤 리뷰든 대환영이에요 ㅎㅎ 낙낙씌에게 많이많이 배워가겠습니다 🤗

낙낙씌랑 이번 미션 같이 진행하게 되어 너무 기대되네요 😎
편할 때 천천히 리뷰주세요!!

@seokmyungham seokmyungham self-assigned this Sep 6, 2024
Comment on lines +10 to +22
public class CacheControlInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String cacheControl = CacheControl
.noCache()
.cachePrivate()
.getHeaderValue();

response.setHeader(CACHE_CONTROL, cacheControl);
return true;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스프링 단에서 캐시 설정을 위해 WebContentInterceptor 를 제공해주는데, 이를 이용해 보아도 좋을 것 같아욥!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 캐시 정책과 관련하여 이미 제공해주는 인터셉터 구현체가 있었군요!!
알려주셔서 감사해요 낙낙 😊

Comment on lines +56 to +58
char[] bodyChars = new char[contentLength];
bufferedReader.read(bodyChars, 0, contentLength);
body.append(bodyChars);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contentLength 는 바이트의 길이인데요!
BufferedReader의 read에 전달되는 len은 문자의 길이입니다!

바디에 한글이 담기거나 다른 인코딩 방식을 사용한다면,
바이트의 길이와 문자의 길이가 다를텐데 이에 대해 어떻게 생각하실까요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정말 날카로운 지적이네요 👍👍
바이트를 다루는게 익숙치 않다보니 미처 생각하지 못했던 것 같아요.

바이트 단위로 데이터를 읽어올 수 있도록 하고, 인코딩 방식을 직접 명시해서 데이터 손실을 해결 해야할 것 같습니다.

Copy link
Member

@nak-honest nak-honest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 재즈씌!!

재즈의 코드에 리뷰를 달 수 있다니,, 영광이네요..!

코드 잘 읽었습니다!
리팩토링 전인데도 잘 짜주셨네요 ㅎㅎ

HttpResponse 는 3단계에서 리팩토링 예정이라 그와 관련된 리뷰는 남기지 않았습니다!!
리팩토링 후에 더 많은 이야기 나누어보아요!!

리뷰 반영하실 부분은 3 단계에서 같이 하시면 될 것 같아 바로 merge 시켜 드립니다!!
고생 많으셨어요!!!!

고생 많으셨습니다!

private static final int VALID_PARTS_LENGTH = 3;

private final HttpMethod httpMethod;
private final String uri;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1단계에서는 요청 uri에 쿼리 스트링이 넘어오는 부분이 있었는데요!
해당 부분을 생각해서 uri를 객체로 감싸면 어떨까 싶어요!!

물론 2단계로 넘어가면서 쿼리 스트링은 사라졌지만,,
기존에 있었던 기능은 계속 살려놔도 좋지 않을까 생각됩니닷!

물론 현재 요구사항은 모두 만족하고 있기 때문에 넘어가셔도 좋습니닷!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 있었던 기능은 계속 살려놔도 좋지 않을까 생각됩니닷!

요구사항이 바뀌어도 기존에 있던 기능은 가져가는게 좋겠어요.
현재는 급하게 구현하느라 책임 분리가 엉망인데 다음 단계를 진행하면서 다시 되돌려놓겠습니다 😊

Comment on lines +33 to +35
if (requestParts.length != VALID_PARTS_LENGTH) {
throw new IllegalArgumentException("올바르지 않은 요청 라인 구조입니다.");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 예외처리 좋네요!!
(저는 안했는데 리팩토링 할 때 체크 해야겠네요 ㅎㅎ)

Comment on lines +27 to +33
public static HttpRequest parse(BufferedReader bufferedReader) throws IOException {
RequestLine requestLine = new RequestLine(bufferedReader.readLine());
RequestHeaders requestHeaders = createRequestHeaders(bufferedReader);
RequestBody requestBody = createRequestBody(bufferedReader, requestHeaders);

return new HttpRequest(requestLine, requestHeaders, requestBody);
}
Copy link
Member

@nak-honest nak-honest Sep 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 HttpRequestBufferedReader를 직접 사용해서 데이터를 읽고 있는데요!
추상화 레벨이나, 책임 관점에서 스트림으로부터 읽는 역할의 객체를 따로 분리하는 건 어떠신가요??

예를들면 성능 문제 등으로 인해 Reader나 InputStream에서 읽어 오는 방식이 바뀔 수도 있을텐데 (버퍼 사이즈 조정 등)
HttpRequest가 영향을 받을 것 같아서요!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 그 부분에 대해 고민하고 있었는데 제안해주신 이유들이 다 너무 좋은 것 같아요.
구조를 유연하게 가져가면서 변경의 영향을 최소화할 수 있겠네요

다음 단계를 진행하면서 적극 반영해보겠습니다!!

Comment on lines +26 to +31
public static ContentType find(String path) {
return Arrays.stream(values())
.filter(contentType -> path.toLowerCase().endsWith(contentType.getExtension()))
.findFirst()
.orElse(HTML);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files.probecontenttype() 를 이용하면 MIME 타입을 구할 수 있습니닷!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 따로 제공해주는 메서드가 있었군요 ㅋㅋㅋ

살펴보니 OS 파일 시스템을 통해 확장자를 파악하고 타입을 추론하는 것 같아요.
일치하는 타입이 존재하지 않으면 null을 반환하는 것과, 파일 시스템과 상호작용으로 IOException을 고려해야 하네요.

현재 방식과 비교해서 고민해보고 다음 단계에 반영해보도록 하겠습니다!!
알려주셔서 감사해요. 배워갑니다 낙낙 😊

Comment on lines +9 to +35
class CookieTest {

@DisplayName("쿠키 헤더로 쿠키 객체를 생성한다.")
@Test
void cookieCreateTest() {
String cookieHeader = "tasty_cookie=choco; JSESSIONID=jazz";
Cookie cookie = new Cookie(cookieHeader);

Map<String, String> cookies = Map.of(
"tasty_cookie", "choco",
"JSESSIONID", "jazz"
);

assertThat(cookies).isEqualTo(cookie.getCookies());
}

@DisplayName("쿠키 객체로 쿠키 헤더를 생성한다.")
@Test
void toCookieHeaderTest() {
String cookieHeader = "tasty_cookie=choco; JSESSIONID=jazz";
Cookie cookie = new Cookie(cookieHeader);

assertThat(cookie.toCookieHeader())
.contains("tasty_cookie=choco")
.contains("JSESSIONID=jazz");
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 👍

Comment on lines +7 to +14
GET,
HEAD,
POST,
PUT,
PATCH,
DELETE,
OPTIONS,
TRACE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTTP 메소드에 CONNECT 도 있어서 말씀 드려봅니다!!
다른 부분은 너무 많아서 현재 미션에서는 다 구현할 필요가 없다 생각하지만, 여기는 딱 하나만 추가하면 되어서 말씀 한번 드려보아요 ㅎㅎ

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아이고 지금 다시보니 하나를 뺴먹었네요.😅
찾아주셔서 감사해요 😊

@nak-honest nak-honest merged commit 825fe18 into woowacourse:seokmyungham Sep 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants