Skip to content

[HTTP 서버 구현하기 - 2, 3단계] 포츈(정윤성) 미션 제출합니다. #104

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

Merged
merged 13 commits into from
Sep 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testImplementation 'org.assertj:assertj-core:3.20.2'
testImplementation "org.mockito:mockito-core:3.+"
testImplementation 'org.mockito:mockito-inline:3.6.0'

testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

Expand Down
7 changes: 2 additions & 5 deletions app/src/main/java/nextstep/jwp/RequestHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.Objects;
import nextstep.jwp.controller.Controller;
import nextstep.jwp.controller.ControllerMapper;
import nextstep.jwp.http.HttpMethod;
import nextstep.jwp.http.HttpRequest;
import nextstep.jwp.http.HttpResponse;
import org.slf4j.Logger;
Expand Down Expand Up @@ -41,10 +40,8 @@ public void run() {

if (controller == null) {
httpResponse.transfer(httpRequest.getUrl());
} else if (httpRequest.getHttpMethod().equals(HttpMethod.GET)) {
controller.get(httpRequest, httpResponse);
} else if (httpRequest.getHttpMethod().equals(HttpMethod.POST)) {
controller.post(httpRequest, httpResponse);
} else {
controller.service(httpRequest, httpResponse);
}

} catch (IOException exception) {
Expand Down
11 changes: 5 additions & 6 deletions app/src/main/java/nextstep/jwp/WebServer.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package nextstep.jwp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebServer {

Expand Down Expand Up @@ -40,9 +39,9 @@ private void handle(ServerSocket serverSocket) throws IOException {

public static int defaultPortIfNull(String[] args) {
return Stream.of(args)
.findFirst()
.map(Integer::parseInt)
.orElse(WebServer.DEFAULT_PORT);
.findFirst()
.map(Integer::parseInt)
.orElse(WebServer.DEFAULT_PORT);
}

private int checkPort(int port) {
Expand Down
24 changes: 24 additions & 0 deletions app/src/main/java/nextstep/jwp/controller/AbstractController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package nextstep.jwp.controller;

import java.io.IOException;
import nextstep.jwp.http.HttpRequest;
import nextstep.jwp.http.HttpResponse;

public abstract class AbstractController implements Controller {

@Override
public void service(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
if (httpRequest.isPost()) {
doPost(httpRequest, httpResponse);
} else {
doGet(httpRequest, httpResponse);
}
}

protected void doGet(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
httpResponse.transfer(httpRequest.getUrl());
}

protected void doPost(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
}
}
4 changes: 1 addition & 3 deletions app/src/main/java/nextstep/jwp/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@

public interface Controller {

void get(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException;

void post(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException;
void service(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
import nextstep.jwp.http.HttpResponse;
import nextstep.jwp.service.LoginService;

public class LoginController implements Controller {
public class LoginController extends AbstractController {

private final LoginService loginService = new LoginService();

@Override
public void get(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
httpResponse.transfer(httpRequest.getUrl());
protected void doGet(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
loginService.doGet(httpResponse, httpRequest);
}

@Override
public void post(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
public void doPost(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
loginService.login(httpRequest, httpResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
import nextstep.jwp.http.HttpResponse;
import nextstep.jwp.service.RegisterService;

public class RegisterController implements Controller {
public class RegisterController extends AbstractController {

private final RegisterService registerService = new RegisterService();

@Override
public void get(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
httpResponse.transfer(httpRequest.getUrl());
public void doPost(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
registerService.registerUser(httpRequest, httpResponse);
}

@Override
public void post(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
registerService.registerUser(httpRequest, httpResponse);
protected void doGet(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
registerService.doGet(httpResponse);
}
}
42 changes: 42 additions & 0 deletions app/src/main/java/nextstep/jwp/http/HttpCookie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package nextstep.jwp.http;

import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpCookie {

private static final Logger LOGGER = LoggerFactory.getLogger(HttpCookie.class);

private static final int COOKIE_KEY = 0;
private static final int COOKIE_VALUE = 1;
private final Map<String, String> cookie;

public HttpCookie(final String cookieData) {
cookie = setCookie(cookieData);
}

private Map<String, String> setCookie(final String cookieRawData) {
Map<String, String> cookieMap = new HashMap<>();
String[] cookieDataSet = cookieRawData.split(";");
for (String cookieData : cookieDataSet) {
cookieData = cookieData.trim();
String[] cookieDatas = cookieData.split("=");
cookieMap.put(cookieDatas[COOKIE_KEY], cookieDatas[COOKIE_VALUE]);

Choose a reason for hiding this comment

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

저는 keyValue[0] 이런 식으로 구현했었는데 인덱스 상수화를 하니까 읽기가 훨씬 편하네요👍

}
return cookieMap;
}

public boolean containsKey(final String cookieKey) {
return cookie.containsKey(cookieKey);
}

public String getCookieValueByKey(final String cookieKey) {
if (!cookie.containsKey(cookieKey)) {
LOGGER.error("없는 key의 쿠키정보를 찾으려고 했습니다. key = {}", cookieKey);
throw new IllegalArgumentException(String.format("없는 key의 쿠키정보를 찾으려고 했습니다. key = {%s}", cookieKey));
}
return cookie.get(cookieKey);
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/nextstep/jwp/http/HttpHeaders.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ public String getAllHeaders() {
}
return headerSet.toString();
}

public boolean contains(final String key) {
return headers.containsKey(key);
}
}
14 changes: 13 additions & 1 deletion app/src/main/java/nextstep/jwp/http/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,24 @@ public String getUrl() {
public String getQueryParam(final String key) {
return requestLine.getQueryParam(key);
}

public String getHttpVersion() {
return requestLine.getHttpVersion();
}

public String getBodyDataByKey(final String key) {
return bodyParams.get(key);
}

public boolean contains(final String key) {
return headers.contains(key);
}

public HttpCookie getCookie() {
return new HttpCookie(headers.getHeaderDataByKey("Cookie"));
}

public boolean isPost() {
return requestLine.isPost();
}
}
12 changes: 7 additions & 5 deletions app/src/main/java/nextstep/jwp/http/HttpResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ public void transfer(final String url) throws IOException {
try {
if (url.equals("/")) {
responseBody = DEFAULT_MESSAGE;
} else if (url.equals("/login") || url.equals("/register")) {
responseBody = getBodyByUrl(DEFAULT_RESOURCE_PATH + url + ".html");
} else {
responseBody = getBodyByUrl(DEFAULT_RESOURCE_PATH + url);
}
Expand Down Expand Up @@ -75,22 +73,22 @@ private String getBodyByUrl(final String url) throws IOException {

private void response200(final String responseBody) throws IOException {
headers.put("Content-Length: " + responseBody.getBytes().length);
String okResponse = HttpStatusCodes._200.getStatusCodeHeader();
String okResponse = HttpStatusCodes.HTTP_200.getStatusCodeHeader();
outputStream.write(okResponse.getBytes(StandardCharsets.UTF_8));
responseHeaderBody(responseBody);
send();
}

public void redirect302Transfer(final String redirectUrl) throws IOException {
String foundResponse = HttpStatusCodes._302.getStatusCodeHeader();
String foundResponse = HttpStatusCodes.HTTP_302.getStatusCodeHeader();
outputStream.write(foundResponse.getBytes(StandardCharsets.UTF_8));
headers.put("Location: " + redirectUrl);
responseHeader();
send();
}

public void redirectWithStatusCode(final String redirectUrl, final String statusCode) throws IOException {
HttpStatusCodes httpStatusCodes = HttpStatusCodes.valueOf("_" + statusCode);
HttpStatusCodes httpStatusCodes = HttpStatusCodes.valueOf("HTTP_" + statusCode);
outputStream.write(httpStatusCodes.getStatusCodeHeader().getBytes(StandardCharsets.UTF_8));
String responseBody = getBodyByUrl(DEFAULT_RESOURCE_PATH + redirectUrl);
responseHeaderBody(responseBody);
Expand All @@ -110,4 +108,8 @@ private void responseHeader() throws IOException {
private void send() throws IOException {
outputStream.flush();
}

public void addHeader(final String headerKey, final String headerValue) {
headers.put(headerKey + ": " + headerValue);
}
}
40 changes: 40 additions & 0 deletions app/src/main/java/nextstep/jwp/http/HttpSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package nextstep.jwp.http;

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

public class HttpSession {

private final Map<String, Object> values = new HashMap<>();
private final String id;

public HttpSession(final String id) {
this.id = id;
}

public void setAttribute(final String name, final Object value) {
values.put(name, value);
}

public Object getAttribute(final String name) {
return values.get(name);
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final HttpSession that = (HttpSession) o;
return Objects.equals(id, that.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}
21 changes: 21 additions & 0 deletions app/src/main/java/nextstep/jwp/http/HttpSessions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package nextstep.jwp.http;

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

public class HttpSessions {

private static final Map<String, HttpSession> SESSIONS = new HashMap<>();

public static HttpSession getSession(final String id) {
if (SESSIONS.containsKey(id)) {
return SESSIONS.get(id);
}
HttpSession httpSession = new HttpSession(id);
SESSIONS.put(id, httpSession);
return httpSession;
}

private HttpSessions() {
}
}
10 changes: 5 additions & 5 deletions app/src/main/java/nextstep/jwp/http/HttpStatusCodes.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package nextstep.jwp.http;

public enum HttpStatusCodes {
_200("HTTP/1.1 200 OK\r\n"),
_302("HTTP/1.1 302 Found\r\n"),
_401("HTTP/1.1 401 Unauthorized\r\n"),
_404("HTTP/1.1 404 Not Found\r\n"),
_409("HTTP/1.1 409 Conflict\r\n");
HTTP_200("HTTP/1.1 200 OK\r\n"),
HTTP_302("HTTP/1.1 302 Found\r\n"),
HTTP_401("HTTP/1.1 401 Unauthorized\r\n"),
HTTP_404("HTTP/1.1 404 Not Found\r\n"),
HTTP_409("HTTP/1.1 409 Conflict\r\n");

private final String statusCodeHeader;

Expand Down
4 changes: 0 additions & 4 deletions app/src/main/java/nextstep/jwp/http/RequestLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ public String getHttpVersion() {
return httpVersion;
}

public boolean isQueryParamsEmpty() {
return queryParams.isEmpty();
}

public boolean isPost() {
return httpMethod.equals(HttpMethod.POST);
}
Expand Down
Loading