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단계 - HTTP 웹 서버 구현 미션 제출합니다. #213

Open
wants to merge 28 commits into
base: jnsorn
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
275fc42
[제이] 1단계 - HTTP 웹 서버 리팩터링 미션 제출합니다. (#198)
jjj0611 Nov 17, 2020
e74a210
[제이] 2단계 - HTTP 웹 서버 리팩터링 미션 제출합니다. (#203)
jjj0611 Nov 19, 2020
95221c8
docs: 3단계 요구사항1 구현 기능목록 작성
jjj0611 Nov 18, 2020
2df5270
feat: 로그인 기능 구현
jjj0611 Nov 18, 2020
326a6f6
feat: default root 설정
jjj0611 Nov 18, 2020
78bc175
docs: 요구사항 2번째 기능 목록 작성
jjj0611 Nov 20, 2020
4299c68
test: handlebar 사용을 위한 학습테스트 작성
jjj0611 Nov 20, 2020
2caa6e1
feat: 로그인하지 않은 상태면 로그인 페이지로 이동
jjj0611 Nov 20, 2020
1eb2810
feat: 유저 목록 출력하기
jjj0611 Nov 20, 2020
f710df6
feat: 로그인 성공 여부에 따라 페이지 redirect
jjj0611 Nov 20, 2020
76b4d32
refactor: http package 구조 변경
jjj0611 Nov 20, 2020
37a4dce
test: /user GET method에 대한 테스트 작성
jjj0611 Nov 20, 2020
45c30d6
merge: 페어 브랜치와 병합
jnsorn Nov 21, 2020
82d6197
docs: 3단계 요구사항3 구현 기능 목록 작성
jnsorn Nov 21, 2020
0ff5fb1
feat: HttpSession 인터페이스 작성
jnsorn Nov 21, 2020
a7df732
feat: SimpleHttpSession 구현체 작성
jnsorn Nov 21, 2020
cde1e62
feat: httpSession을 적용하여 로그인 구현
jnsorn Nov 22, 2020
ecad459
feat: Cookie 객체 분리
jnsorn Nov 24, 2020
5969877
refactor: Cookies 생성
jnsorn Nov 24, 2020
1f1dcd8
refactor: 지원하지 않는 메서드에 대해서 MethodNotAllowed를 응답하도록 변경
jnsorn Nov 24, 2020
96555ff
refactor: 테스트용 request 파일명 변경
jnsorn Nov 24, 2020
9366961
test: UserServiceTest#findAll 테스트 작성
jnsorn Nov 24, 2020
2a64cd9
refactor: HttpVersion 객체 분리
jnsorn Nov 24, 2020
a8a6832
docs : 3단계 리팩터링 목록 작성
jnsorn Nov 25, 2020
8d6504f
refactor : 인코딩 실패 시 errorStack 출력 -> InternalServerError 반환
jnsorn Nov 25, 2020
1d2b4a7
refactor : null 반환 제거
jnsorn Nov 25, 2020
9b6706a
refactor : doGet() 템플릿화하어 재사용 가능한 구조를 만들기
jnsorn Nov 25, 2020
ac44bc5
refactor : 로그인 검증에 대한 부분을 분리하여 재사용 가능하도록 변경
jjj0611 Nov 26, 2020
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
Prev Previous commit
Next Next commit
feat: Cookie 객체 분리
  • Loading branch information
jnsorn committed Nov 24, 2020
commit ecad459d53aa2f9f4da94f3277f087a576d9549e
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -101,5 +101,5 @@ Thread Pool을 적용해 일정 수의 사용자 동시에 처리가 가능하
- [x] void setAttribute(String name, Object value): 현재 세션에 value 인자로 전달되는 객체를 name 인자 이름으로 저장
- [x] Object getAttribute(String name): 현재 세션에 name 인자로 저장되어 있는 객체 값을 찾아 반환
- [x] void removeAttribute(String name): 현재 세션에 name 인자로 저장되어 있는 객체 값을 삭제
- [ ] void invalidate(): 현재 세션에 저장되어 있는 모든 값을 삭제
- [ ] cookie 구조화
- [x] void invalidate(): 현재 세션에 저장되어 있는 모든 값을 삭제
- [x] cookie 구조화
11 changes: 1 addition & 10 deletions src/main/java/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package controller;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import annotation.RequestMapping;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.io.ClassPathTemplateLoader;
import com.github.jknack.handlebars.io.TemplateLoader;

import annotation.RequestMapping;
import dto.JoinRequestDto;
import dto.UserResponseDto;
import http.ContentType;
@@ -46,11 +42,6 @@ protected void doPost(HttpRequest httpRequest, HttpResponse httpResponse) {

@Override
protected void doGet(HttpRequest httpRequest, HttpResponse httpResponse) {
String cookie = httpRequest.getCookie();
if (Objects.isNull(cookie)) {
unauthorized(httpResponse);
return;
}
HttpSession session = httpRequest.getSession();
String logined = String.valueOf(session.getAttribute("logined"));
if (Objects.isNull(logined) || !"true".equals(logined)) {
39 changes: 39 additions & 0 deletions src/main/java/http/Cookie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package http;

import static java.util.stream.Collectors.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class Cookie {
private String name;
private String value;

public static List<Cookie> listOf(String cookie) {
if(Objects.isNull(cookie) || cookie.isEmpty()){
return new ArrayList<>();
}
return Arrays.stream(cookie.split("; "))
.map(value -> new Cookie(value.split("=")[0], value.split("=")[1]))
.collect(toList());
}

public static Cookie of(String name, String value) {
return new Cookie(name, value);
}

private Cookie(String name, String value) {
this.name = name;
this.value = value;
}

public String getName() {
return name;
}

public String getValue() {
return value;
}
}
2 changes: 1 addition & 1 deletion src/main/java/http/HttpHeaders.java
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ public HttpHeaders() {
this.headers = new HashMap<>();
}

public HttpHeaders(Map<String, String> headers) {
private HttpHeaders(Map<String, String> headers) {
this.headers = headers;
}

2 changes: 2 additions & 0 deletions src/main/java/http/HttpSession.java
Original file line number Diff line number Diff line change
@@ -6,4 +6,6 @@ public interface HttpSession {
Object getAttribute(String name);
void removeAttribute(String name);
void invalidate();
boolean isNew();
void toOld();
}
18 changes: 15 additions & 3 deletions src/main/java/http/SimpleHttpSession.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package http;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class SimpleHttpSession implements HttpSession {
private static Map<String, HttpSession> HTTP_SESSION_STORAGE = new HashMap<>();
private static Map<String, HttpSession> HTTP_SESSION_STORAGE = new ConcurrentHashMap<>();

private String id;
private Map<String, Object> attributes;
private boolean isNew;

public static HttpSession getHttpSessionStorage(String sessionId) {
return HTTP_SESSION_STORAGE.getOrDefault(sessionId, new SimpleHttpSession());
}

private SimpleHttpSession() {
this.id = UUID.randomUUID().toString();
this.attributes = new HashMap<>();
this.attributes = new ConcurrentHashMap<>();
this.isNew = true;
HTTP_SESSION_STORAGE.put(id, this);
}

@@ -44,4 +46,14 @@ public void removeAttribute(String name) {
public void invalidate() {
attributes.clear();
}

@Override
public boolean isNew(){
return isNew;
}

@Override
public void toOld(){
this.isNew = false;
}
}
2 changes: 0 additions & 2 deletions src/main/java/http/request/HttpRequest.java
Original file line number Diff line number Diff line change
@@ -21,7 +21,5 @@ public interface HttpRequest {

HttpBody getBody();

String getCookie();

HttpSession getSession();
}
47 changes: 21 additions & 26 deletions src/main/java/http/request/SimpleHttpRequest.java
Original file line number Diff line number Diff line change
@@ -2,11 +2,10 @@

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import http.Cookie;
import http.HttpBody;
import http.HttpHeaders;
import http.HttpMethod;
@@ -19,6 +18,7 @@ public class SimpleHttpRequest implements HttpRequest {
private HttpHeaders headers;
private HttpBody httpBody;
private HttpSession httpSession;
private List<Cookie> cookies;
private String rawRequest;

public static SimpleHttpRequest of(BufferedReader bufferedReader) throws IOException {
@@ -42,34 +42,34 @@ private static String extractRequestHeader(BufferedReader bufferedReader) throws
}

private static String joinRequest(String startLine, String httpHeaders, String requestBody) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(startLine);
stringBuilder.append(System.lineSeparator());
stringBuilder.append(httpHeaders);
stringBuilder.append(System.lineSeparator());
stringBuilder.append(System.lineSeparator());
stringBuilder.append(requestBody);
return stringBuilder.toString();
return startLine
+ System.lineSeparator()
+ httpHeaders
+ System.lineSeparator()
+ System.lineSeparator()
+ requestBody;
}

private SimpleHttpRequest(StartLine startLine, HttpHeaders httpHeaders, HttpBody httpBody,
String rawRequest) {
this.startLine = startLine;
this.headers = httpHeaders;
this.httpBody = httpBody;
String cookie = getCookie();
if (Objects.isNull(cookie)) {
this.httpSession = SimpleHttpSession.getHttpSessionStorage("");
} else {
Map<String, String> cookies = Arrays.stream(cookie.split("; "))
.map(value -> value.split("="))
.collect(Collectors.toMap(arr -> arr[0], arr -> arr[1]));
String logined = cookies.get("JSESSIONID");
this.httpSession = SimpleHttpSession.getHttpSessionStorage(logined);
}
String cookie = headers.getCookie();
this.cookies = Cookie.listOf(cookie);
String jSessionId = getSessionId();
this.httpSession = SimpleHttpSession.getHttpSessionStorage(jSessionId);
this.rawRequest = rawRequest;
}

private String getSessionId() {
Cookie jSessionCookie = cookies.stream()
.filter(cookie -> "JSESSIONID".equals(cookie.getName()))
.findFirst()
.orElse(null);
return Objects.isNull(jSessionCookie) ? "" : jSessionCookie.getValue();
}

@Override
public HttpMethod getMethod() {
return startLine.getHttpMethod();
@@ -95,11 +95,6 @@ public HttpBody getBody() {
return httpBody;
}

@Override
public String getCookie() {
return headers.getCookie();
}

@Override
public HttpSession getSession() {
return httpSession;
7 changes: 4 additions & 3 deletions src/main/java/webserver/RequestHandler.java
Original file line number Diff line number Diff line change
@@ -31,7 +31,6 @@ public RequestHandler(Socket connectionSocket) {
public void run() {
logger.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
connection.getPort());

try (
InputStream inputStream = connection.getInputStream();
OutputStream outputStream = connection.getOutputStream();
@@ -54,9 +53,11 @@ private void doDispatch(DataOutputStream dos, HttpRequest httpRequest, HttpRespo
HttpServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.service(httpRequest, httpResponse);
} finally {
// TODO: 2020/11/21 나중에 분리 생각하기
HttpSession session = httpRequest.getSession();
httpResponse.setCookie("JSESSIONID=" + session.getId() + "; Path=/");
if(session.isNew()){
httpResponse.setCookie("JSESSIONID=" + session.getId() + "; Path=/");
session.toOld();
}
httpResponse.send(dos);
}
}
8 changes: 1 addition & 7 deletions src/test/java/http/HttpHeadersTest.java
Original file line number Diff line number Diff line change
@@ -22,13 +22,7 @@ void create() {
"Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7" + "\n" +
"Cookie: _ga=GA1.1.1818307867.1604572661" + "\n";

Map<String, String> headers = Arrays.stream(headerRequest.split(System.lineSeparator()))
.map(header -> header.split(": "))
.collect(Collectors.toMap(
pair -> pair[0], pair -> pair[1]
));

HttpHeaders httpHeaders = new HttpHeaders(headers);
HttpHeaders httpHeaders = HttpHeaders.from(headerRequest);

assertAll(
() -> assertThat(httpHeaders.getHeader("Host")).isEqualTo("localhost:8080"),