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

[톰캣 구현하기 3, 4단계] 루쿠(백경환) 미션 제출합니다. #488

Merged
merged 35 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
69e0cae
train : 학습 테스트 학습
aiaiaiai1 Sep 2, 2023
eaf05ed
feat : GET /index.html 응답하기 + CSS 지원하기
aiaiaiai1 Sep 2, 2023
4983f19
feat : QueryString 파싱
aiaiaiai1 Sep 2, 2023
6e9a13d
feat : HTTP Status Code 302 구현
aiaiaiai1 Sep 2, 2023
dfc5091
feat : reqeustHeader 파싱 기능 추가 + POST 방식으로 회원가입 기능 추가
aiaiaiai1 Sep 3, 2023
21fa23a
feat : 로그인 페이지도 버튼을 눌렀을 때 GET 방식에서 POST 방식으로 전송하도록 변경
aiaiaiai1 Sep 3, 2023
0cad6ff
feat : 세션, 쿠키, 세션매니저 클래스 구현
aiaiaiai1 Sep 3, 2023
c8c49b3
feat : HttpResponse 클래스 구현
aiaiaiai1 Sep 3, 2023
09f7da5
feat : 로그인시 쿠키 설정, 로그인 페이지 접속시 쿠키 헤더 확인 후 응답 처리 추가
aiaiaiai1 Sep 4, 2023
b97149c
refactor: 불필요한 메서드 삭제
aiaiaiai1 Sep 4, 2023
cf030ce
feat: HttpRequest 클래스 구현
aiaiaiai1 Sep 4, 2023
7f37022
feat: HttpRequest 클래스 적용
aiaiaiai1 Sep 4, 2023
8df0133
fix: 컨텐트 타입 text/html로 응답 수정
aiaiaiai1 Sep 4, 2023
2dae997
fix: favicon.ico 응답 추가
aiaiaiai1 Sep 4, 2023
be6dc82
fix: 로그 삭제
aiaiaiai1 Sep 4, 2023
a199ec5
refactor: 접근 제어자 수정
aiaiaiai1 Sep 6, 2023
b367bc5
refactor: 기존 메서드 활용
aiaiaiai1 Sep 6, 2023
e71dd0a
fix: 기존 메서드 내용 구현
aiaiaiai1 Sep 6, 2023
bc337a1
refactor: HttpStatus enum 추가
aiaiaiai1 Sep 6, 2023
031bdf6
refactor: HttpMethod enum 추가
aiaiaiai1 Sep 6, 2023
84c25a5
feat: Controller 인터페이스 추가
aiaiaiai1 Sep 9, 2023
0086b13
refactor: login, register Controller 도입
aiaiaiai1 Sep 9, 2023
959a333
refactor: Request url 매핑 컨트롤러 추가
aiaiaiai1 Sep 10, 2023
72532ba
test: RequestMapping 테스트 코드 추가
aiaiaiai1 Sep 10, 2023
9b278bd
refactor: RootController 분리 및 메서드 삭제
aiaiaiai1 Sep 10, 2023
85917d6
test: 테스트코드 추가
aiaiaiai1 Sep 10, 2023
df9ef9c
feat: 쓰레드 풀 설정 + 세션 동시성 해결
aiaiaiai1 Sep 10, 2023
0d3e1f0
feat: 쓰레드 풀 설정 + 세션 동시성 해결
aiaiaiai1 Sep 10, 2023
176a1ef
충돌해결
aiaiaiai1 Sep 11, 2023
d8b6ab8
fix: 로그인 페이지 불러오기 버그 수정
aiaiaiai1 Sep 14, 2023
c7cb1a0
refactor: 새로운 인스턴스 생기지 않도록 수정
aiaiaiai1 Sep 14, 2023
39abdb4
refactor: 메서드명 수정
aiaiaiai1 Sep 14, 2023
833eaea
refactor: 필드 이름 수정
aiaiaiai1 Sep 14, 2023
8df60ee
refactor: 개행 제거
aiaiaiai1 Sep 14, 2023
147d760
refactor: 방어 로직 추가
aiaiaiai1 Sep 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions tomcat/src/main/java/org/apache/catalina/connector/Connector.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
package org.apache.catalina.connector;

