Skip to content

Commit

Permalink
[톰캣 구현하기 - 3, 4단계] 달리 미션 제출합니다 (#442)
Browse files Browse the repository at this point in the history
* refactor: 클래스 제거

* refactor: handler 구조 변경

* refactor: filter 구현

* style: 코드 컨벤션 적용

* feat: threadPool 적용

* test: study 요구조건 진행

* refactor: 불필요한 클래스 분리 통합

* feat: controller 추상 매서드 추가

* refactor: requestline 분리

* refactor: bufferedreader 자원관리

* style: 코드 컨벤션 적용

* refactor: 사용하지 않는 클래스 제거

* refactor: Map key value 변경

* refactor: 값객체 클래스명 변경

* refactor: 생성자 접근자 변경

* refactor: filter 등록을 안할 시 npe 방지 default filter 추가

* refactor: var 제거

* style: 코드 컨벤션 적용

* feat: handler 및 FilterChainManager 싱글톤으로 관리

* refactor: singleton 생성자 private 으로 변경
  • Loading branch information
waterricecake authored Sep 13, 2023
1 parent 841e70a commit c33e0ec
Show file tree
Hide file tree
Showing 41 changed files with 735 additions and 544 deletions.
4 changes: 2 additions & 2 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ handlebars:

server:
tomcat:
accept-count: 1
max-connections: 1
accept-count: 100
max-connections: 250
threads:
max: 2
2 changes: 1 addition & 1 deletion study/src/test/java/thread/stage0/SynchronizationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private static final class SynchronizedMethods {

private int sum = 0;

public void calculate() {
synchronized public void calculate() {
setSum(getSum() + 1);
}

Expand Down
6 changes: 3 additions & 3 deletions study/src/test/java/thread/stage0/ThreadPoolsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ void testNewFixedThreadPool() {
executor.submit(logWithSleep("hello fixed thread pools"));

// 올바른 값으로 바꿔서 테스트를 통과시키자.
final int expectedPoolSize = 0;
final int expectedQueueSize = 0;
final int expectedPoolSize = 2;
final int expectedQueueSize = 1;

assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
assertThat(expectedQueueSize).isEqualTo(executor.getQueue().size());
Expand All @@ -46,7 +46,7 @@ void testNewCachedThreadPool() {
executor.submit(logWithSleep("hello cached thread pools"));

// 올바른 값으로 바꿔서 테스트를 통과시키자.
final int expectedPoolSize = 0;
final int expectedPoolSize = 3;
final int expectedQueueSize = 0;

assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
Expand Down
2 changes: 1 addition & 1 deletion study/src/test/java/thread/stage2/AppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AppTest {
*/
@Test
void test() throws Exception {
final var NUMBER_OF_THREAD = 10;
final var NUMBER_OF_THREAD = 250;
var threads = new Thread[NUMBER_OF_THREAD];

for (int i = 0; i < NUMBER_OF_THREAD; i++) {
Expand Down
43 changes: 43 additions & 0 deletions tomcat/src/main/java/nextstep/jwp/config/LoginFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package nextstep.jwp.config;

import java.util.Map;
import nextstep.jwp.db.InMemorySession;
import org.apache.coyote.http11.filter.Filter;
import org.apache.coyote.http11.filter.FilterChain;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;
import org.apache.coyote.http11.util.Resource;

public class LoginFilter implements Filter {

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {

final String uri = request.getPath();
final Map<String, String> cookie = request.getCookie();

if (uri.equals("/login") && cookie.containsKey("JSESSIONID")) {
validKey(cookie.get("JSESSIONID"), response);
}
filterChain.doFilter(request, response);
}

private void validKey(String jSessionId, Response response) {
if (InMemorySession.isLogin(jSessionId)) {
response
.setStatus(HttpStatus.FOUND)
.setContentType("html")
.setLocation("/index.html")
.setResponseBody(Resource.getFile("index.html"))
.setFiltered(true);
return;
}
response
.setStatus(HttpStatus.UNAUTHORIZED)
.setContentType("html")
.setResponseBody(Resource.getFile("401.html"))
.setLocation("/401.html")
.setFiltered(true);
}
}
43 changes: 43 additions & 0 deletions tomcat/src/main/java/nextstep/jwp/config/RegisterFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package nextstep.jwp.config;

import java.util.Map;
import nextstep.jwp.db.InMemorySession;
import org.apache.coyote.http11.filter.Filter;
import org.apache.coyote.http11.filter.FilterChain;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;
import org.apache.coyote.http11.util.Resource;

public class RegisterFilter implements Filter {

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {

final String uri = request.getPath();
final Map<String, String> cookie = request.getCookie();

if ((uri.equals("/register")) && cookie.containsKey("JSESSIONID")) {
validKey(cookie.get("JSESSIONID"), response);
}
filterChain.doFilter(request, response);
}

private void validKey(String jSessionId, Response response) {
if (InMemorySession.isLogin(jSessionId)) {
response
.setStatus(HttpStatus.FOUND)
.setContentType("html")
.setLocation("/index.html")
.setResponseBody(Resource.getFile("index.html"))
.setFiltered(true);
return;
}
response
.setStatus(HttpStatus.UNAUTHORIZED)
.setContentType("html")
.setResponseBody(Resource.getFile("401.html"))
.setLocation("/401.html")
.setFiltered(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nextstep.jwp.controller;

import org.apache.coyote.http11.controller.AbstractController;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;

public class HelloWorldController extends AbstractController {

@Override
protected void doGet(Request request, Response response) {
response.setStatus(HttpStatus.OK)
.setContentType("html")
.setResponseBody("Hello world!");
}
}
67 changes: 21 additions & 46 deletions tomcat/src/main/java/nextstep/jwp/controller/LoginController.java
Original file line number Diff line number Diff line change
@@ -1,68 +1,43 @@
package nextstep.jwp.controller;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import nextstep.jwp.db.InMemorySession;
import nextstep.jwp.db.InMemoryUserRepository;
import nextstep.jwp.exception.UnauthorizedException;
import nextstep.jwp.model.AuthUser;
import nextstep.jwp.model.User;
import org.apache.coyote.http11.controller.AbstractController;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;
import org.apache.coyote.http11.servlet.Servlet;
import org.apache.coyote.http11.util.Resource;

public class LoginController {
public class LoginController extends AbstractController {

public static Response login(Request request){
@Override
protected void doPost(Request request, Response response) {
Map<String, String> body = request.getBody();
AuthUser authUser = AuthUser.from(body);
User user = InMemoryUserRepository.findByAccount(authUser.getAccount()).orElseThrow(()->new UnauthorizedException("해당 유저가 없습니다."));
if(!user.checkPassword(authUser.getPassword())){
User user = InMemoryUserRepository.findByAccount(body.get("account"))
.orElseThrow(() -> new UnauthorizedException("해당 유저가 없습니다."));
if (!user.checkPassword(body.get("password"))) {
throw new UnauthorizedException("아이디 및 패스워드가 틀렸습니다.");
}
String jSessionId = InMemorySession.login(user);
Map<String,String> cookie = new HashMap<>();
if(!request.getCookie().containsKey("JSESSIONID")){
cookie.put("JSESSIONID",jSessionId);
Map<String, String> cookie = new HashMap<>();
if (!request.getCookie().containsKey("JSESSIONID")) {
cookie.put("JSESSIONID", jSessionId);
}
return Response.builder()
.status(HttpStatus.FOUND)
.contentType("html")
.cookie(cookie)
.location("index.html")
.responseBody(getFile("index.html"))
.build();
response.setStatus(HttpStatus.FOUND)
.setContentType("html")
.setCookie(cookie)
.setLocation("index.html")
.setResponseBody(Resource.getFile("index.html"));
}

public static Response signUp(Request request){
Map<String, String> requestBody = request.getBody();
final String account = requestBody.get("account");
final String password = requestBody.get("password");
final String email = requestBody.get("email");
User user = new User(account,password,email);
InMemoryUserRepository.save(user);
return Response.builder()
.status(HttpStatus.FOUND)
.contentType("html")
.location("index.html")
.responseBody(getFile("index.html"))
.build();
}


private static String getFile(String fileName){
try {
final var fileUrl = Servlet.class.getClassLoader().getResource("static/" + fileName);
final var fileBytes = Files.readAllBytes(new File(fileUrl.getFile()).toPath());
return new String(fileBytes);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (NullPointerException e){
return "";
}
@Override
protected void doGet(Request request, Response response) {
response.setStatus(HttpStatus.OK)
.setContentType("html")
.setResponseBody(Resource.getFile("login.html"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package nextstep.jwp.controller;

import java.util.Map;
import nextstep.jwp.db.InMemoryUserRepository;
import nextstep.jwp.model.User;
import org.apache.coyote.http11.controller.AbstractController;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;
import org.apache.coyote.http11.util.Resource;

public class RegisterController extends AbstractController {

@Override
public void doPost(Request request, Response response) {
Map<String, String> requestBody = request.getBody();
final String account = requestBody.get("account");
final String password = requestBody.get("password");
final String email = requestBody.get("email");
User user = new User(account, password, email);
InMemoryUserRepository.save(user);
response.setStatus(HttpStatus.FOUND)
.setContentType("html")
.setLocation("index.html")
.setResponseBody(Resource.getFile("index.html"));
}

@Override
protected void doGet(Request request, Response response) {
response.setStatus(HttpStatus.OK)
.setContentType("html")
.setResponseBody(Resource.getFile("register.html"));
}
}
46 changes: 9 additions & 37 deletions tomcat/src/main/java/nextstep/jwp/controller/ViewController.java
Original file line number Diff line number Diff line change
@@ -1,48 +1,20 @@
package nextstep.jwp.controller;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.apache.coyote.http11.controller.AbstractController;
import org.apache.coyote.http11.request.Request;
import org.apache.coyote.http11.response.HttpStatus;
import org.apache.coyote.http11.response.Response;
import org.apache.coyote.http11.servlet.Servlet;
import org.apache.coyote.http11.util.Resource;

public class ViewController {
public static Response getLogin(Request request){
return Response.builder()
.status(HttpStatus.OK)
.contentType("html")
.responseBody(getFile("login.html"))
.build();
}

public static Response getRegister(Request request){
return Response.builder()
.status(HttpStatus.OK)
.contentType("html")
.responseBody(getFile("register.html"))
.build();
}
public class ViewController extends AbstractController {

public static Response getVoid(Request request){
return Response.builder()
.status(HttpStatus.OK)
.responseBody("Hello world!")
.contentType("html")
.build();
}
@Override
protected void doGet(Request request, Response response) {

String fileName = request.getPath();

private static String getFile(String fileName){
try {
final var fileUrl = Servlet.class.getClassLoader().getResource("static/" + fileName);
final var fileBytes = Files.readAllBytes(new File(fileUrl.getFile()).toPath());
return new String(fileBytes);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (NullPointerException e){
return "";
}
response.setStatus(HttpStatus.OK)
.setContentType(fileName.split("\\.")[1])
.setResponseBody(Resource.getFile(fileName));
}
}
17 changes: 10 additions & 7 deletions tomcat/src/main/java/nextstep/jwp/db/InMemorySession.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import nextstep.jwp.exception.UnauthorizedException;
import nextstep.jwp.model.User;

public class InMemorySession {
private static final Map<User, UUID> session = new HashMap<>();

public static String login(User user){
private static final Map<UUID, User> session = new HashMap<>();

private InMemorySession(){}

public static String login(User user) {
UUID uuid = UUID.randomUUID();
session.put(user,uuid);
session.put(uuid, user);
return uuid.toString();
}
public static boolean isLogin(String id){
for(UUID uuid: session.values()){
if(uuid.toString().equals(id)){

public static boolean isLogin(String id) {
for (UUID uuid : session.keySet()) {
if (uuid.toString().equals(id)) {
return true;
}
}
Expand Down
Loading

0 comments on commit c33e0ec

Please sign in to comment.