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

2주차 미션 / 서버 1조 주민석 #2

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1487673
Feat: return index.html
emes-g Mar 26, 2024
43982a0
Feat: sign up in 'GET' method
emes-g Mar 26, 2024
3906898
Feat: sign up in 'POST' method
emes-g Mar 26, 2024
5ce9940
Refactor: declare 'index' that is used in queryString
emes-g Mar 26, 2024
9a8173e
Feat: login and save cookie
emes-g Mar 26, 2024
894d3d1
Feat: apply css
emes-g Mar 26, 2024
3e95242
Feat: set cookie path and print userList
emes-g Mar 27, 2024
a89f06f
Refactor: early return with respect to userList
emes-g Mar 27, 2024
41e541d
Refactor: remove duplicate code and make url constant
emes-g Mar 28, 2024
5b6c6da
Refactor: remove duplicate code
emes-g Mar 28, 2024
d1eb93c
Fix: fix bug that user can enter non-existent page
emes-g Mar 28, 2024
0d73452
Fix: add flush() after writing HTTP response headers
emes-g Mar 28, 2024
8e3c97e
Refactor: add enum class(HttpMethod, URL)
emes-g Mar 28, 2024
262aaeb
Test: test that request message is separated well
emes-g Mar 28, 2024
60c9f18
Revert "Test: test that request message is separated well"
emes-g Mar 31, 2024
913ec5b
Revert "Refactor: add enum class(HttpMethod, URL)"
emes-g Mar 31, 2024
fd822f5
Refactor: TDD 방식으로 HttpRequest 메시지 분리
emes-g Mar 31, 2024
8d5fb47
Refactor: RequestURL enum class 추가
emes-g Apr 1, 2024
bb94580
Feat: 이미지 요청에 대한 응답 추가
emes-g Apr 1, 2024
1f4264d
Refactor: RequestHandler에서 요청 데이터 처리 로직을 HttpRequest에 위임
emes-g Apr 1, 2024
9ca1732
Refactor: HttpResponse 메시지 분리
emes-g Apr 1, 2024
0d07440
Fix: 생성자 매개변수 순서를 올바르게 수정
emes-g Apr 1, 2024
18f3d59
Refactor: RequestHandler에서 응답 데이터 처리 로직을 HttpResponse에 위임
emes-g Apr 1, 2024
07342cf
Refactor: Controller 인터페이스를 통해 URL 마다 작업 처리 분리
emes-g Apr 1, 2024
c9d6d11
Refactor: RequestMapper 클래스를 통해 request URL에 대한 Controller를 반환
emes-g Apr 1, 2024
c39a067
Style: 출력문 및 사용하지 않는 변수 제거
emes-g Apr 1, 2024
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
21 changes: 21 additions & 0 deletions src/main/java/controller/AbstractController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package controller;

import http.constants.HttpMethod;
import http.request.HttpRequest;
import http.response.HttpResponse;

import java.io.IOException;

public abstract class AbstractController implements Controller {
@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
if(request.getMethod().equals(HttpMethod.GET.get())){
doGet(request, response);
return;
}
doPost(request, response);
}

public abstract void doGet(HttpRequest request, HttpResponse response) throws IOException;
public abstract void doPost(HttpRequest request, HttpResponse response) throws IOException;
}
10 changes: 10 additions & 0 deletions src/main/java/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package controller;

import http.request.HttpRequest;
import http.response.HttpResponse;

import java.io.IOException;

public interface Controller {
void execute(HttpRequest request, HttpResponse response) throws IOException;
}
13 changes: 13 additions & 0 deletions src/main/java/controller/ForwardController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package controller;

import http.request.HttpRequest;
import http.response.HttpResponse;

import java.io.IOException;

public class ForwardController implements Controller {
@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
response.forward(request.getPath());
}
}
14 changes: 14 additions & 0 deletions src/main/java/controller/HomeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package controller;

import http.request.HttpRequest;
import http.request.RequestURL;
import http.response.HttpResponse;

import java.io.IOException;

public class HomeController implements Controller {
@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
response.forward(RequestURL.HOME_URL.get());
}
}
22 changes: 22 additions & 0 deletions src/main/java/controller/ListController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package controller;

import http.request.HttpRequest;
import http.request.RequestURL;
import http.response.HttpResponse;

import java.io.IOException;

public class ListController implements Controller {

@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
// 비로그인 상태 : redirect to /user/login.html
String cookie = request.getField("Cookie");
if (cookie == null || !cookie.equals("logined=true")) {
response.redirect(RequestURL.LOGIN_URL.get());
return;
}
// 로그인 상태 : user/list.html 반환
response.forward(RequestURL.LIST_URL.get());
}
}
26 changes: 26 additions & 0 deletions src/main/java/controller/LoginController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package controller;

import db.MemoryUserRepository;
import db.Repository;
import http.request.HttpRequest;
import http.request.RequestURL;
import http.response.HttpResponse;
import model.User;

import java.io.IOException;

public class LoginController implements Controller {
private final Repository repository = MemoryUserRepository.getInstance();
@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
User user = repository.findUserById(request.getQueryParameter("userId"));

// 로그인 성공
if (user != null && user.getPassword().equals(request.getQueryParameter("password"))) {
response.redirectWithCookie(RequestURL.HOME_URL.get());
return;
}
// 로그인 실패
response.redirect(RequestURL.LOGIN_FAILED_URL.get());
}
}
24 changes: 24 additions & 0 deletions src/main/java/controller/SignUpController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package controller;