import org.apache.coyote.http11.Http11Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.coyote.http11.Http11Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Connector implements Runnable {

private static final Logger log = LoggerFactory.getLogger(Connector.class);

private static final int DEFAULT_PORT = 8080;
private static final int DEFAULT_ACCEPT_COUNT = 100;
private static final int DEFAULT_MAX_THREADS = 10;

private final ServerSocket serverSocket;
private final ExecutorService executorService;
private boolean stopped;

public Connector() {
this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT);
this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT, DEFAULT_MAX_THREADS);
}

public Connector(final int port, final int acceptCount) {
public Connector(final int port, final int acceptCount, final int maxThreads) {
this.serverSocket = createServerSocket(port, acceptCount);
this.executorService = Executors.newFixedThreadPool(maxThreads);
this.stopped = false;
}

Expand Down Expand Up @@ -67,7 +71,7 @@ private void process(final Socket connection) {
return;
}
var processor = new Http11Processor(connection);
new Thread(processor).start();
executorService.execute(processor);
}

public void stop() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.apache.coyote.controller;

import static org.apache.coyote.http11.HttpMethod.GET;
import static org.apache.coyote.http11.HttpMethod.POST;

import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;

public abstract class AbstractController implements Controller {

@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
if (request.getMethod() == GET) {
doGet(request, response);
return;
}

if (request.getMethod() == POST) {
doPost(request, response);
return;
}

throw new IllegalArgumentException("지원하지 않는 메서드 입니다.");
}

protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ }

protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.apache.coyote.controller;


import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;

