Skip to content

step1 #35

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
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
10 changes: 8 additions & 2 deletions src/main/java/db/DataBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@

import java.util.Collection;
import java.util.Map;
import java.util.Optional;

import com.google.common.collect.Maps;

import model.User;

public class DataBase {
private static Map<String, User> users = Maps.newHashMap();
static{
DataBase.addUser(new User("n", "n", "엔삼", "n@n.com"));
DataBase.addUser(new User("n1", "n1", "엔삼1", "n1@n.com"));
DataBase.addUser(new User("n2", "n2", "엔삼2", "n2@n.com"));
}

public static void addUser(User user) {
users.put(user.getUserId(), user);
}

public static User findUserById(String userId) {
return users.get(userId);
public static Optional<User> findUserById(String userId) {
return Optional.ofNullable(users.get(userId));
}

public static Collection<User> findAll() {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ public String getEmail() {
public String toString() {
return "User [userId=" + userId + ", password=" + password + ", name=" + name + ", email=" + email + "]";
}

public boolean isSamePassword(String password) {
return this.password.equals(password);
}
}
18 changes: 14 additions & 4 deletions src/main/java/util/HttpRequestUtils.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package util;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;

public class HttpRequestUtils {
/**
* @param queryString은
* @param queryString
* URL에서 ? 이후에 전달되는 field1=value1&field2=value2 형식임
* @return
*/
Expand All @@ -18,8 +20,8 @@ public static Map<String, String> parseQueryString(String queryString) {
}

/**
* @param 쿠키
* 값은 name1=value1; name2=value2 형식임
* @param cookies
* 쿠키값은 name1=value1; name2=value2 형식임
* @return
*/
public static Map<String, String> parseCookies(String cookies) {
Expand All @@ -32,7 +34,11 @@ private static Map<String, String> parseValues(String values, String separator)
}

String[] tokens = values.split(separator);
return Arrays.stream(tokens).map(t -> getKeyValue(t, "=")).filter(p -> p != null)
return parse(Arrays.stream(tokens), "=");
}

private static Map<String, String> parse(Stream<String> stream, String separator) {
return stream.map(t -> getKeyValue(t, separator)).filter(p -> p != null)
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
}

Expand All @@ -53,6 +59,10 @@ public static Pair parseHeader(String header) {
return getKeyValue(header, ": ");
}

public static Map<String, String> parseHeader(List<String> headers) {
return parse(headers.stream(), ": ");
}

public static class Pair {
String key;
String value;
Expand Down
151 changes: 142 additions & 9 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.net.Socket;

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

import java.io.*;
import java.net.Socket;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class RequestHandler extends Thread {
private static final Logger log = LoggerFactory.getLogger(RequestHandler.class);
Expand All @@ -24,10 +30,103 @@ public void run() {

try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) {
// TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다.

List<String> request = new ArrayList<>();

BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while (!"".equals(line = br.readLine())) {
if (line == null) {
return;
}
log.debug("{}", line);
request.add(line);
}

String[] startLine = request.get(0).split(" ");
String method = startLine[0];
String requestUrl = startLine[1];
String version = startLine[2];

Map<String, String> headers = HttpRequestUtils.parseHeader(request.subList(1, request.size()));

String[] splitResource = requestUrl.split("\\?");
String url = splitResource[0];
String queryString = "";
if (splitResource.length == 2) {
queryString = URLDecoder.decode(splitResource[1], "UTF-8");
}


log.debug("requestUrl : {} , url : {}, queryString : {}", requestUrl, url, queryString);


byte[] responseBody = "".getBytes();
DataOutputStream dos = new DataOutputStream(out);
byte[] body = "Hello World".getBytes();
response200Header(dos, body.length);
responseBody(dos, body);

if (method.equals("GET")) {
if (url.equals("/user/list.html")) {
System.out.println("list");
if (headers.get("Cookie") != null && headers.get("Cookie").contains("true")) {
BufferedReader fr = new BufferedReader(new FileReader("./webapp/user/list.html"));
StringBuilder sb = new StringBuilder();
String fileLine;
while ((fileLine = fr.readLine()) != null) {
if (fileLine.contains("{{list}}")) {
StringBuilder iterateSb = new StringBuilder();
String iterateLine;
while (!((iterateLine = fr.readLine()).contains("{{/list}}"))) {
iterateSb.append(iterateLine);
}
String forString = iterateSb.toString();
for (User user : DataBase.findAll()) {
sb.append(forString
.replace("{{id}}", user.getUserId())
.replace("{{name}}", user.getName())
.replace("{{email}}", user.getEmail()));
}
} else {
sb.append(fileLine);
}
}
responseBody = sb.toString().getBytes();
} else {
response304Header(dos, "/index.html");
}
} else {
responseBody = Files.readAllBytes(new File("./webapp" + url).toPath());
}
if (headers.get("Accept").contains("css")) {
response200HeaderCss(dos, responseBody.length);
}else{
response200Header(dos, responseBody.length);
}
responseBody(dos, responseBody);
} else if (method.equals("POST")) {
String requestBody = IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length")));
Map<String, String> ret = HttpRequestUtils.parseQueryString(requestBody);
if (url.equals("/user/create")) {
DataBase.addUser(
new User(ret.get("userId"),
ret.get("password"),
ret.get("name"),
ret.get("email"))
);
System.out.println("post");
log.debug("query body : {}", ret);
response304Header(dos, "/index.html");
} else if (url.equals("/user/login")) {
if (DataBase.findUserById(ret.get("userId"))
.map(User::getPassword)
.filter((x) -> x.equals(ret.get("password")))
.isPresent()) {
response304HeaderLogined(dos, "/index.html", true);
} else {
response304HeaderLogined(dos, "/index.html", false);
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

메소드 아름답네요. ㅋㅋ


} catch (IOException e) {
log.error(e.getMessage());
}
Expand All @@ -44,6 +143,40 @@ private void response200Header(DataOutputStream dos, int lengthOfBodyContent) {
}
}

private void response200HeaderCss(DataOutputStream dos, int lengthOfBodyContent) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
dos.writeBytes("Content-Type: text/css;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 response304HeaderLogined(DataOutputStream dos, String location, boolean logined) {
try {
dos.writeBytes("HTTP/1.1 302 FOUND \r\n");
dos.writeBytes("Location: " + location + "\r\n");
dos.writeBytes("Set-Cookie: logined=" + logined + "; Path=/");
dos.writeBytes("\r\n");
dos.flush();
} catch (IOException e) {
log.error(e.getMessage());
}
}

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

private void responseBody(DataOutputStream dos, byte[] body) {
try {
dos.write(body, 0, body.length);
Expand Down
30 changes: 25 additions & 5 deletions src/test/java/util/HttpRequestUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
package util;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import util.HttpRequestUtils.Pair;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.junit.Test;

import util.HttpRequestUtils.Pair;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;

public class HttpRequestUtilsTest {
@Test
public void test() {
String headers =
"Host: localhost:8080\n\r" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\n\r" +
"Referer: http://localhost:8080/user/form.html\n\r";
List<String> list = Arrays.asList(headers.split("\\n\\r"));
Map<String, String> ret = HttpRequestUtils.parseHeader(list);
System.out.println(ret);
assertThat(ret.get("Host"), is("localhost:8080"));
assertThat(ret.get("Accept"), is("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"));
assertThat(ret.get("Referer"), is("http://localhost:8080/user/form.html"));



}


@Test
public void parseQueryString() {
String queryString = "userId=javajigi";
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
7 changes: 3 additions & 4 deletions webapp/user/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@
</tr>
</thead>
<tbody>
{{list}}
<tr>
<th scope="row">1</th> <td>javajigi</td> <td>자바지기</td> <td>javajigi@sample.net</td><td><a href="#" class="btn btn-success" role="button">수정</a></td>
</tr>
<tr>
<th scope="row">2</th> <td>slipp</td> <td>슬립</td> <td>slipp@sample.net</td><td><a href="#" class="btn btn-success" role="button">수정</a></td>
<th scope="row">1</th> <td>{{id}}</td> <td>{{name}}</td> <td>{{email}}</td><td><a href="#" class="btn btn-success" role="button">수정</a></td>
</tr>
{{/list}}
</tbody>
</table>
</div>
Expand Down