import db.MemoryUserRepository;
import db.Repository;
import http.request.HttpRequest;
import http.request.RequestURL;
import http.response.HttpResponse;
import model.User;

import java.io.IOException;

public class SignUpController implements Controller {
private final Repository repository = MemoryUserRepository.getInstance();

@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
User user = new User(request.getQueryParameter("userId"),
request.getQueryParameter("password"),
request.getQueryParameter("name"),
request.getQueryParameter("email"));
repository.addUser(user);
response.redirect(RequestURL.HOME_URL.get());
}
}
16 changes: 16 additions & 0 deletions src/main/java/http/constants/HttpMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package http.constants;

public enum HttpMethod {
GET("GET"),
POST("POST");

private final String method;

HttpMethod(String method) {
this.method = method;
}

public String get() {
return method;
}
}
58 changes: 58 additions & 0 deletions src/main/java/http/request/HttpHeader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package http.request;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HttpHeader {
private final Map<String, String> header; // header fields

public HttpHeader(Map<String, String> header) {
this.header = header;
}

public static HttpHeader from(BufferedReader br) throws IOException {
return new HttpHeader(readHeader(br));
}

private static Map<String, String> readHeader(BufferedReader br) throws IOException {
Map<String, String> header = new HashMap<>();
String field = "";

while (!(field = br.readLine()).isEmpty()) {
String[] pair = field.split(": ");
String name = pair[0];
String value = pair[1];
header.put(name, value);
}

return header;
}

public boolean contains(String fieldName) {
return header.containsKey(fieldName);
}

public String get(String fieldName) {
return header.get(fieldName);
}

public void put(String name, String value) {
header.put(name, value);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();

for (String name : header.keySet()) {
sb.append(name)
.append(": ")
.append(header.get(name))
.append("\r\n");
}

return sb.append("\r\n").toString();
}
}
78 changes: 78 additions & 0 deletions src/main/java/http/request/HttpRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package http.request;

import http.constants.HttpMethod;
import http.util.HttpRequestUtils;
import http.util.IOUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class HttpRequest {
private final HttpRequestStartLine startLine; // request start-line
private final HttpHeader header; // request header (fields)
private final String body; // request body
private final Map<String, String> query;

private HttpRequest(HttpRequestStartLine startLine, HttpHeader header, String body, Map<String, String> query) {
this.startLine = startLine;
this.header = header;
this.body = body;
this.query = query;
}

public static HttpRequest from(InputStream in) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String startLine = br.readLine();
if (startLine == null) {
throw new IllegalArgumentException("request is empty.");
}

HttpRequestStartLine httpRequestStartLine = HttpRequestStartLine.from(startLine);
HttpHeader header = HttpHeader.from(br);
String body = readBody(br, header);
Map<String, String> query = createQuery(body);

return new HttpRequest(httpRequestStartLine, header, body, query);
}

private static String readBody(BufferedReader br, HttpHeader header) throws IOException {
if (!header.contains("Content-Length")) {
return "";
}

int contentLength = Integer.parseInt(header.get("Content-Length"));
return IOUtils.readData(br, contentLength);
}

private static Map<String, String> createQuery(String body) {
// GET 방식인 경우
if (body.isEmpty()) {
return new HashMap<>();
}

// POST 방식인 경우
return HttpRequestUtils.parseQueryParameter(body);
}

public String getPath() {
return startLine.getPath();
}

public String getMethod() {
return startLine.getMethod();
}

public String getQueryParameter(String fieldName) {
if (getMethod().equals(HttpMethod.GET.get()))
return startLine.getQueryParameter(fieldName);
return query.get(fieldName);
}

public String getField(String fieldName) {
return header.get(fieldName);
}
}
59 changes: 59 additions & 0 deletions src/main/java/http/request/HttpRequestStartLine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package http.request;

import http.util.HttpRequestUtils;

import java.util.HashMap;
import java.util.Map;

public class HttpRequestStartLine {
private final String method;
private final String path;
private final String version;
private final Map<String, String> query;

public HttpRequestStartLine(String method, String path, String version, Map<String, String> query) {
this.method = method;
this.path = path;
this.version = version;
this.query = query;
}

public static HttpRequestStartLine from(String startLine) {
String[] elements = startLine.split(" ");

String method = elements[0];
String path = elements[1];
String version = elements[2];
Map<String, String> query = createQuery(path);

return new HttpRequestStartLine(method, path, version, query);
}

private static Map<String, String> createQuery(String path) {
// POST 방식인 경우
int index = path.indexOf("?");
if (index == -1) {
return new HashMap<>();
}

// GET 방식인 경우
String queryString = path.substring(index + 1);
return HttpRequestUtils.parseQueryParameter(queryString);
}

public String getMethod() {
return method;
}

public String getPath() {
return path;
}

public String getVersion() {
return version;
}

public String getQueryParameter(String queryParameter) {
return query.get(queryParameter);
}
}
22 changes: 22 additions & 0 deletions src/main/java/http/request/RequestURL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package http.request;

public enum RequestURL {
ROOT("./webapp"),
HOME_URL("/index.html"),
LOGIN_FAILED_URL("/user/login_failed.html"),
LOGIN_URL("/user/login.html"),
LIST_URL("/user/list.html"),
SIGN_UP("/user/signup"),
LOGIN("/user/login"),
USER_LIST("/user/userList");

private final String url;

RequestURL(String url) {
this.url = url;
}

public String get() {
return url;
}
}
Loading