public interface Controller {
void service(HttpRequest request, HttpResponse response) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.apache.coyote.controller;

import static org.apache.coyote.http11.HttpStatus.FOUND;
import static org.apache.coyote.http11.HttpStatus.OK;

import java.util.Map;
import java.util.UUID;
import nextstep.jwp.db.InMemoryUserRepository;
import nextstep.jwp.model.User;
import org.apache.coyote.http11.HttpCookie;
import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;
import org.apache.coyote.http11.Session;
import org.apache.coyote.http11.SessionManager;
import org.apache.coyote.http11.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoginController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(LoginController.class);
private static final SessionManager sessionManager = new SessionManager();

@Override
protected void doPost(HttpRequest request, HttpResponse response) throws Exception {
Map<String, String> queryParms = Utils.parseToQueryParms(request.getBody());

try {
User user = InMemoryUserRepository.findByAccount(queryParms.get("account"))
.orElseThrow(() -> new IllegalArgumentException("해당 사용자 없음"));

if (!user.checkPassword(queryParms.get("password"))) {
throw new IllegalArgumentException("비밀번호 불일치");
}
log.info("user: {}", user);

Session session = new Session(UUID.randomUUID().toString());
session.setAttribute("user", user);
sessionManager.add(session);
response.setStatus(FOUND);
response.setRedirectUrl("/index.html");
response.setCookie("JSESSIONID=" + session.getId());

} catch (IllegalArgumentException e) {
log.error("error : {}", e);
response.setStatus(FOUND);
response.setRedirectUrl("/401.html");

}
}

@Override
protected void doGet(HttpRequest request, HttpResponse response) throws Exception {
HttpCookie cookie = new HttpCookie(request.getHeaders().get("Cookie"));

String sessionId = cookie.findValue("JSESSIONID");
if (sessionManager.isExist(sessionId)) {
response.setStatus(FOUND);
response.setRedirectUrl("/index.html");
} else {
response.setStatus(OK);
response.setContentType("text/html");
response.setBody(Utils.readFile("static", "login.html"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.apache.coyote.controller;

import static org.apache.coyote.http11.HttpStatus.FOUND;
import static org.apache.coyote.http11.HttpStatus.OK;

import java.util.Map;
import nextstep.jwp.db.InMemoryUserRepository;
import nextstep.jwp.model.User;
import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;
import org.apache.coyote.http11.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RegisterController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(RegisterController.class);

@Override
protected void doPost(HttpRequest request, HttpResponse response) throws Exception {
Map<String, String> queryParms = Utils.parseToQueryParms(request.getBody());
User user = new User(queryParms.get("account"), queryParms.get("password"),
queryParms.get("email"));
Comment on lines +25 to +26

Choose a reason for hiding this comment

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

queryParams에 account, password, email 중 하나라도 없으면 User에 잘못된 값이 들어갈 것 같은데,
살짝의 방어로직을 추가해보는 것은 어떨까용??

Copy link
Author

@aiaiaiai1 aiaiaiai1 Sep 14, 2023

Choose a reason for hiding this comment

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

추가하였습니다!

InMemoryUserRepository.save(user);
response.setStatus(FOUND);
response.setRedirectUrl("/index.html");
}

@Override
protected void doGet(HttpRequest request, HttpResponse response) throws Exception {
response.setStatus(OK);
response.setContentType("text/html");
response.setBody(Utils.readFile("static", "register.html"));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.apache.coyote.controller;

import org.apache.coyote.http11.HttpRequest;

public class RequestMapping {

public Controller getController(HttpRequest request) {
if (request.getPath().equals("/login")) {
return new LoginController();
}

if (request.getPath().equals("/register")) {
return new RegisterController();
}

if (request.getPath().equals("/")) {
return new RootController();
}

return new ResourceController();
}

Choose a reason for hiding this comment

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

마찬가지로 모든 요청마다 LoginController, RegisterController 등을 새로 만들어 주는 이유가 있나요?!

Copy link
Author

Choose a reason for hiding this comment

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

예리하시군요,.. map에다가 담아 사용하도록 수정하였습니다


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.apache.coyote.controller;

import static org.apache.coyote.http11.HttpStatus.FOUND;
import static org.apache.coyote.http11.HttpStatus.OK;

import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;
import org.apache.coyote.http11.Utils;

public class ResourceController extends AbstractController {

protected void doGet(HttpRequest request, HttpResponse response) throws Exception {
response.setStatus(OK);

String path = request.getPath();
String fileName = path.substring(path.lastIndexOf('/') + 1);

if (fileName.endsWith(".html")) {
response.setContentType("text/html");
response.setBody(Utils.readFile("static", fileName));
return;
}

if (fileName.equals("styles.css")) {
response.setContentType("text/css");
response.setBody(Utils.readFile("static/css", fileName));
return;
}

if (fileName.endsWith(".js") && !fileName.equals("scripts.js")) {
response.setContentType("text/javascript");
response.setBody(Utils.readFile("static/assets", fileName));
return;
}

if (fileName.equals("scripts.js")) {
response.setContentType("text/javascript");
response.setBody(Utils.readFile("static/js", fileName));
return;
}

if (fileName.equals("favicon.ico")) {
response.setContentType("text/javascript");
response.setBody("Hello world!");
return;
}
Comment on lines +18 to +46

Choose a reason for hiding this comment

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

지금 구조에서는
새로운 정적파일이 추가될 때마다 if 분기문이 계속해서 추가되어야 할 것 같은데
어떻게 생각하시나용??

Copy link
Author

@aiaiaiai1 aiaiaiai1 Sep 14, 2023

Choose a reason for hiding this comment

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

맞습니다 오잉이 말씀해주신것처럼 정적파일이 추가될때마다 If문이 추가될거같아요..
이부분에 대해서는 좀더 근본적인 방법이 잘 떠오르지 않아서 좀더 고민하고 생각해봐야할거같습니다 😭


response.setStatus(FOUND);
response.setRedirectUrl("404.html");
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.apache.coyote.controller;

import org.apache.coyote.http11.HttpRequest;
import org.apache.coyote.http11.HttpResponse;
import org.apache.coyote.http11.HttpStatus;

public class RootController extends AbstractController {

@Override
protected void doGet(HttpRequest request, HttpResponse response) throws Exception {
response.setStatus(HttpStatus.OK);
response.setContentType("text/html");
response.setBody("Hello world!");
}

}
Loading
Loading