HttpRequestParser.java

package sprout.mvc.http.parser;

import sprout.beans.annotation.Component;
import sprout.mvc.http.HttpRequest;

import java.util.Map;

@Component
public class HttpRequestParser {
    private final RequestLineParser lineParser;
    private final QueryStringParser qsParser;
    private final HttpHeaderParser headerParser;

    public HttpRequestParser(RequestLineParser lineParser, QueryStringParser qsParser, HttpHeaderParser headerParser) {
        this.lineParser = lineParser;
        this.qsParser = qsParser;
        this.headerParser = headerParser;
    }

    public HttpRequest<?> parse(String raw) {
        String[] parts = split(raw);
        String headerAndRequestLinePart = parts[0];
        String bodyPart   = parts[1];
        String firstLine  = headerAndRequestLinePart.split("\r?\n",2)[0];

        var rl    = lineParser.parse(firstLine);
        var query = qsParser.parse(rl.rawPath());

        String rawHeadersOnly = "";
        int firstLineEnd = headerAndRequestLinePart.indexOf("\n");
        if (firstLineEnd != -1) {
            rawHeadersOnly = headerAndRequestLinePart.substring(firstLineEnd + 1);
        }
        Map<String, String> headers = headerParser.parse(rawHeadersOnly);

        return new HttpRequest<>(rl.method(), rl.cleanPath(), bodyPart, query, headers);
    }

    private String[] split(String raw) {
        System.out.println(raw);
        // 헤더·바디 구분 문자열을 먼저 CRLF( \r\n\r\n )로 찾고
        // 없으면 LF( \n\n ) 로 한 번 더 찾기
        int delimiterIdx   = raw.indexOf("\r\n\r\n");
        int delimiterLen   = 4;                 // 기본 CRLF 길이

        if (delimiterIdx == -1) {               // CRLF 구분자가 없다면
            delimiterIdx = raw.indexOf("\n\n"); // LF 구분자 탐색
            delimiterLen = 2;
        }

        if (delimiterIdx != -1) {
            return new String[]{
                    raw.substring(0, delimiterIdx),               // 헤더(요청라인+헤더)
                    raw.substring(delimiterIdx + delimiterLen)     // 바디
            };
        }
        // 구분자를 찾지 못했으면 바디는 빈 문자열
        return new String[]{ raw, "" };
    }
}