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단계] 그레이(김동욱) 미션 제출합니다. #367

Merged
merged 33 commits into from
Sep 6, 2023

Conversation

Kim0914
Copy link

@Kim0914 Kim0914 commented Sep 4, 2023

안녕하세요 이리내 !
리뷰 잘 부탁드립니다 ㅎㅎ

우선 큰 구조는 다음과 같습니다.

  1. HttpRequest에서 URL 추출
  2. URL에 해당하는 핸들러 찾기
  3. 핸들러를 이용해 요청 처리 후 HttpResponse 반환

시간이 조금 부족해서 리다이렉트 부분과 테스트를 꼼꼼히 작성하지 못했어요 😅
리뷰 반영할 때 보충해서 추가할게요 ~~

감사합니다 🙇🏻

@Kim0914 Kim0914 requested a review from hectick September 4, 2023 08:34
@Kim0914 Kim0914 self-assigned this Sep 4, 2023
Copy link

@hectick hectick left a comment

Choose a reason for hiding this comment

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

안녕하세요 그레이~
클래스 분리를 적절히 해주신 덕분에 흐름을 따라가면서 코드 리뷰를 수월하게 할 수 있었습니다!

포스트맨도 돌려보고, 궁금한점이나 개선했으면 하는 점 몇자 남겨보았는데요,
그래서 해야할일이 좀 늘었을 수도 있겠습니다만 적절히 셀렉해서 반영해주시면 되겠읍니다~

한번 쭉 보시고 수정할 부분 수정하셔서 pr 요청 주시면 마지할게요!


public static HttpMethod of(String value) {
return Arrays.stream(values())
.filter(httpMethod -> Objects.equals(httpMethod.name, value))
Copy link

Choose a reason for hiding this comment

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

httpMethod.name.equals(value) 대신 Objects.equals(httpMethod.name, value))를 사용한 이유가 있나요?
문자열 비교는 문자열.equlas(문자열)를 습관적으로 써와서 특별히 이렇게 하신 이유가 있는지 궁금해서 물어봅니당

Copy link
Author

@Kim0914 Kim0914 Sep 5, 2023

Choose a reason for hiding this comment

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

null 안정성을 위해서 Objects.equals를 주로 사용합니다.

A.equals(B)에서 A가 상수이거나 null safe 하다면 문제가 되지 않지만,
A가 null이면 NullPointerException이 발생할 수 있어서요 !

그래서 습관적으로 Objects.equals를 써요 ~


final var responseBody = "Hello world!";
HttpRequest httpRequest = HttpRequest.of(bufferedReader);
Copy link

Choose a reason for hiding this comment

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

커밋 순서대로 보려고 했는데 HttpRequest는 같이 커밋이 안되어있는 것을 발견했습니다!
뒤늦게 나눠서 커밋했나보죠? 🫨
네(you 아니고 four) 커밋 이후에 HttpRequest 파일이 생겼네요 깜짝 놀랐읍니다 조심해주세용~

Copy link
Author

Choose a reason for hiding this comment

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

네(four 아니고 yes)


