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

Feature/#1 web server #37

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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
172 changes: 159 additions & 13 deletions src/main/java/webserver/RequestHandler.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package webserver;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Collection;
import java.util.Map;

import db.DataBase;
import model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.HttpRequestUtils;
import util.IOUtils;


public class RequestHandler extends Thread {
private static final Logger log = LoggerFactory.getLogger(RequestHandler.class);
Expand All @@ -19,25 +25,165 @@ public RequestHandler(Socket connectionSocket) {
}

public void run() {
log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
connection.getPort());

try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.
DataOutputStream dos = new DataOutputStream(out);
byte[] body = "Hello World".getBytes();
response200Header(dos, body.length);
responseBody(dos, body);
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line = br.readLine();
log.debug("===== request line : {} =====", line); // 요청 라인

if (line == null) {
return;
}

String[] tokens = line.split(" ");
int contentLength = 0;
boolean logined = false;
while (!line.equals("")) {
line = br.readLine();
log.debug("header : {}", line);

if (line.contains("Content-Length")) {
contentLength = getContentLength(line);
}

if (line.contains("Cookie")) {
logined = isLogin(line);
}
}

String url = tokens[1];

if (url.equals("/user/create")) {
String body = IOUtils.readData(br, contentLength);
Map<String, String> params = HttpRequestUtils.parseQueryString(body);

User user = new User(
params.get("userId"),
params.get("password"),
params.get("name"),
params.get("email")
);
DataBase.addUser(user);
log.debug("user : {}", user);

DataOutputStream dos = new DataOutputStream(out);
response302Header(dos, "/index.html");
} else if (url.equals("/user/login")) {
String body = IOUtils.readData(br, contentLength);
Map<String, String> params = HttpRequestUtils.parseQueryString(body);

User user = DataBase.findUserById(params.get("userId"));

if (user == null) {
responseResource(out, "/user/login_failed.html");
return;
}

if (user.getPassword().equals(params.get("password"))) {
DataOutputStream dos = new DataOutputStream(out);
response302LoginSuccessHeader(dos);
} else {
responseResource(out, "/user/login_failed.html");
}

} else if (url.equals("/user/list")) {
if (!logined) {
responseResource(out, "/user/login.html");
return;
}

Collection<User> users = DataBase.findAll();
StringBuilder sb = new StringBuilder();
sb.append("<table border='1'>");
for (User user : users) {
sb.append("<tr>");
sb.append("<td>" + user.getUserId() + "</td>");
sb.append("<td>" + user.getName() + "</td>");
sb.append("<td>" + user.getEmail() + "</td>");
sb.append("</tr>");
}
sb.append("</table>");

byte[] body = sb.toString().getBytes(StandardCharsets.UTF_8);
DataOutputStream dos = new DataOutputStream(out);
response200Header(dos, body.length);
responseBody(dos, body);
} else if (url.endsWith(".css")) {
DataOutputStream dos = new DataOutputStream(out);
byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
response200CssHeader(dos, body.length);
responseBody(dos, body);
} else {
responseResource(out, url);
}

} catch (IOException e) {
log.error(e.getMessage());
}
}

private void response200CssHeader(DataOutputStream dos, int lengthOfBodyContent) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
dos.writeBytes("Content-Type: text/css \r\n");
dos.writeBytes("Content-Length: " + lengthOfBodyContent + " \r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}

private boolean isLogin(String line) {
String[] tokens = line.split(":");
Map<String, String> cookies = HttpRequestUtils.parseCookies(tokens[1].trim());
String value = cookies.get("logined");

if (value == null) {
return false;
}

return Boolean.parseBoolean(value);
}

private void responseResource(OutputStream out, String url) throws IOException {
DataOutputStream dos = new DataOutputStream(out);
byte[] body = Files.readAllBytes(new File("./webapp" + url).toPath());
response200Header(dos, body.length);
responseBody(dos, body);
}

private void response302LoginSuccessHeader(DataOutputStream dos) {
try {
dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
dos.writeBytes("Set-Cookie: logined=true \r\n");
dos.writeBytes("Location: /index.html \r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}

private void response302Header(DataOutputStream dos, String url) {
try {
dos.writeBytes("HTTP/1.1 302 Redirect \r\n");
dos.writeBytes("Location: " + url + " \r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}

private int getContentLength(String line) {
String[] tokens = line.split(":");

return Integer.parseInt(tokens[1].trim());
}

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("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());
Expand Down
1 change: 0 additions & 1 deletion src/main/java/webserver/WebServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public static void main(String args[]) throws Exception {
}

// 서버소켓을 생성한다. 웹서버는 기본적으로 8080번 포트를 사용한다.

try (ServerSocket listenSocket = new ServerSocket(port)) {
log.info("Web Application Server started {} port.", port);

Expand Down
2 changes: 1 addition & 1 deletion webapp/user/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<div class="container" id="main">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default content-main">
<form name="question" method="get" action="/user/create">
<form name="question" method="post" action="/user/create">
<div class="form-group">
<label for="userId">사용자 아이디</label>
<input class="form-control" id="userId" name="userId" placeholder="User ID">
Expand Down