diff --git a/src/main/java/app/handler/RegisterHandlerImpl.java b/src/main/java/app/handler/RegisterHandlerImpl.java index ff671b5b0..215b890e0 100644 --- a/src/main/java/app/handler/RegisterHandlerImpl.java +++ b/src/main/java/app/handler/RegisterHandlerImpl.java @@ -6,22 +6,23 @@ import exception.ServiceException; import http.HttpMethod; import http.request.HttpRequest; +import web.dispatch.argument.QueryParameters; import web.handler.SingleArgHandler; import web.response.HandlerResponse; import web.response.StaticViewResponse; -public class RegisterHandlerImpl extends SingleArgHandler { +public class RegisterHandlerImpl extends SingleArgHandler { public RegisterHandlerImpl() { super(HttpMethod.GET, "/create"); } @Override - public HandlerResponse handle(HttpRequest request) { - String userId = request.getQueryValue("userId").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "userId required")); - String password = request.getQueryValue("password").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "password required")); - String name = request.getQueryValue("name").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "name required")); - String email = request.getQueryValue("email").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "email required")); + public HandlerResponse handle(QueryParameters params) { + String userId = params.getQueryValue("userId").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "userId required")); + String password = params.getQueryValue("password").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "password required")); + String name = params.getQueryValue("name").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "name required")); + String email = params.getQueryValue("email").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "email required")); Database.addUser(new User(userId, password, name, email)); return StaticViewResponse.of("/login"); } diff --git a/src/main/java/config/AppConfig.java b/src/main/java/config/AppConfig.java index 0a5794ec3..fdadf265a 100644 --- a/src/main/java/config/AppConfig.java +++ b/src/main/java/config/AppConfig.java @@ -5,17 +5,18 @@ import exception.handler.ErrorExceptionHandler; import exception.handler.ServiceExceptionHandler; import exception.handler.UnhandledErrorHandler; -import http.request.HttpBufferedReaderRequestConverter; +import http.request.BufferedReaderHttpRequestConverter; import http.request.HttpRequestConverter; -import http.response.HttpBufferedStreamResponseConverter; +import http.request.InputStreamHttpRequestConverter; +import http.response.HttpResponseBufferedStreamConverter; import http.response.HttpResponseConverter; -import web.dispatch.ArgumentResolver; +import web.dispatch.argument.ArgumentResolver; import web.dispatch.Dispatcher; import web.dispatch.HandlerAdapter; import web.dispatch.adapter.DefaultHandlerAdapter; import web.dispatch.adapter.SingleArgHandlerAdapter; -import web.dispatch.argument.HttpRequestResolver; -import web.dispatch.argument.QueryParamsResolver; +import web.dispatch.argument.resolver.HttpRequestResolver; +import web.dispatch.argument.resolver.QueryParamsResolver; import web.handler.StaticContentHandler; import web.handler.WebHandler; import web.renderer.StaticViewRenderer; @@ -25,19 +26,22 @@ public class AppConfig { //Http - public HttpBufferedReaderRequestConverter httpBufferedReaderRequestConverter(){ - return new HttpBufferedReaderRequestConverter(); + public HttpRequestConverter httpRequestConverter(){ + return inputStreamHttpRequestConverter(); + } + public HttpResponseConverter httpResponseConverter(){ + return httpResponseBufferedStreamConverter(); } - public HttpBufferedStreamResponseConverter httpBufferedStreamResponseConverter(){ - return new HttpBufferedStreamResponseConverter(); + public BufferedReaderHttpRequestConverter httpBufferedReaderRequestConverter(){ + return new BufferedReaderHttpRequestConverter(); } - public HttpRequestConverter httpRequestConverter(){ - return httpBufferedReaderRequestConverter(); + public HttpResponseBufferedStreamConverter httpResponseBufferedStreamConverter(){ + return new HttpResponseBufferedStreamConverter(); } - public HttpResponseConverter httpResponseConverter(){ - return httpBufferedStreamResponseConverter(); + public InputStreamHttpRequestConverter inputStreamHttpRequestConverter(){ + return new InputStreamHttpRequestConverter(); } diff --git a/src/main/java/http/request/BufferedReaderHttpRequestConverter.java b/src/main/java/http/request/BufferedReaderHttpRequestConverter.java new file mode 100644 index 000000000..6e3f81d39 --- /dev/null +++ b/src/main/java/http/request/BufferedReaderHttpRequestConverter.java @@ -0,0 +1,42 @@ +package http.request; + +import exception.ErrorException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.Socket; + +public class BufferedReaderHttpRequestConverter implements HttpRequestConverter { + private static final Logger logger = LoggerFactory.getLogger(BufferedReaderHttpRequestConverter.class); + public HttpRequest parseRequest(Socket connection){ + + try { + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader( + connection.getInputStream())); + + HttpRequest request = HttpRequest.from(bufferedReader.readLine()); + request.setRequestAddress(connection.getInetAddress()); + + setHeaders(bufferedReader, request); + + //TODO: Body 파싱 추가 + + return request; + + } catch (IOException e) { + throw new ErrorException("HttpRequestParseError: IO Exception", e); + } + } + + private void setHeaders(BufferedReader bufferedReader, HttpRequest request) throws IOException { + String line; + while ((line = bufferedReader.readLine())!= null) { + if(line.isEmpty()) break; + int idx = line.indexOf(':'); + if(idx<0) throw new ErrorException("HttpRequestHeaderParseError"); + request.setHeader(line.substring(0, idx).strip(), line.substring(idx+1).strip()); + } + } +} diff --git a/src/main/java/http/request/HttpBufferedReaderRequestConverter.java b/src/main/java/http/request/HttpBufferedReaderRequestConverter.java deleted file mode 100644 index 5abaf4f24..000000000 --- a/src/main/java/http/request/HttpBufferedReaderRequestConverter.java +++ /dev/null @@ -1,44 +0,0 @@ -package http.request; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.net.Socket; -import java.util.Arrays; - -public class HttpBufferedReaderRequestConverter implements HttpRequestConverter { - private static final Logger logger = LoggerFactory.getLogger(HttpBufferedReaderRequestConverter.class); - public HttpRequest parseRequest(Socket connection){ - - try { - InputStream in = connection.getInputStream(); - InputStreamReader reader = new InputStreamReader(in); - BufferedReader bufferedReader = new BufferedReader(reader); - String firstLine = bufferedReader.readLine(); - HttpRequest request = HttpRequest.from(firstLine); - request.setRequestAddress(connection.getInetAddress()); - - while (bufferedReader.ready()) { - String line = bufferedReader.readLine().strip(); - if(line.length() <= 1) break; - int idx = line.indexOf(':'); - //TODO: idx == -1 일 경우 Throw Exception - - request.setHeader(line.substring(0, idx).strip(), line.substring(idx+1).strip()); -// logger.debug("New Header Added:{} - {}", line.substring(0, idx), line.substring(idx)); - } - - //TODO: Body 파싱 추가 - - return request; - - } catch (IOException e) { - logger.error(e.getMessage()); - logger.error(Arrays.toString(e.getStackTrace())); - logger.error(String.valueOf(e.getClass())); - } - //TODO: throw webserver exception - return null; - } -} diff --git a/src/main/java/http/request/HttpRequest.java b/src/main/java/http/request/HttpRequest.java index f4e361e0a..2b73186e0 100644 --- a/src/main/java/http/request/HttpRequest.java +++ b/src/main/java/http/request/HttpRequest.java @@ -5,33 +5,47 @@ import exception.ServiceException; import http.HttpMethod; -import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.URI; -import java.net.URLDecoder; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; public class HttpRequest { private final HttpMethod method; - private final Map headers; - private final URI uri; + private final Map headers; //TODO: Map> 타입으로 변경 private String httpVersion; + private final URI uri; private String contentType; - - //TODO: Map> 타입으로 변경 - private Map queryMap; - private byte[] body; + private InetAddress requestAddress; + private HttpRequest (HttpMethod method, + String target, + String httpVersion) { + this.method = method; + this.uri = URI.create(target); + this.httpVersion = httpVersion; + this.headers = new HashMap<>(); + } + + public byte[] getBody() { + return body; + } + + public String getContentType() { + return contentType; + } public String getHeader(String key){ return headers.get(key.toLowerCase()); } + public void setHeader(String key, String value){ headers.put(key.toLowerCase(), value); + if (key.equalsIgnoreCase("Content-Type")) { + this.contentType = value; + } } public List getHeaders(){ @@ -46,31 +60,10 @@ public String getQueryString(){ return uri.getQuery(); } - public List getQueryKeys(){ - return queryMap.keySet().stream().toList(); - } - - public Optional getQueryValue(String key){ - if (queryMap == null) { - queryMap = parseQueryToMap(uri.getQuery()); - } - return Optional.ofNullable(queryMap.get(key)); - } - public HttpMethod getMethod(){ return this.method; } - private HttpRequest (HttpMethod method, - String target, - String httpVersion) { - this.method = method; - this.uri = URI.create(target); - this.httpVersion = httpVersion; - this.headers = new HashMap<>(); - - } - public void setRequestAddress(InetAddress requestAddress) { this.requestAddress = requestAddress; } @@ -93,33 +86,7 @@ public static HttpRequest from(String requestLine){ } } - - private Map parseQueryToMap(String queryString) { - Map map = new HashMap<>(); - if (queryString == null || queryString.isBlank()) { - return map; - } - - String[] pairs = queryString.strip().split("&"); - for (String pair : pairs) { - if (pair.isEmpty()) continue; - - String[] kv = pair.split("=", 2); // value에 '=' 들어가도 OK - String rawKey = kv[0]; - String rawValue = kv.length == 2 ? kv[1] : ""; - - String key = urlDecode(rawKey); - String value = urlDecode(rawValue); - map.put(key, value); - } - return map; - } - - private String urlDecode(String s) { - try { - return URLDecoder.decode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("UTF-8 not supported", e); - } + public void setBody(byte[] body){ + this.body = body; } } diff --git a/src/main/java/http/request/InputStreamHttpRequestConverter.java b/src/main/java/http/request/InputStreamHttpRequestConverter.java new file mode 100644 index 000000000..fcc46d7ba --- /dev/null +++ b/src/main/java/http/request/InputStreamHttpRequestConverter.java @@ -0,0 +1,119 @@ +package http.request; + +import exception.ErrorException; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.Socket; + +public class InputStreamHttpRequestConverter implements HttpRequestConverter{ + + @Override + public HttpRequest parseRequest(Socket connection) { + try { + BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream()); + + String requestLine = readLine(inputStream); + if (requestLine == null || requestLine.isEmpty()) { + throw new ErrorException("HttpRequestParseError: Empty request line"); + } + + HttpRequest request = HttpRequest.from(requestLine); + request.setRequestAddress(connection.getInetAddress()); + + readHeaders(inputStream, request); + readBody(inputStream, request); + + return request; + + } catch (IOException e) { + throw new ErrorException("HttpRequestParseError: IO Exception", e); + } + } + + private void readHeaders(BufferedInputStream in, HttpRequest request) { + try { + while (true) { + String line = readLine(in); + if (line == null || line.isEmpty()) { + break; + } + + int idx = line.indexOf(':'); + if (idx < 0) { + throw new ErrorException("HttpRequestHeaderParseError: " + line); + } + + request.setHeader( + line.substring(0, idx).trim(), + line.substring(idx + 1).trim() + ); + } + } catch (IOException e){ + throw new ErrorException("HttpRequestHeaderParseError: IOException"); + } catch (Exception e){ + throw new ErrorException("HttpRequestHeaderParseError: Unexpected Error", e); + } + } + + private void readBody(BufferedInputStream in, HttpRequest request) { + try { + String contentLength = request.getHeader("Content-Length"); + if (contentLength == null) { + return; // body 없음 + } + + int length; + try { + length = Integer.parseInt(contentLength.trim()); + } catch (NumberFormatException e) { + throw new ErrorException("Invalid Content-Length: " + contentLength, e); + } + + if (length <= 0) return; + + byte[] body = new byte[length]; + int offset = 0; + + while (offset < length) { + int n = in.read(body, offset, length - offset); + if (n < 0) { + throw new ErrorException("Unexpected EOF while reading body"); + } + offset += n; + } + + request.setBody(body); + } catch (IOException e){ + throw new ErrorException("HttpRequestBodyParseError: IOException"); + } catch (Exception e){ + throw new ErrorException("HttpRequestBodyParseError: Unexpected Error", e); + } + } + + private String readLine(BufferedInputStream in) throws IOException { + ByteArrayOutputStream lineBuffer = new ByteArrayOutputStream(128); + + int prev = -1; + while (true) { + int cur = in.read(); + if (cur == -1) { + if (lineBuffer.size() == 0) return null; + return lineBuffer.toString(); + } + + if (prev == '\r' && cur == '\n') { + byte[] raw = lineBuffer.toByteArray(); + int len = raw.length; + if (len > 0 && raw[len - 1] == '\r') { + return new String(raw, 0, len - 1); + } + return lineBuffer.toString(); + } + + lineBuffer.write(cur); + prev = cur; + } + } +} diff --git a/src/main/java/http/response/HttpBufferedStreamResponseConverter.java b/src/main/java/http/response/HttpResponseBufferedStreamConverter.java similarity index 95% rename from src/main/java/http/response/HttpBufferedStreamResponseConverter.java rename to src/main/java/http/response/HttpResponseBufferedStreamConverter.java index 7ad59fbb2..481588c77 100644 --- a/src/main/java/http/response/HttpBufferedStreamResponseConverter.java +++ b/src/main/java/http/response/HttpResponseBufferedStreamConverter.java @@ -7,7 +7,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; -public class HttpBufferedStreamResponseConverter implements HttpResponseConverter { +public class HttpResponseBufferedStreamConverter implements HttpResponseConverter { @Override public boolean support() { @@ -20,6 +20,7 @@ public void sendResponse(HttpResponse response, Socket connection) { OutputStream raw = connection.getOutputStream(); BufferedOutputStream out = new BufferedOutputStream(raw); + byte[] body = response.getBody(); if (body == null) body = new byte[0]; diff --git a/src/main/java/web/dispatch/Dispatcher.java b/src/main/java/web/dispatch/Dispatcher.java index e62e4d238..0d55440b0 100644 --- a/src/main/java/web/dispatch/Dispatcher.java +++ b/src/main/java/web/dispatch/Dispatcher.java @@ -32,10 +32,12 @@ public HttpResponse handle(HttpRequest request){ logger.debug("{}: {} - {} from {}", request.getMethod(), request.getPath(), request.getQueryString(), request.getRequestAddress()); + //handler 선택 WebHandler handler = handlerMapping.get(request.getMethod()).stream() .filter(h -> h.checkEndpoint(request.getMethod(), request.getPath())) .findFirst().orElseThrow(()-> new ServiceException(ErrorCode.NO_SUCH_RESOURCE)); + //Adapter 선택 HandlerAdapter adapter = adapterList.stream().filter(ha -> ha.support(handler)) .findFirst().orElseThrow(() -> new ErrorException("DispatcherError: No adapter matched")); diff --git a/src/main/java/web/dispatch/adapter/SingleArgHandlerAdapter.java b/src/main/java/web/dispatch/adapter/SingleArgHandlerAdapter.java index ebf2c0d1c..e8573e00f 100644 --- a/src/main/java/web/dispatch/adapter/SingleArgHandlerAdapter.java +++ b/src/main/java/web/dispatch/adapter/SingleArgHandlerAdapter.java @@ -2,7 +2,7 @@ import exception.ErrorException; import http.request.HttpRequest; -import web.dispatch.ArgumentResolver; +import web.dispatch.argument.ArgumentResolver; import web.dispatch.HandlerAdapter; import web.handler.SingleArgHandler; import web.handler.WebHandler; diff --git a/src/main/java/web/dispatch/ArgumentResolver.java b/src/main/java/web/dispatch/argument/ArgumentResolver.java similarity index 94% rename from src/main/java/web/dispatch/ArgumentResolver.java rename to src/main/java/web/dispatch/argument/ArgumentResolver.java index bbdf50ab7..6d27b2bbf 100644 --- a/src/main/java/web/dispatch/ArgumentResolver.java +++ b/src/main/java/web/dispatch/argument/ArgumentResolver.java @@ -1,4 +1,4 @@ -package web.dispatch; +package web.dispatch.argument; import http.request.HttpRequest; diff --git a/src/main/java/web/dispatch/argument/QueryParameters.java b/src/main/java/web/dispatch/argument/QueryParameters.java index 6272b3ced..bb7541f1e 100644 --- a/src/main/java/web/dispatch/argument/QueryParameters.java +++ b/src/main/java/web/dispatch/argument/QueryParameters.java @@ -1,27 +1,69 @@ package web.dispatch.argument; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.*; public class QueryParameters { private final Map> params; + private String queryString; + private QueryParameters(String queryString) { + this.params = parseQueryToMap(queryString); + this.queryString = queryString; + } - public QueryParameters() { - this.params = new HashMap<>(); + public static QueryParameters of(String queryString) { + return new QueryParameters(queryString); } - public void addParams(String key, String value){ - if(!params.containsKey(key)) params.put(key, new ArrayList<>()); - params.get(key).add(value); + public String getQueryString() { + return queryString; } - public Optional getValue(String key){ - return Optional.ofNullable(params.get(key).get(0)); + public Optional getQueryValue(String key){ + if(params.containsKey(key)) + return Optional.of(params.get(key).get(0)); + return Optional.empty(); } - public List getValues(String key){ + public List getQueryValues(String key){ if(params.containsKey(key)) return params.get(key); return List.of(); } + + public List getQueryKeys(){ + return params.keySet().stream().toList(); + } + + private Map> parseQueryToMap(String queryString) { + Map> map = new HashMap<>(); + if (queryString == null || queryString.isBlank()) { + return map; + } + + String[] pairs = queryString.strip().split("&"); + for (String pair : pairs) { + if (pair.isEmpty()) continue; + + String[] kv = pair.split("=", 2); // value에 '=' 들어가도 OK + String rawKey = kv[0]; + String rawValue = kv.length == 2 ? kv[1] : ""; + + String key = urlDecode(rawKey); + String value = urlDecode(rawValue); + if(!map.containsKey(key)) map.put(key, new ArrayList<>()); + map.get(key).add(value); + } + return map; + } + + private String urlDecode(String s) { + try { + return URLDecoder.decode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("UTF-8 not supported", e); + } + } } diff --git a/src/main/java/web/dispatch/argument/QueryParamsResolver.java b/src/main/java/web/dispatch/argument/QueryParamsResolver.java deleted file mode 100644 index a3fd502dd..000000000 --- a/src/main/java/web/dispatch/argument/QueryParamsResolver.java +++ /dev/null @@ -1,18 +0,0 @@ -package web.dispatch.argument; - -import exception.ErrorException; -import http.request.HttpRequest; -import web.dispatch.ArgumentResolver; - -public class QueryParamsResolver extends ArgumentResolver { - - @Override - public QueryParameters resolve(HttpRequest request) { - QueryParameters queryParameters = new QueryParameters(); - for (String key : request.getQueryKeys()) { - queryParameters.addParams(key, request.getQueryValue(key).orElseThrow( - ()-> new ErrorException("query parameter mapping error"))); - } - return queryParameters; - } -} diff --git a/src/main/java/web/dispatch/argument/HttpRequestResolver.java b/src/main/java/web/dispatch/argument/resolver/HttpRequestResolver.java similarity index 70% rename from src/main/java/web/dispatch/argument/HttpRequestResolver.java rename to src/main/java/web/dispatch/argument/resolver/HttpRequestResolver.java index ccc9c0033..1f773723a 100644 --- a/src/main/java/web/dispatch/argument/HttpRequestResolver.java +++ b/src/main/java/web/dispatch/argument/resolver/HttpRequestResolver.java @@ -1,7 +1,7 @@ -package web.dispatch.argument; +package web.dispatch.argument.resolver; import http.request.HttpRequest; -import web.dispatch.ArgumentResolver; +import web.dispatch.argument.ArgumentResolver; public class HttpRequestResolver extends ArgumentResolver { diff --git a/src/main/java/web/dispatch/argument/resolver/QueryParamsResolver.java b/src/main/java/web/dispatch/argument/resolver/QueryParamsResolver.java new file mode 100644 index 000000000..7645c2ab5 --- /dev/null +++ b/src/main/java/web/dispatch/argument/resolver/QueryParamsResolver.java @@ -0,0 +1,21 @@ +package web.dispatch.argument.resolver; + +import http.request.HttpRequest; +import web.dispatch.argument.ArgumentResolver; +import web.dispatch.argument.QueryParameters; +import java.nio.charset.StandardCharsets; + +public class QueryParamsResolver extends ArgumentResolver { + + @Override + public QueryParameters resolve(HttpRequest request) { + String queryString = request.getQueryString(); + if(queryString==null) { + if (request.getContentType() != null + && request.getContentType().strip().equalsIgnoreCase("application/x-www-form-urlencoded")) { + queryString = new String(request.getBody(), StandardCharsets.UTF_8); + } else queryString = ""; + } + return QueryParameters.of(queryString); + } +} diff --git a/src/test/java/web/dispatch/argument/QueryParametersTest.java b/src/test/java/web/dispatch/argument/QueryParametersTest.java new file mode 100644 index 000000000..54536d230 --- /dev/null +++ b/src/test/java/web/dispatch/argument/QueryParametersTest.java @@ -0,0 +1,32 @@ +package web.dispatch.argument; + +import http.request.HttpRequest; +import org.junit.jupiter.api.Test; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class QueryParametersTest { + + @Test + void query_params_GET_decode_test() throws UnsupportedEncodingException { + String value = URLEncoder.encode("한글", "UTF-8"); + HttpRequest request = HttpRequest.from("GET /user/create?test=" + value + " HTTP/1.1"); + QueryParameters queryParameters = QueryParameters.of(request.getQueryString()); + + assertThat(queryParameters.getQueryValue("test").orElse(null)).isEqualTo("한글"); + } + @Test + void query_params_GET_parse_and_decode_test(){ + HttpRequest request = HttpRequest.from("GET /user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net HTTP/1.1"); + QueryParameters queryParameters = QueryParameters.of(request.getQueryString()); + + assertThat(queryParameters.getQueryValue("userId").orElse("")).isEqualTo("javajigi"); + assertThat(queryParameters.getQueryValue("password").orElse("")).isEqualTo("password"); + assertThat(queryParameters.getQueryValue("name").orElse("")).isEqualTo("박재성"); + assertThat(queryParameters.getQueryValue("email").orElse("")).isEqualTo("javajigi@slipp.net"); + } +} \ No newline at end of file diff --git a/src/test/java/web/dispatch/argument/resolver/QueryParamsResolverTest.java b/src/test/java/web/dispatch/argument/resolver/QueryParamsResolverTest.java new file mode 100644 index 000000000..360b6cf5d --- /dev/null +++ b/src/test/java/web/dispatch/argument/resolver/QueryParamsResolverTest.java @@ -0,0 +1,41 @@ +package web.dispatch.argument.resolver; + +import http.request.HttpRequest; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import web.dispatch.argument.QueryParameters; + +import java.io.UnsupportedEncodingException; + +import static org.assertj.core.api.Assertions.assertThat; + +class QueryParamsResolverTest { + QueryParamsResolver resolver = new QueryParamsResolver(); + + @Test + void query_params_resolver_parse_POST_test() throws UnsupportedEncodingException { + HttpRequest request = HttpRequest.from("POST /user/create HTTP/1.1"); + request.setHeader("Host", "localhost:8080"); + request.setHeader("Connection", "keep-alive"); + request.setHeader("Content-Type", "application/x-www-form-urlencoded"); + request.setHeader("Content-Length","67"); + request.setBody("userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net".getBytes("UTF-8")); + + QueryParameters queryParameters = resolver.resolve(request); + assertThat(queryParameters.getQueryValue("userId").orElse(null)).isEqualTo("javajigi"); + assertThat(queryParameters.getQueryValue("password").orElse(null)).isEqualTo("password"); + assertThat(queryParameters.getQueryValue("name").orElse(null)).isEqualTo("박재성"); + assertThat(queryParameters.getQueryValue("email").orElse(null)).isEqualTo("javajigi@slipp.net"); + } + + @Test + void query_params_resolver_parse_GET_test(){ + HttpRequest request = HttpRequest.from("GET /user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net HTTP/1.1"); + QueryParameters queryParameters = resolver.resolve(request); + + assertThat(queryParameters.getQueryValue("userId").orElse("")).isEqualTo("javajigi"); + assertThat(queryParameters.getQueryValue("password").orElse("")).isEqualTo("password"); + assertThat(queryParameters.getQueryValue("name").orElse("")).isEqualTo("박재성"); + assertThat(queryParameters.getQueryValue("email").orElse("")).isEqualTo("javajigi@slipp.net"); + } +} \ No newline at end of file diff --git a/src/test/java/web/http/request/HttpRequestConverterTest.java b/src/test/java/web/http/request/HttpRequestConverterTest.java index a1854e622..3a17a10b3 100644 --- a/src/test/java/web/http/request/HttpRequestConverterTest.java +++ b/src/test/java/web/http/request/HttpRequestConverterTest.java @@ -1,6 +1,7 @@ package web.http.request; -import http.request.HttpBufferedReaderRequestConverter; +import config.AppConfig; +import http.request.BufferedReaderHttpRequestConverter; import http.request.HttpRequest; import http.request.HttpRequestConverter; import org.junit.jupiter.api.Test; @@ -14,7 +15,8 @@ import static org.mockito.Mockito.*; class HttpRequestConverterTest { - private final HttpRequestConverter converter = new HttpBufferedReaderRequestConverter(); + private final AppConfig appConfig = new AppConfig(); + private final HttpRequestConverter converter = appConfig.httpRequestConverter(); @Test void parse_GET_request_test() throws Exception { @@ -33,8 +35,7 @@ void parse_GET_request_test() throws Exception { assertThat(req.getMethod().name()).isEqualTo("GET"); assertThat(req.getPath()).isEqualTo("/hello"); - assertThat(req.getQueryValue("name").get()).isEqualTo("ta"); - assertThat(req.getQueryValue("x").get()).isEqualTo("1"); + assertThat(req.getQueryString()).isEqualTo("name=ta&x=1"); assertThat(req.getHeader("Host")).isEqualTo("localhost"); assertThat(req.getHeader("User-Agent")).isEqualTo("junit"); } diff --git a/src/test/java/web/http/request/HttpRequestTest.java b/src/test/java/web/http/request/HttpRequestTest.java index c230a66e6..b2454b26c 100644 --- a/src/test/java/web/http/request/HttpRequestTest.java +++ b/src/test/java/web/http/request/HttpRequestTest.java @@ -11,7 +11,7 @@ class HttpRequestTest { void query_parameter_parse_test(){ HttpRequest request = HttpRequest.from("GET /create?userId=user1&nickname=testNick&password=123 HTTP/1.1"); assertThat(request.getPath()).isEqualTo("/create"); - assertThat(request.getQueryValue("userId").get()).isEqualTo("user1"); + assertThat(request.getQueryString()).isEqualTo("userId=user1&nickname=testNick&password=123"); } } \ No newline at end of file diff --git a/src/test/java/web/http/response/HttpResponseConverterTest.java b/src/test/java/web/http/response/HttpResponseConverterTest.java index e180b8e35..07420c045 100644 --- a/src/test/java/web/http/response/HttpResponseConverterTest.java +++ b/src/test/java/web/http/response/HttpResponseConverterTest.java @@ -1,6 +1,6 @@ package web.http.response; -import http.response.HttpBufferedStreamResponseConverter; +import http.response.HttpResponseBufferedStreamConverter; import http.response.HttpResponse; import http.response.HttpResponseConverter; import org.junit.jupiter.api.Test; @@ -18,7 +18,7 @@ @ExtendWith(MockitoExtension.class) class HttpResponseConverterTest { - private final HttpResponseConverter converter = new HttpBufferedStreamResponseConverter(); + private final HttpResponseConverter converter = new HttpResponseBufferedStreamConverter(); @Test void write_response_to_socket_test() throws Exception {