public class HttpRequest {

private final HttpLine httpLine;
Copy link

Choose a reason for hiding this comment

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

네이밍이 포괄적인것 같아요.
구글에 검색해보니 http 요청 구조에서 첫줄은 start line, request line이라고 부르던데,
HttpStartLine이나 HttpRequestLine은 어떤가요?

Comment on lines 40 to 44
private static void validate(String[] splits) {
if (splits.length < MIN_LINE_SIZE) {
throw new IllegalArgumentException("올바르지 않은 HTTP 요청입니다.");
}
}
Copy link

Choose a reason for hiding this comment

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

예외처리 좋네용 👍

Comment on lines +24 to +26
.collect(collectingAndThen(
toMap(line -> line[HEADER_KEY_INDEX], line -> line[HEADER_VALUE_INDEX]),
HttpHeaders::new)
Copy link

Choose a reason for hiding this comment

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

오오 좋은거 배워갑니다잉


public static ContentType of(String value) {
return Arrays.stream(values())
.filter(contentType -> Objects.equals(contentType.getValue(), value))
Copy link

Choose a reason for hiding this comment

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

getValue()대신 그냥 value를 쓸 수 있는걸요~

Suggested change
.filter(contentType -> Objects.equals(contentType.getValue(), value))
.filter(contentType -> Objects.equals(contentType.value, value))

TEXT_CSS("text/css"),
TEXT_HTML("text/html"),
APPLICATION_JS("application/js"),
PERMIT_ALL("*/*");
Copy link

Choose a reason for hiding this comment

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

permit all.. 좋네요 메모..

OK("200"),
FOUND("302"),
UNAUTHORIZED("401"),
CONFLICT("409");
Copy link

Choose a reason for hiding this comment

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

CONFLICT는 어떤 상황에 필요한 것인지 궁금해요

Copy link
Author

Choose a reason for hiding this comment

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

HttpStatus에 대해서 찾아보다가 서버의 현재 상태와 요청이 충돌된 경우(버져닝과 관련된..?)이 있길래 추가해봤었는데
사용하지 않아서 삭제하도록 하겠습니당

Comment on lines 18 to 29
private final ContentType contentType;
private final String body;
private final HashMap<String, String> headers;

public HttpResponse(HttpStatus httpStatus, ContentType contentType, String body) {
this.headers = new LinkedHashMap<>();
this.httpStatus = httpStatus;
this.contentType = contentType;
this.body = body;
headers.put(CONTENT_TYPE, contentType.getValue() + ";charset=utf-8 ");
headers.put(CONTENT_LENGTH, body.getBytes().length + " ");
}
Copy link

Choose a reason for hiding this comment

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

ContentType 필드를 headers 안에 저장하는데, 따로 필드로 들고있는 이유가 있나요?

Copy link
Author

Choose a reason for hiding this comment

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

마감시간에 쫓겨서 급하게 마무리한다고 그랬었는데 리팩토링할게요 ㅎㅎ

@@ -0,0 +1,20 @@
package org.apache.common;

public class Content {
Copy link

Choose a reason for hiding this comment

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

안쓰는 클래스 같아용
무슨 용도였나요?

Copy link
Author

Choose a reason for hiding this comment

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

body를 감싸려고 했었는데 다른 클래스를 사용하고 있어서 삭제해도 되겠네요 !

@sonarcloud
Copy link

sonarcloud bot commented Sep 6, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

warning The version of Java (11.0.20.1) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more here

@Kim0914
Copy link
Author

Kim0914 commented Sep 6, 2023

소중한 피드백 반영했습니다 ㅎㅎ

부족한 테스트도 함께 추가했어요 !

감사합니다 ~~

Copy link

@hectick hectick left a comment

Choose a reason for hiding this comment

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

안녕하세요 그레이~
변경해주신 부분과 테스트 모두 잘 확인했습니다!
추가로 코멘트도 몇개 남겨보았어요!! 다만 아직 해결되지 못한 미스테리가 하나 남아있는데 이건 저도 열심히 찾아보겠습니다🥲
그럼 이만 마지할게용~

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>404 Error - SB Admin</title>
Copy link

Choose a reason for hiding this comment

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

Suggested change
<title>404 Error - SB Admin</title>
<title>405 Error - SB Admin</title>

Comment on lines +17 to +21
if (!httpRequest.isGet()) {
String content = FileReader.read(METHOD_NOT_ALLOWED_PAGE);
HttpResponse httpResponse = new HttpResponse(HttpStatus.METHOD_NOT_ALLOWED, content);
httpResponse.setContentType(ContentType.TEXT_HTML);
return httpResponse;
Copy link

Choose a reason for hiding this comment

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

Comment on lines +48 to +49
String[] accountQuery = queries[0].split("=");
String[] passwordQuery = queries[1].split("=");
Copy link

Choose a reason for hiding this comment

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

쿼리 파라미터의 순서가 다르게 오는 상황도 있을까요?
ex) password=password&account=gugu

Comment on lines 27 to 38
public static HttpLine of(String line) {
String[] splits = splitLine(line);
validate(splits);
String httpMethod = splits[HTTP_METHOD_INDEX];
String requestTarget = splits[RESOURCE_INDEX];
String httpVersion = splits[HTTP_VERSION_INDEX];
return new HttpLine(HttpMethod.of(httpMethod), requestTarget, httpVersion);
}

private static String[] splitLine(String line) {
return line.split(REQUEST_SPLIT_DELIMITER);
}
Copy link

Choose a reason for hiding this comment

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

일단 null 처리를 하긴 했지만 저도 아직 정확히 알지는 못합니다...
현재 코드를 돌려보면, 크롬에서 동작할때는 한 요청당 하나의 스레드가 생기지만,
포스트맨에서 요청을 보낼 때는 한 요청에 두개의 스레드가 생기고, 그 중 첫번째 스레드가 null pointer exception이 터지더라구요.
본격적인 요청을 보내기 전에 서버에 일단 아무거나 보내보는걸까요?
혹시 원인을 먼저 알게되면 공유 부탁드립니당..ㅠ

@hectick hectick merged commit b30ffd1 into woowacourse:kim0914 Sep 6, 2023
2 checks passed
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.

2 participants