diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java new file mode 100644 index 0000000..4b05be9 --- /dev/null +++ b/src/main/java/controller/Controller.java @@ -0,0 +1,11 @@ +package controller; + +import http.request.HttpRequest; + +import http.response.HttpResponse; + +import java.io.IOException; + +public interface Controller { + void execute(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException; +} diff --git a/src/main/java/controller/JustGetController.java b/src/main/java/controller/JustGetController.java new file mode 100644 index 0000000..681ca89 --- /dev/null +++ b/src/main/java/controller/JustGetController.java @@ -0,0 +1,42 @@ +package controller; + +import http.HttpHeaders; +import http.constant.HttpHeader; +import http.request.HttpRequest; +import http.response.HttpResponse; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static http.constant.URL.ROOT; + +public class JustGetController implements Controller { + + public JustGetController(){ + } + + @Override + public void execute(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException { + // request 분석 + String requestURL = httpRequest.getPath(); + String TYPE = "html"; + if(requestURL.contains(".css")) + TYPE = "css"; + + // 1 startLine - forward 메소드 내 구현 + + // 2 + byte[] body = Files.readAllBytes(Paths.get(ROOT.getURL() + httpRequest.getPath())); + httpResponse.setBody(body); + + // 3 + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.put(HttpHeader.CONTENT_LENGTH, Integer.toString(body.length)); + httpHeaders.put(HttpHeader.CONTENT_TYPE, "text/"+TYPE+";charset=utf-8"); + httpResponse.setHeaders(httpHeaders); + + // forward 내부에 writeResponse 메소드 존재. + httpResponse.forward(requestURL); + } +} diff --git a/src/main/java/controller/LoginController.java b/src/main/java/controller/LoginController.java new file mode 100644 index 0000000..7c0a8bb --- /dev/null +++ b/src/main/java/controller/LoginController.java @@ -0,0 +1,52 @@ +package controller; + +import db.MemoryUserRepository; +import db.Repository; +import http.HttpHeaders; +import http.constant.HttpHeader; +import http.request.HttpRequest; +import http.response.HttpResponse; +import model.User; + +import java.io.IOException; +import java.util.Map; + +import static http.constant.URL.LOGIN_FAILED_PATH; +import static http.constant.URL.MAIN_PATH; +import static model.UserQueryKey.*; + +public class LoginController implements Controller { + private final Repository repository; + + + public LoginController(){ + this.repository = MemoryUserRepository.getInstance(); + } + + @Override + public void execute(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException { + + // query 분석 + Map query = httpRequest.getQuery(); + + if(query == null || (query != null && query.size() < 2)) + throw new IllegalArgumentException("로그인 정보를 모두 채워주세요."); + User user = repository.findUserById(query.get(USERID.getKey())); + + HttpHeaders httpHeaders = new HttpHeaders(); + String path = LOGIN_FAILED_PATH.getURL(); + + // 로그인 성공 + if(user != null && user.getPassword().equals(query.get(PASSWORD.getKey()))){ + path = MAIN_PATH.getURL(); + httpHeaders.put(HttpHeader.SET_COOKIE, "logined=true"); + } + + // header + httpHeaders.put(HttpHeader.LOCATION, path); + httpResponse.setHeaders(httpHeaders); + + // 로그인 성공 - redirect MAIN_PATH + httpResponse.redirect(path); + } +} diff --git a/src/main/java/controller/SignUpController.java b/src/main/java/controller/SignUpController.java new file mode 100644 index 0000000..8c18c6e --- /dev/null +++ b/src/main/java/controller/SignUpController.java @@ -0,0 +1,51 @@ +package controller; + +import db.MemoryUserRepository; +import db.Repository; +import http.HttpHeaders; +import http.constant.HttpHeader; +import http.request.HttpRequest; +import http.response.HttpResponse; +import model.User; + +import java.io.IOException; +import java.util.Map; + +import static http.constant.URL.MAIN_PATH; +import static model.UserQueryKey.*; + +public class SignUpController implements Controller { + + private final Repository repository = MemoryUserRepository.getInstance(); + + public SignUpController(){ + } + + @Override + public void execute(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException { + // request 분석 + String requestURL = httpRequest.getPath(); + System.out.println(requestURL); + + // method == get + // GET일 땐 starLine의 requestURL에서 query 얻어올 수 있음. + Map query = httpRequest.getQuery(); + + if(query == null || (query != null && query.size() < 4)) + throw new IllegalArgumentException("회원가입 정보를 모두 채워주세요."); + User user = new User(query.get(USERID.getKey()), query.get(PASSWORD.getKey()), query.get(NAME.getKey()), query.get(EMAIL.getKey())); + repository.addUser(user); + + // 1 startLine - redirect 메소드 내 구현 + + // 2 body x + + // 3 headers + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.put(HttpHeader.LOCATION, MAIN_PATH.getURL()); + httpResponse.setHeaders(httpHeaders); + + // redirect 내부에 writeResponse 메소드 존재. + httpResponse.redirect(MAIN_PATH.getURL()); + } +} diff --git a/src/main/java/controller/UserListController.java b/src/main/java/controller/UserListController.java new file mode 100644 index 0000000..4d79566 --- /dev/null +++ b/src/main/java/controller/UserListController.java @@ -0,0 +1,35 @@ +package controller; + +import http.HttpHeaders; +import http.constant.HttpHeader; +import http.request.HttpRequest; +import http.response.HttpResponse; + +import java.io.IOException; +import static http.constant.URL.*; + +public class UserListController implements Controller { + + public UserListController(){ + } + + @Override + public void execute(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException { + // request + HttpHeaders headers = httpRequest.getHeader(); + System.out.println(headers.toString()); + String cookie = headers.get(HttpHeader.COOKIE); + String path = LOGIN_PATH.getURL(); + + if(cookie != null && cookie.contains("logined=true")){ + path = USERLIST_PATH.getURL(); + } + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.put(HttpHeader.LOCATION, path); + httpResponse.setHeaders(httpHeaders); + + httpResponse.redirect(path); + + } +} diff --git a/src/main/java/http/HttpHeaders.java b/src/main/java/http/HttpHeaders.java new file mode 100644 index 0000000..3ed24d4 --- /dev/null +++ b/src/main/java/http/HttpHeaders.java @@ -0,0 +1,38 @@ +package http; + +import http.constant.HttpHeader; + +import java.util.HashMap; +import java.util.Map; + +public class HttpHeaders { + private Map headers = new HashMap<>(); + private static final String DELIMITER = ": "; + private static final String CRLF = "\r\n"; + + public HttpHeaders(){} + + public void put(HttpHeader header, String value) { + headers.put(header, value); + } + + @Override + public String toString(){ + String str = ""; + if(headers.isEmpty()) + return str; + for(HttpHeader key : headers.keySet()){ + str += key.getHeader() + DELIMITER + headers.get(key) + CRLF; + } + return str + CRLF; + } + + public boolean containsKey(HttpHeader header) { + return headers.containsKey(header); + } + + public String get(HttpHeader header){ + return headers.get(header); + } + +} diff --git a/src/main/java/http/constant/HttpHeader.java b/src/main/java/http/constant/HttpHeader.java new file mode 100644 index 0000000..b569b52 --- /dev/null +++ b/src/main/java/http/constant/HttpHeader.java @@ -0,0 +1,24 @@ +package http.constant; + +import java.util.Arrays; + +public enum HttpHeader { + CONTENT_TYPE("Content-Type"), CONTENT_LENGTH("Content-Length"), SET_COOKIE("Set-Cookie"), COOKIE("Cookie"), LOCATION("Location"); + + private String header; + + HttpHeader(String header){ + this.header = header; + } + + public static HttpHeader of(String header) { + return Arrays.stream(values()) + .filter(h -> header.equals(h.header)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("해당되는 Http Header가 없습니다."))); + } + + public String getHeader() { + return header; + } +} diff --git a/src/main/java/http/constant/HttpMethod.java b/src/main/java/http/constant/HttpMethod.java new file mode 100644 index 0000000..552f68b --- /dev/null +++ b/src/main/java/http/constant/HttpMethod.java @@ -0,0 +1,25 @@ +package http.constant; + +import java.util.Arrays; + +public enum HttpMethod { + GET("GET"), POST("POST"); + + private String method; + + HttpMethod(String method){ + this.method = method; + } + + + public static HttpMethod of(String method) { + return Arrays.stream(values()) + .filter(m -> method.equals(m.method)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("해당되는 Http Method가 없습니다."))); + } + + public String getMethod() { + return method; + } +} diff --git a/src/main/java/http/constant/HttpStatus.java b/src/main/java/http/constant/HttpStatus.java new file mode 100644 index 0000000..d5afd31 --- /dev/null +++ b/src/main/java/http/constant/HttpStatus.java @@ -0,0 +1,15 @@ +package http.constant; + +public enum HttpStatus { + OK("200 OK"), REDIRECT("302 FOUND"); + + private final String status; + + HttpStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } +} diff --git a/src/main/java/http/constant/URL.java b/src/main/java/http/constant/URL.java new file mode 100644 index 0000000..2707522 --- /dev/null +++ b/src/main/java/http/constant/URL.java @@ -0,0 +1,26 @@ +package http.constant; + +import java.util.Arrays; + +public enum URL { + USERLIST_PATH("/user/list.html"), USERLIST_ACTION("/user/userList"), LOGIN_ACTION("/user/login"), SIGNUP_ACTION("/user/signup"), ROOT("./webapp"), MAIN_PATH("/index.html"), LOGIN_PATH("/user/login.html"), LOGIN_FAILED_PATH("/user/login_failed.html"); + + private String url; + + URL(String url){ + this.url = url; + } + + public static URL of(String url) { + return Arrays.stream(values()) + .filter(u -> url.equals(u.url)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("처리가 불가능한 url입니다."))); + } + + public String getURL() { + return url; + } + +} + diff --git a/src/main/java/http/request/HttpRequest.java b/src/main/java/http/request/HttpRequest.java new file mode 100644 index 0000000..8939ad5 --- /dev/null +++ b/src/main/java/http/request/HttpRequest.java @@ -0,0 +1,90 @@ +package http.request; + +import http.HttpHeaders; +import http.util.HttpRequestUtils; +import http.util.IOUtils; +import http.constant.HttpHeader; +import http.constant.HttpMethod; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static http.constant.HttpHeader.*; + +public class HttpRequest { + + private BufferedReader br; + private HttpRequestStartLine startLine; + private HttpHeaders requestHeader; + private String body; + + + private HttpRequest(HttpRequestStartLine startLine, HttpHeaders requestHeader, String body) throws IOException { + this.startLine = startLine; + this.requestHeader = requestHeader; + this.body = body; + System.out.println("HttpRequest - startLine : " + startLine.toString()); + } + + public static HttpRequest from(BufferedReader br) throws IOException { + /* startLine parsing */ + String readStartLine = br.readLine(); + HttpRequestStartLine startLine = parsingStartLine(readStartLine); + + /* header parsing */ + HttpHeaders headers = new HttpHeaders(); + while (true) { + final String line = br.readLine(); + + if (line==null || line.equals("")) + break; + if (line.startsWith(CONTENT_LENGTH.getHeader())) { + headers.put(CONTENT_LENGTH, line.split(": ")[1].strip()); + } + if (line.startsWith(COOKIE.getHeader())) { + headers.put(COOKIE, line.split(": ")[1].strip()); + } + } + + /* body parsing */ + String body = parsingBody(br, headers); + + return new HttpRequest(startLine, headers, body); + } + + private static HttpRequestStartLine parsingStartLine(String readStartLine) { + return HttpRequestStartLine.from(readStartLine); + } + + private static String parsingBody(BufferedReader br, HttpHeaders headers) throws IOException { + if(!headers.containsKey(CONTENT_LENGTH)) + return ""; + String content_length = headers.get(CONTENT_LENGTH); + return IOUtils.readData(br, Integer.parseInt(content_length)); + } + + public String getPath() { + return startLine.getPath(); + } + + public String getBody(){ + return body; + } + + public Map getQuery() { + if(startLine.getQueries() != null) + return startLine.getQueries(); + + return HttpRequestUtils.parseQueryParameter(body); + } + + public HttpMethod getMethod() { + return startLine.getMethod(); + } + + public HttpHeaders getHeader() { + return requestHeader; + } +} diff --git a/src/main/java/http/request/HttpRequestStartLine.java b/src/main/java/http/request/HttpRequestStartLine.java new file mode 100644 index 0000000..6db2d5b --- /dev/null +++ b/src/main/java/http/request/HttpRequestStartLine.java @@ -0,0 +1,81 @@ +package http.request; + +import http.constant.HttpMethod; +import http.util.HttpRequestUtils; + +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static http.constant.URL.MAIN_PATH; + +public class HttpRequestStartLine { + + private static Map queries; + private HttpMethod method; + private String path; + private String version; + + private final static String SEPARATOR = " "; + private final static String QUERY_IDENTIFIER = "\\?"; + private final static String QUERY_VALUE_IDENTIFIER = "="; + + private HttpRequestStartLine(HttpMethod method, String path, Map queries, String version){ + this.method = method; + this.path = path; + this.queries = queries; + this.version = version; + } + + public static HttpRequestStartLine from(String line){ + String[] startLines = line.split(SEPARATOR); + if(startLines.length < 3) + throw new IllegalArgumentException("Request Message의 StartLine의 인자가 잘못되었습니다."); + HttpMethod method = HttpMethod.of(startLines[0].strip()); + String path = startLines[1].strip(); + String version = startLines[2].strip(); + + // query 미존재 + // query가 존재하지 않고, url은 "/"인 경우 + if(path.equals("/")) + path = MAIN_PATH.getURL(); + + if(!path.contains(QUERY_IDENTIFIER)){ + return new HttpRequestStartLine(method, path, null, version); + } + + // query 존재 + String query = null; + // query 존재 + if(method == HttpMethod.GET) { + query = path.split(QUERY_IDENTIFIER)[1]; + path = path.split(QUERY_IDENTIFIER)[0]; + } + + if(path.equals("/")) + path = MAIN_PATH.getURL(); + + queries = HttpRequestUtils.parseQueryParameter(query); + + return new HttpRequestStartLine(method, path, queries, version); + } + + + + public HttpMethod getMethod() { + return method; + } + + public String getPath() { + return path; + } + + public Map getQueries() { + return queries; + } + + public String toString(){ + return method + SEPARATOR + path + SEPARATOR + version + "\r\n"; + } + +} diff --git a/src/main/java/http/response/HttpResponse.java b/src/main/java/http/response/HttpResponse.java new file mode 100644 index 0000000..0b8c3ee --- /dev/null +++ b/src/main/java/http/response/HttpResponse.java @@ -0,0 +1,59 @@ +package http.response; + +import http.HttpHeaders; + +import java.io.IOException; +import java.io.OutputStream; + +import static http.constant.HttpStatus.*; + +public class HttpResponse { + + private OutputStream outputStream; + private HttpResponseStartLine startLine; + private HttpHeaders headers; + private byte[] body; + + public HttpResponse(OutputStream outputStream) { + this.outputStream = outputStream; + this.headers = new HttpHeaders(); + this.startLine = new HttpResponseStartLine(); + this.body = new byte[0]; + } + + // 200 OK + public void forward(String path) throws IOException { + startLine.setStatus(OK); + writeResponse(); + } + + // 302 FOUND + public void redirect(String path) throws IOException { + startLine.setStatus(REDIRECT); + writeResponse(); + } + + + private void writeResponse() throws IOException { + outputStream.write(startLine.toString().getBytes()); + outputStream.write(headers.toString().getBytes()); + outputStream.write(body); + outputStream.flush(); + outputStream.close(); + } + + + /* SET */ + public void setHeaders(HttpHeaders headers){ + this.headers = headers; + } + + public void setBody(byte[] body) { + this.body = body; + } + +// public void setStartLineStatus(Status status){ +// startLine.setStatus(status); +// } + +} diff --git a/src/main/java/http/response/HttpResponseStartLine.java b/src/main/java/http/response/HttpResponseStartLine.java new file mode 100644 index 0000000..e9a7fea --- /dev/null +++ b/src/main/java/http/response/HttpResponseStartLine.java @@ -0,0 +1,39 @@ +package http.response; + +import http.constant.HttpStatus; + +public class HttpResponseStartLine { + + // 기본 200 + private final String version = "HTTP/1.1"; + private HttpStatus httpStatus = HttpStatus.OK; + private static final String DELIMITER = " "; + private static final String CRLF = "\r\n"; + + public HttpResponseStartLine() {} + public HttpResponseStartLine(HttpStatus httpStatus) { + this.httpStatus = httpStatus; + } + + public String getHttpVersion() { + return version; + } + + public HttpStatus getResponseStatus() { + return httpStatus; + } + + public void setStatus(HttpStatus httpStatus) { + this.httpStatus = httpStatus; + } + + public void setHttpVersion(String version) { + version = version; + } + + @Override + public String toString(){ + return version + DELIMITER + httpStatus.getStatus() + CRLF; + } + +} diff --git a/src/main/java/model/UserQueryKey.java b/src/main/java/model/UserQueryKey.java new file mode 100644 index 0000000..6183372 --- /dev/null +++ b/src/main/java/model/UserQueryKey.java @@ -0,0 +1,14 @@ +package model; + +public enum UserQueryKey { + USERID("userId"), PASSWORD("password"), NAME("name"), EMAIL("email"); + private String key; + + UserQueryKey(String key) { + this.key = key; + } + + public String getKey() { + return key; + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index f87ac24..a321afd 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,16 +1,33 @@ package webserver; +import db.MemoryUserRepository; +import db.Repository; +import http.request.HttpRequest; +import http.response.HttpResponse; +import http.util.HttpRequestUtils; +import http.util.IOUtils; +import model.User; + import java.io.*; import java.net.Socket; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public class RequestHandler implements Runnable{ Socket connection; + private static final String ROOT = "./webapp"; + private static final String MAIN_PATH = "/index.html"; + + private final Repository repository; private static final Logger log = Logger.getLogger(RequestHandler.class.getName()); + public RequestHandler(Socket connection) { this.connection = connection; + repository = MemoryUserRepository.getInstance(); } @Override @@ -20,33 +37,14 @@ public void run() { BufferedReader br = new BufferedReader(new InputStreamReader(in)); DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); - response200Header(dos, body.length); - responseBody(dos, body); + HttpRequest httpRequest = HttpRequest.from(br); + HttpResponse httpResponse = new HttpResponse(dos); - } catch (IOException e) { - log.log(Level.SEVERE,e.getMessage()); - } - } + RequestMapper requestMapper = new RequestMapper(httpRequest, httpResponse); + requestMapper.proceed(); - 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.log(Level.SEVERE, e.getMessage()); - } - } - - private void responseBody(DataOutputStream dos, byte[] body) { - try { - dos.write(body, 0, body.length); - dos.flush(); - } catch (IOException e) { - log.log(Level.SEVERE, e.getMessage()); + log.log(Level.SEVERE,e.getMessage()); } } - } diff --git a/src/main/java/webserver/RequestMapper.java b/src/main/java/webserver/RequestMapper.java new file mode 100644 index 0000000..c3fe8de --- /dev/null +++ b/src/main/java/webserver/RequestMapper.java @@ -0,0 +1,47 @@ +package webserver; + +import controller.*; +import http.request.HttpRequest; +import http.response.HttpResponse; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static http.constant.URL.*; + +public class RequestMapper { + + static Map controllers = new HashMap<>(); + private final HttpRequest httpRequest; + private final HttpResponse httpResponse; + private String url; + + public RequestMapper(HttpRequest httpRequest, HttpResponse httpResponse) { + this.httpRequest = httpRequest; + this.httpResponse = httpResponse; + + url = httpRequest.getPath(); + } + + static { + controllers.put(SIGNUP_ACTION.getURL(), new SignUpController()); + controllers.put(LOGIN_ACTION.getURL(), new LoginController()); + controllers.put(USERLIST_ACTION.getURL(), new UserListController()); + } + + public void proceed() throws IOException { + Controller controller = null; + if(controllers.containsKey(url)) + controller = controllers.get(url); + + if(url.endsWith(".html") || url.endsWith(".css")) + controller = new JustGetController(); + + if(controller == null) + throw new IllegalArgumentException("처리할 수 없는 url 입니다."); + controller.execute(httpRequest, httpResponse); + } + + +} diff --git a/src/test/java/ControllerTest.java b/src/test/java/ControllerTest.java new file mode 100644 index 0000000..3a17a81 --- /dev/null +++ b/src/test/java/ControllerTest.java @@ -0,0 +1,56 @@ +import controller.Controller; +import http.request.HttpRequest; +import http.response.HttpResponse; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +import controller.JustGetController; + +class ControllerTest { + + + private final static String testDirectory = "./src/test/java"; + private final static String reqPath = "/res/request/"; + private final static String respPath = "/res/response/"; + private static String reqFile= "GET_message.txt"; + private String respFile = "GET_res.txt"; + + private BufferedReader bufferedReaderFromFile(String path) throws IOException { + return new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(path)))); + } + + private OutputStream outputStreamToFile(String path) throws IOException { + return Files.newOutputStream(Paths.get(path)); + } + + @Test + @DisplayName("JustGetController - .html의 body 반환") + void HTMLControllerTest() throws IOException { + String responseFile = "GET_index_html.txt"; + HttpRequest httpRequest = HttpRequest.from(bufferedReaderFromFile(testDirectory + reqPath + reqFile)); + + HttpResponse httpResponse = new HttpResponse(outputStreamToFile(testDirectory+ respPath + responseFile)); + + Controller htmlController = new JustGetController(); + htmlController.execute(httpRequest, httpResponse); + } + + @Test + @DisplayName("JustGetController - .css의 body 반환") + void CSSControllerTest() throws IOException { + String responseFile = "Forward_css.txt"; + reqFile = "GET_css.txt"; + HttpRequest httpRequest = HttpRequest.from(bufferedReaderFromFile(testDirectory + reqPath + reqFile)); + + HttpResponse httpResponse = new HttpResponse(outputStreamToFile(testDirectory+ respPath + responseFile)); + + Controller cssController = new JustGetController(); + cssController.execute(httpRequest, httpResponse); + } + + +} \ No newline at end of file diff --git a/src/test/java/http/ConstantTest.java b/src/test/java/http/ConstantTest.java new file mode 100644 index 0000000..41c04b7 --- /dev/null +++ b/src/test/java/http/ConstantTest.java @@ -0,0 +1,35 @@ +package http; + +import http.constant.HttpMethod; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static http.constant.HttpStatus.OK; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class ConstantTest { + + @Test + @DisplayName("Status - 문자열 생성 테스트") + public void testStatus(){ + String s = "HTTP/1.1 " + OK.getStatus(); + assertEquals(s,"HTTP/1.1 200 OK"); + + String ok = "200 OK"; + + } + + @Test + @DisplayName("HttpMethod - of 테스트") + public void testMethod(){ + String startLine_method = "GET"; + HttpMethod method = HttpMethod.of(startLine_method); + + assertEquals("GET", method.getMethod()); + assertNotEquals("POST", method.getMethod()); + + } + + +} diff --git a/src/test/java/http/HttpHeadersTest.java b/src/test/java/http/HttpHeadersTest.java new file mode 100644 index 0000000..1df5666 --- /dev/null +++ b/src/test/java/http/HttpHeadersTest.java @@ -0,0 +1,26 @@ +package http; + + +import http.constant.HttpHeader; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class HttpHeadersTest { + + @Test + @DisplayName("put Header Test") + public void putHeaderTest(){ + HttpHeaders httpHeaders = new HttpHeaders(); + + httpHeaders.put(HttpHeader.CONTENT_LENGTH, "50"); + httpHeaders.put(HttpHeader.LOCATION, "/index.html"); + + String response = "Location: /index.html" + "\r\n" + + "Content-Length: 50" + "\r\n" + + "\r\n"; + + assertEquals(response, httpHeaders.toString()); + + } +} \ No newline at end of file diff --git a/src/test/java/http/HttpRequestTest.java b/src/test/java/http/HttpRequestTest.java new file mode 100644 index 0000000..09341aa --- /dev/null +++ b/src/test/java/http/HttpRequestTest.java @@ -0,0 +1,37 @@ +package http; + +import http.request.HttpRequest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static http.constant.HttpMethod.POST; +import static org.junit.jupiter.api.Assertions.*; + +class HttpRequestTest { + + + private final static String testDirectory = "./src/test/java"; + private final static String reqPath = "/res/request/"; + private final static String reqFile= "POST_message.txt"; + + private BufferedReader bufferedReaderFromFile(String path) throws IOException { + return new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(path)))); + } + + + + @Test + @DisplayName("httpRequestMessage test - check attribute") + void httpRequestMessageTest() throws IOException { + HttpRequest httpRequest = HttpRequest.from(bufferedReaderFromFile(testDirectory + reqPath + reqFile)); + assertEquals("/user/create", httpRequest.getPath()); + assertEquals(POST, httpRequest.getMethod()); + + + } + +} \ No newline at end of file diff --git a/src/test/java/http/HttpResponseTest.java b/src/test/java/http/HttpResponseTest.java new file mode 100644 index 0000000..37244c6 --- /dev/null +++ b/src/test/java/http/HttpResponseTest.java @@ -0,0 +1,79 @@ +package http; + +import http.request.HttpRequest; +import http.response.HttpResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class HttpResponseTest { + private final static String testDirectory = "./src/test/java"; + private final static String reqPath = "/res/request/"; + private final static String respPath = "/res/response/"; + private static String reqFile= "GET_message.txt"; + private String respFile = "GET_res.txt"; + + private BufferedReader bufferedReaderFromFile(String path) throws IOException { + return new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get(path)))); + } + + @BeforeEach + void init() throws IOException { + HttpRequest httpRequest = HttpRequest.from(bufferedReaderFromFile(testDirectory + reqPath + reqFile)); + } + + private OutputStream outputStreamToFile(String path) throws IOException { + return Files.newOutputStream(Paths.get(path)); + } + + @Test + @DisplayName("httpResponseMessage test - forward() 테스트") + void forwardTest() throws IOException { + respFile = "GET_index.txt"; + HttpResponse httpResponse = new HttpResponse(outputStreamToFile(testDirectory + respPath +respFile)); + httpResponse.forward("/index.html"); + + + respFile = "GET_list.txt"; + httpResponse = new HttpResponse(outputStreamToFile(testDirectory + respPath +respFile)); + httpResponse.forward("/user/list.html"); + } + + + @Test + @DisplayName("url이 \"/\"인 경우 처리 Test") + void forward_SlashAddress_Test() throws IOException { + reqFile = "GET_slash.txt"; + HttpRequest httpRequest = HttpRequest.from(bufferedReaderFromFile(testDirectory + reqPath + reqFile)); + + + respFile = "GET_slash_resp.txt"; + HttpResponse httpResponse = new HttpResponse(outputStreamToFile(testDirectory+ respPath +respFile)); + httpResponse.forward(httpRequest.getPath()); + } + + @Test + @DisplayName("httpResponseMessage test - check attribute") + void httpResponseMessageTest() throws IOException { + respFile = "RED_index.txt"; + HttpResponse httpResponse = new HttpResponse(outputStreamToFile(testDirectory+ respPath + respFile)); + httpResponse.redirect("/index.html"); + + + respFile = "RED_list.txt"; + httpResponse = new HttpResponse(outputStreamToFile(testDirectory+ respPath + respFile)); + httpResponse.redirect("/user/list.html"); + + } + + @Test + @DisplayName("Request 얻어와서 StartLine 생성하기") + void makeStartLine_fromRequest(){ + + } + +} diff --git a/src/test/java/http/util/ConstantTest.java b/src/test/java/http/util/ConstantTest.java new file mode 100644 index 0000000..b0dac48 --- /dev/null +++ b/src/test/java/http/util/ConstantTest.java @@ -0,0 +1,18 @@ +package http.util; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static http.util.constant.Status.OK; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ConstantTest { + + @Test + @DisplayName("Status - 문자열 생성 테스트") + public void testStatus(){ + String s = "HTTP/1.1 " + OK.getStatus(); + assertEquals(s,"HTTP/1.1 200 OK"); + } + +} diff --git a/src/test/java/model/UserTest.java b/src/test/java/model/UserTest.java new file mode 100644 index 0000000..d22758a --- /dev/null +++ b/src/test/java/model/UserTest.java @@ -0,0 +1,69 @@ +package model; + +import http.util.HttpRequestUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import db.MemoryUserRepository; + +import java.util.Collection; +import java.util.Map; + +import static model.UserQueryKey.*; +import static org.junit.jupiter.api.Assertions.*; + +class UserTest { + + @Test + @DisplayName("addUser: Repository에 반영되는지 확인") + public void addUserTest(){ + User user = new User("uid12", "1234", "name", "ke123@gmail.com"); + + MemoryUserRepository repo = MemoryUserRepository.getInstance(); + // Before: addUser + Collection userList = repo.findAll(); + assertTrue(userList.size() == 0); + + // After : addUser + repo.addUser(user); + userList = repo.findAll(); + assertTrue(userList.size() != 0); + } + + @Test + @DisplayName("addUser: query에서 parsing하여 생성") + public void addUserTest_With_Query(){ + Map queries = HttpRequestUtils.parseQueryParameter("userId=uid12&password=1234&name=tmp&email=tmp@gamil.com"); + + + User user = new User(queries.get("userId"), queries.get("password"), queries.get("name"), queries.get("email")); + + MemoryUserRepository repo = MemoryUserRepository.getInstance(); + repo.addUser(user); + Collection userList = repo.findAll(); + assertTrue(userList.size() != 0); + + User findUser = repo.findUserById(queries.get("userId")); + assertEquals(findUser.getUserId(), "uid12"); + } + + @Test + @DisplayName("addUser: UserQueryKey enum class 이용 ") + public void addUserTest_WithUserQueryKey(){ + Map queries = HttpRequestUtils.parseQueryParameter("userId=uid12&password=1234&name=tmp&email=tmp@gamil.com"); + + assertEquals("uid12", queries.get(USERID.getKey())); + + User user = new User(queries.get(USERID.getKey()), queries.get(PASSWORD.getKey()), queries.get(NAME.getKey()), queries.get(EMAIL.getKey())); + + MemoryUserRepository repo = MemoryUserRepository.getInstance(); + repo.addUser(user); + Collection userList = repo.findAll(); + assertTrue(userList.size() != 0); + + User findUser = repo.findUserById(queries.get(USERID.getKey())); + assertEquals(findUser.getUserId(), "uid12"); + } + + + +} \ No newline at end of file diff --git a/webapp/user/login_failed.html b/webapp/user/login_failed.html index 87736e1..065e932 100644 --- a/webapp/user/login_failed.html +++ b/webapp/user/login_failed.html @@ -5,7 +5,7 @@ KUIT - +