diff --git a/README.md b/README.md
index f5372b4f..a409f6e1 100644
--- a/README.md
+++ b/README.md
@@ -132,6 +132,57 @@ URL 전체 문법
- query : key=value 형태. ?로 시작, &로 추가 가능
- fragment : html 내부 북마크 등에 사용하며 서버에 전송되는 정보는 아님
+
+
+쿠키
+
+- Set-Cookie : 서버에서 클라이언트로 쿠키 전달(응답)
+- Cookie : 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
+
+---
+
+- Stateless한 HTTP의 특징의 대안
+ - (쿠키 미사용) 모든 요청에 사용자 정보 포함
+ - 모든 요청과 링크에 사용자 정보를 포함하라구? 😱
+ - 모든 요청에 사용자 정보가 포함되도록 개발 해야함
+ - 브라우저를 완전히 종료하고 다시 열면?
+ - 쿠키의 등장
+ - 웹 브라우저 내부의 쿠키 저장소에 서버가 응답에 보낸 Set-Cookie의 내용을 저장
+ - 앞으로 요청을 보낼때마다 쿠키 저장소를 뒤져서 Cookie에 담아서 요청
+ - 모든 요청에 쿠키 정보 자동 포함
+- 사용처
+ - 사용자 로그인 세션 관리
+ - 광고 정보 트래킹
+- 쿠키 정보는 항상 서버에 전송됨
+ - 네트워크 트래픽 추가 유발
+ - 최소한의 정보만 사용(세션 id, 인증 토큰)
+ - 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(localStorage, sessionStorage) 참고
+- 보안에 민감한 데이터는 저장하면 안됨
+- 생명주기
+ - expires : 만료일이 되면 쿠키 삭제
+ - max-age : 0이나 음수를 지정하면 쿠키 삭제 (초단위)
+ - 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시까지만 유지
+ - 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지
+- 도메인 domain
+ - 명시 : 명시한 문서 기준 도메인 + 서브 도메인 포함
+ - domain=example.org를 지정해서 쿠키를 생성하면, example.org는 물론이고 dev.example.org도 쿠키 접근
+ - 생략 : 현재 문서 기준 도메인만 적용
+ - example.org에서 쿠키를 생성하고 domain 지정을 생략하면 example.org에서만 쿠키 접근
+- 경로 path
+ - 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
+ - 일반적으로 path=/ 루트로 지정
+- 보안
+ - Secure
+ - 쿠키는 http, https를 구분하지 않고 전송하는데, secure를 적용하면 https인 경우에만 전송
+ - HttpOnly
+ - XSS 공격 방지
+ - 자바스크립트에서 접근 불가
+ - HTTP 전송에만 사용
+ - SameSite
+ - XSRF 공격 방지
+ - 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
+ - 브라우저에서 지원하는지 확인 하고 사용
+
### 삽질을 통해 배운 점
겪은 문제 : 서버에 "POST" 요청을 했을 때 바로 response가 오지 않고, 다음 요청이 왔을 때 전에 "POST"의 response가 비어있는 상태로 software caused connection
@@ -191,8 +242,18 @@ TODO 리스트
- [x] Run를 여러 메소드로 쪼갠다.
## 리뷰 받은 내용
-
- [x] 마크다운 문법에 맞게 README를 작성하기
- [x] HttpRequestUtils에서 getQueryString() 메소드 수정
- [x] 인코딩 형식들 README에 작성하기
- [x] URL에 대한 내용 찾아보기
+
+## 4단계 - 쿠키를 이용한 로그인 구현
+ - [x] 회원가입한 사용자로 로그인을 할 수 있어야 한다.
+ - [x] “로그인” 메뉴를 클릭하면 http://localhost:8080/user/login.html 으로 이동해 로그인할 수 있다.
+ - [x] 로그인이 성공하면 index.html로 이동하고, 로그인이 실패하면 /user/login_failed.html로 이동해야 한다.
+ - [x] 정상적으로 로그인 되었는지 확인하려면 앞 단계에서 회원가입한 데이터를 유지해야 한다.
+ - [x] 앞 단계에서 회원가입할 때 생성한 User 객체를 DataBase.addUser() 메서드를 활용해 메모리에 저장한다.
+ - [x] 필요에 따라 Database 클래스의 메소드나 멤버변수를 수정해서 사용한다.
+ - [x] 아이디와 비밀번호가 같은지를 확인해서 로그인이 성공하면 응답 header의 Set-Cookie 값을 sessionId=적당한값으로 설정한다.
+ - [x] Set-Cookie 설정시 모든 요청에 대해 Cookie 처리가 가능하도록 Path 설정 값을 /(Path=/)로 설정한다.
+ - [x] 응답 header에 Set-Cookie값을 설정한 후 요청 header에 Cookie이 전달되는지 확인한다.
diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
new file mode 100644
index 00000000..b1f5491c
--- /dev/null
+++ b/src/main/java/controller/Controller.java
@@ -0,0 +1,10 @@
+package controller;
+
+import http.Request;
+import http.Response;
+
+import java.io.IOException;
+
+public interface Controller {
+ public Response run(Request request) throws IOException;
+}
diff --git a/src/main/java/controller/DefaultController.java b/src/main/java/controller/DefaultController.java
new file mode 100644
index 00000000..42fe997d
--- /dev/null
+++ b/src/main/java/controller/DefaultController.java
@@ -0,0 +1,40 @@
+package controller;
+
+import http.Request;
+import http.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DefaultController implements Controller {
+
+ private static final Logger log = LoggerFactory.getLogger(DefaultController.class);
+ private static final DefaultController instance = new DefaultController();
+
+ public static DefaultController getInstance() {
+ return instance;
+ }
+
+ private DefaultController() {
+
+ }
+
+ @Override
+ public Response run(Request request) throws IOException {
+ String url = request.methodUrl().getValue(); // /index.html
+ String contentType = url.split("\\.")[1];
+ byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
+ Map responseHeader = new HashMap<>();
+// responseHeader.put("Content-Type", "text/" + contentType + ";charset=utf-8");
+ responseHeader.put("Content-Length", String.valueOf(body.length));
+ Response response = new Response("HTTP/1.1", "200", "OK", responseHeader, body);
+ log.debug("[response] : {}", response.responseMessage());
+ return response;
+ }
+}
diff --git a/src/main/java/controller/LogInController.java b/src/main/java/controller/LogInController.java
new file mode 100644
index 00000000..b2dce410
--- /dev/null
+++ b/src/main/java/controller/LogInController.java
@@ -0,0 +1,48 @@
+package controller;
+
+import db.DataBase;
+import http.Request;
+import http.Response;
+import model.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class LogInController implements Controller {
+ private static final Logger log = LoggerFactory.getLogger(LogInController.class);
+ private static final LogInController instance = new LogInController();
+
+ public static LogInController getInstance() {
+ return instance;
+ }
+
+ private LogInController() {
+
+ }
+
+ @Override
+ public Response run(Request request) {
+ String userId = request.findBodyByFieldName("userId");
+ String password = request.findBodyByFieldName("password");
+ Optional user = DataBase.findUserById(userId);
+
+ Map responseHeader = new HashMap<>();
+ responseHeader.put("Content-Type", "text/html;charset=utf-8");
+ responseHeader.put("Content-Length", String.valueOf(0));
+ if (user.isEmpty() || !user.get().isCorrectPassword(password)) {
+ log.debug("로그인을 실패하였습니다!");
+ responseHeader.put("Location", "/user/login_failed.html");
+
+ } else if (user.get().isCorrectPassword(password)) {
+ log.debug("로그인을 성공했습니다!");
+ responseHeader.put("Location", "/index.html");
+ responseHeader.put("Set-Cookie", "logined=true; Path=/");
+ }
+ Response response = new Response("HTTP/1.1", "302", "Found", responseHeader, "".getBytes());
+ log.debug("[response] : {}", response.responseMessage());
+ return response;
+ }
+}
diff --git a/src/main/java/controller/LogOutController.java b/src/main/java/controller/LogOutController.java
new file mode 100644
index 00000000..9d4e877c
--- /dev/null
+++ b/src/main/java/controller/LogOutController.java
@@ -0,0 +1,40 @@
+package controller;
+
+import http.Request;
+import http.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.Map;
+
+public class LogOutController implements Controller {
+
+ private static final Logger log = LoggerFactory.getLogger(LogOutController.class);
+ private static final LogOutController instance = new LogOutController();
+
+ public static LogOutController getInstance() {
+ return instance;
+ }
+
+ private LogOutController() {
+
+ }
+
+ @Override
+ public Response run(Request request) throws IOException {
+ byte[] body;
+ body = Files.readAllBytes(new File("./webapp" + "/index.html").toPath());
+ Map responseHeader = new HashMap<>();
+ responseHeader.put("Content-Type", "text/html;charset=utf-8");
+ responseHeader.put("Content-Length", String.valueOf(body.length));
+ responseHeader.put("Location", "/index.html");
+ responseHeader.put("Set-Cookie", "logined=true; Max-Age=0; Path=/");
+ Response response = new Response("HTTP/1.1", "302", "Found", responseHeader, body);
+ log.debug("[response] : {}", response.responseMessage());
+ return response;
+ }
+}
diff --git a/src/main/java/controller/SignUpController.java b/src/main/java/controller/SignUpController.java
new file mode 100644
index 00000000..9011f80a
--- /dev/null
+++ b/src/main/java/controller/SignUpController.java
@@ -0,0 +1,67 @@
+package controller;
+
+import db.DataBase;
+import http.Request;
+import http.Response;
+import model.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+public class SignUpController implements Controller {
+
+ private static final Logger log = LoggerFactory.getLogger(SignUpController.class);
+ private static final SignUpController instance = new SignUpController();
+
+ public static SignUpController getInstance() {
+ return instance;
+ }
+
+ private SignUpController() {
+
+ }
+
+ @Override
+ public Response run(Request request) {
+ byte[] body = "".getBytes();
+ Map responseHeader = new HashMap<>();
+ responseHeader.put("Content-Type", "text/html;charset=utf-8");
+ responseHeader.put("Content-Length", String.valueOf(body.length));
+
+ DataBase.findUserById(request.findBodyByFieldName("userId"))
+ .ifPresentOrElse(
+ redirectSignUpFail(responseHeader),
+ redirectSignUpSuccess(request, responseHeader)
+ );
+ Response response = new Response("HTTP/1.1", "302", "Found", responseHeader, body);
+ log.debug("[response] : {}", response.responseMessage());
+ return response;
+ }
+
+ private Runnable redirectSignUpSuccess(Request request, Map responseHeader) {
+ return () -> {
+ createUser(request);
+ responseHeader.put("Location", "/index.html");
+ };
+ }
+
+ private void createUser(Request request) {
+ User user = new User(
+ request.findBodyByFieldName("userId"),
+ request.findBodyByFieldName("password"),
+ request.findBodyByFieldName("name"),
+ request.findBodyByFieldName("email"));
+ log.debug("User : {}", user);
+ DataBase.addUser(user);
+ }
+
+ private Consumer redirectSignUpFail(Map responseHeader) {
+ return user -> {
+ responseHeader.put("Location", "/user/form.html");
+ log.debug("중복된 아이디가 존재합니다.");
+ };
+ }
+}
diff --git a/src/main/java/http/Request.java b/src/main/java/http/Request.java
new file mode 100644
index 00000000..265fbfa0
--- /dev/null
+++ b/src/main/java/http/Request.java
@@ -0,0 +1,82 @@
+package http;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import util.HttpRequestUtils;
+import util.IOUtils;
+import util.Pair;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Request {
+ private static final Logger log = LoggerFactory.getLogger(Request.class);
+
+ private final int METHOD = 0;
+ private final int URL = 1;
+ private final int HTTP_VERSION = 2;
+ private final int KEY = 0;
+ private final int VALUE = 1;
+
+ private String httpMethod;
+ private String requestUrl;
+ private String httpVersion;
+ private Map requestHeaderField = new HashMap<>();
+ private Map requestBody = new HashMap<>();
+
+ public Request(InputStream in) throws IOException {
+ BufferedReader input = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+ setRequestLine(input);
+ setRequestHeader(input);
+ setRequestBody(input);
+ }
+
+ private void setRequestLine(BufferedReader input) throws IOException {
+ String requestLine = URLDecoder.decode(input.readLine(), StandardCharsets.UTF_8);
+ log.debug("<<<<>>>>");
+ log.debug("[request line] : {}", requestLine);
+
+ String[] requestInfo = HttpRequestUtils.getRequestInfo(requestLine);
+ httpMethod = requestInfo[METHOD];
+ requestUrl = requestInfo[URL];
+ httpVersion = requestInfo[HTTP_VERSION];
+ }
+
+ private void setRequestHeader(BufferedReader input) throws IOException {
+ String line;
+ while (!"".equals(line = URLDecoder.decode(input.readLine(), StandardCharsets.UTF_8))) {
+ if (line == null) {
+ return;
+ }
+ Pair pair = HttpRequestUtils.parseHeader(line);
+ requestHeaderField.put(pair.getKey(), pair.getValue());
+ }
+
+ requestHeaderField.entrySet().forEach(e -> {
+ log.debug("{} : {}", e.getKey(), e.getValue());
+ });
+ log.debug("<<<<>>>>");
+ }
+
+ private void setRequestBody(BufferedReader input) throws IOException {
+ int contentLength = (requestHeaderField.get("Content-Length") == null) ?
+ 0 : Integer.parseInt(requestHeaderField.get("Content-Length"));
+ String data = IOUtils.readData(input, contentLength);
+ String decodedData = URLDecoder.decode(data, StandardCharsets.UTF_8);
+ requestBody = HttpRequestUtils.parseRequestBody(decodedData);
+ }
+
+ public Pair methodUrl() {
+ return new Pair(httpMethod, requestUrl);
+ }
+
+ public String findBodyByFieldName(String fieldName) {
+ return requestBody.get(fieldName);
+ }
+}
diff --git a/src/main/java/http/Response.java b/src/main/java/http/Response.java
new file mode 100644
index 00000000..1896d2ee
--- /dev/null
+++ b/src/main/java/http/Response.java
@@ -0,0 +1,45 @@
+package http;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class Response {
+ private static final Logger log = LoggerFactory.getLogger(Response.class);
+
+ private final String httpVersion;
+ private final String statusCode;
+ private final String reasonPhrase;
+ private final Map responseHeaderField;
+ private byte[] responseBody;
+
+ public Response(String httpVersion, String statusCode, String reasonPhrase, Map responseHeaderField, byte[] responseBody) {
+ this.httpVersion = httpVersion;
+ this.statusCode = statusCode;
+ this.reasonPhrase = reasonPhrase;
+ this.responseHeaderField = responseHeaderField;
+ this.responseBody = responseBody;
+ }
+
+ public String responseMessage() {
+ StringBuilder responseMessage = new StringBuilder();
+ appendStatusLine(responseMessage);
+ appendResponseHeaderField(responseMessage);
+ responseMessage.append("\r\n");
+ responseMessage.append("\r\n");
+ responseMessage.append(new String(responseBody));
+ return responseMessage.toString();
+ }
+
+ private void appendStatusLine(StringBuilder responseMessage) {
+ responseMessage.append(httpVersion).append(" ")
+ .append(statusCode).append(" ")
+ .append(reasonPhrase).append(" \r\n");
+ }
+
+ private void appendResponseHeaderField(StringBuilder responseMessage) {
+ responseHeaderField.entrySet()
+ .forEach(e -> responseMessage.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n"));
+ }
+}
diff --git a/src/main/java/model/User.java b/src/main/java/model/User.java
index b7abb730..3b617c4e 100644
--- a/src/main/java/model/User.java
+++ b/src/main/java/model/User.java
@@ -17,17 +17,10 @@ public String getUserId() {
return userId;
}
- public String getPassword() {
- return password;
+ public boolean isCorrectPassword(String password) {
+ return this.password.equals(password);
}
- public String getName() {
- return name;
- }
-
- public String getEmail() {
- return email;
- }
@Override
public String toString() {
diff --git a/src/main/java/util/HttpRequestUtils.java b/src/main/java/util/HttpRequestUtils.java
index 5674eadc..ea849eb0 100644
--- a/src/main/java/util/HttpRequestUtils.java
+++ b/src/main/java/util/HttpRequestUtils.java
@@ -70,58 +70,4 @@ static Pair getKeyValue(String keyValue, String regex) {
public static Pair parseHeader(String header) {
return getKeyValue(header, ": ");
}
-
- public static class Pair {
- String key;
- String value;
-
- Pair(String key, String value) {
- this.key = key.trim();
- this.value = value.trim();
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((key == null) ? 0 : key.hashCode());
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Pair other = (Pair) obj;
- if (key == null) {
- if (other.key != null)
- return false;
- } else if (!key.equals(other.key))
- return false;
- if (value == null) {
- if (other.value != null)
- return false;
- } else if (!value.equals(other.value))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "Pair [key=" + key + ", value=" + value + "]";
- }
- }
}
diff --git a/src/main/java/util/Pair.java b/src/main/java/util/Pair.java
new file mode 100644
index 00000000..cd70f604
--- /dev/null
+++ b/src/main/java/util/Pair.java
@@ -0,0 +1,55 @@
+package util;
+
+public class Pair {
+ String key;
+ String value;
+
+ public Pair(String key, String value) {
+ this.key = key.trim();
+ this.value = value.trim();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Pair other = (Pair) obj;
+ if (key == null) {
+ if (other.key != null)
+ return false;
+ } else if (!key.equals(other.key))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Pair [key=" + key + ", value=" + value + "]";
+ }
+}
diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java
index 537ffe43..be12c1ab 100644
--- a/src/main/java/webserver/RequestHandler.java
+++ b/src/main/java/webserver/RequestHandler.java
@@ -2,38 +2,32 @@
import java.io.*;
import java.net.Socket;
-import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
-import db.DataBase;
-import model.User;
+import controller.*;
+import http.Request;
+import http.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import util.HttpRequestUtils;
-import util.IOUtils;
+import util.Pair;
public class RequestHandler extends Thread {
private static final Logger log = LoggerFactory.getLogger(RequestHandler.class);
-
- private final int METHOD = 0;
- private final int URL = 1;
- private final int HTTP_VERSION = 2;
- private final int KEY = 0;
- private final int VALUE = 1;
+ private static final Map controllerMapper;
private Socket connection;
- private String httpMethod;
- private String requestUrl;
- private String httpVersion;
- private Map requestHeaderField;
- private Map requestBody;
public RequestHandler(Socket connectionSocket) {
this.connection = connectionSocket;
- this.requestHeaderField = new HashMap<>();
+ }
+
+ static {
+ controllerMapper = new HashMap<>();
+ controllerMapper.put(new Pair("POST", "/user/create"), SignUpController.getInstance());
+ controllerMapper.put(new Pair("POST", "/user/login"), LogInController.getInstance());
+ controllerMapper.put(new Pair("GET", "/user/logout"), LogOutController.getInstance());
}
public void run() {
@@ -41,118 +35,14 @@ public void run() {
connection.getPort());
try (InputStream in = connection.getInputStream();
- OutputStream out = connection.getOutputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
- DataOutputStream dos = new DataOutputStream(out)) {
-
- setRequestLine(br);
- setRequestHeader(br);
- setRequestBody(br);
-
- // 1) 정적 페이지 요청
- if (httpMethod.equals("GET") && requestUrl.endsWith(".html")) {
- responseStaticPage(dos);
- }
-
- // 2) 유저 회원가입 요청
- if (httpMethod.equals("POST") && requestUrl.startsWith("/user/create")) {
- signUpUser(dos);
- }
-
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- }
-
- private void responseStaticPage(DataOutputStream dos) throws IOException {
- byte[] body;
- body = Files.readAllBytes(new File("./webapp" + requestUrl).toPath());
- response200Header(dos, body.length);
- responseBody(dos, body);
- }
-
- private void signUpUser(DataOutputStream dos) throws IOException {
- byte[] body = "".getBytes();
-
- DataBase.findUserById(requestBody.get("userId"))
- .ifPresentOrElse(user -> {
- log.debug("중복된 아이디가 존재합니다.");
- response302Header(dos, "/user/form.html", body.length);
- responseBody(dos, body);
- }, () -> {
- User user = new User(
- requestBody.get("userId"),
- requestBody.get("password"),
- requestBody.get("name"),
- requestBody.get("email"));
- log.debug("User : {}", user);
- DataBase.addUser(user);
- response302Header(dos, "/index.html", body.length);
- responseBody(dos, body);
- });
- }
-
- private void setRequestLine(BufferedReader br) throws IOException {
- String requestLine = URLDecoder.decode(br.readLine(), StandardCharsets.UTF_8);
- log.debug("<<<<>>>>");
- log.debug("[request line] : {}", requestLine);
-
- String[] requestInfo = HttpRequestUtils.getRequestInfo(requestLine);
- httpMethod = requestInfo[METHOD];
- requestUrl = requestInfo[URL];
- httpVersion = requestInfo[HTTP_VERSION];
- }
-
- private void setRequestHeader(BufferedReader br) throws IOException {
- String line;
- while (!"".equals(line = URLDecoder.decode(br.readLine(), StandardCharsets.UTF_8))) {
- if (line == null) {
- return;
- }
- HttpRequestUtils.Pair pair = HttpRequestUtils.parseHeader(line);
- requestHeaderField.put(pair.getKey(), pair.getValue());
- }
-
- requestHeaderField.entrySet().forEach(e -> {
- log.debug("{} : {}", e.getKey(), e.getValue());
- });
- log.debug("<<<<>>>>");
- }
-
- private void setRequestBody(BufferedReader br) throws IOException {
- int contentLength = requestHeaderField.get("Content-Length") == null ? 0 : Integer.parseInt(requestHeaderField.get("Content-Length"));
- String data = IOUtils.readData(br, contentLength);
- String decodedData = URLDecoder.decode(data, StandardCharsets.UTF_8);
- requestBody = HttpRequestUtils.parseRequestBody(decodedData);
- }
-
- private void response200Header(DataOutputStream dos, int lengthOfBodyContent) {
- try {
- dos.writeBytes("HTTP/1.1 200 OK \r\n");
- dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n");
- dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
- dos.writeBytes("\r\n");
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- }
-
- private void response302Header(DataOutputStream dos, String redirectUrl, int lengthOfBodyContent) {
- try {
- dos.writeBytes("HTTP/1.1 302 Found \r\n");
- dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n");
- dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
- dos.writeBytes("Location: " + redirectUrl + "\r\n");
- dos.writeBytes("\r\n");
- } catch (IOException e) {
- log.error(e.getMessage());
- }
- }
-
- private void responseBody(DataOutputStream dos, byte[] body) {
- try {
- dos.write(body, 0, body.length);
- dos.flush();
+ OutputStream out = connection.getOutputStream()) {
+ Request request = new Request(in);
+ Controller controller = controllerMapper.get(request.methodUrl()) == null ?
+ DefaultController.getInstance() : controllerMapper.get(request.methodUrl());
+ Response response = controller.run(request);
+ DataOutputStream dataOutputStream = new DataOutputStream(out);
+ dataOutputStream.write(response.responseMessage().getBytes(StandardCharsets.UTF_8));
+ dataOutputStream.flush();
} catch (IOException e) {
log.error(e.getMessage());
}
diff --git a/src/test/java/util/HttpRequestUtilsTest.java b/src/test/java/util/HttpRequestUtilsTest.java
index 73f36d29..f2dcb691 100644
--- a/src/test/java/util/HttpRequestUtilsTest.java
+++ b/src/test/java/util/HttpRequestUtilsTest.java
@@ -5,10 +5,8 @@
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
-import java.util.Optional;
import org.junit.jupiter.api.Test;
-import util.HttpRequestUtils.Pair;
public class HttpRequestUtilsTest {
@Test
diff --git a/webapp/index.html b/webapp/index.html
index f8d0a21f..cfe7c8a6 100644
--- a/webapp/index.html
+++ b/webapp/index.html
@@ -5,11 +5,11 @@
SLiPP Java Web Programming
-
-
-
-
-
+
+
+
@@ -71,7 +71,7 @@
로그인
회원가입
-->
- 로그아웃
+ 로그아웃
개인정보수정
@@ -140,9 +140,9 @@
-
-
-
-
+ script references
+
+
+