2016-06-24 5 views
1

나는 간단한 http 요청 파서를 Java 학습용으로 작성하고 있습니다. 내 임무는 시체를 포함하는 POST 요청을 간단하게 가져 와서 구문 분석하고 http 프로토콜 (상태 200 OK)에 따라 응답을 되돌려 보내는 것입니다.Java에서 HTTP 요청 구문 분석

curl 명령으로 요청을 게시하면 요청 행과 헤더가 인쇄되지만 본문은 인쇄되지 않습니다. Ctrl c를 눌러 컬을 벗어나면 본문이 인쇄됩니다.

nc -l 명령은 제대로 작동하고 본문이 머리글과 함께 인쇄됩니다.

두 가지의 차이점은 무엇이며 어떻게 요청 본문을 컬 포스트 명령으로 인쇄 할 수 있습니까?

아래 코드는 입력 사항입니다.

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.util.*; 

public class Server { 

private static ServerSocket serverSocket; 
private static Socket clientSocket; 
private static BufferedReader bufferedReader; 
private static String inputLine; 
private static PrintWriter output; 

public static void main(String[] args) { 
    try { 
     serverSocket = new ServerSocket(3000); 

     while (true) { 
      List<String> list = new ArrayList<String>(); 
      clientSocket = serverSocket.accept(); 
      bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
      output = new PrintWriter(clientSocket.getOutputStream()); 

      inputLine = bufferedReader.readLine(); 
      while (inputLine.length() > 0) { 
       System.out.println(inputLine); 
       list.add(inputLine); 
       inputLine = bufferedReader.readLine(); 
      } 

      String bodyLine = bufferedReader.readLine(); 
      while(bodyLine != null && bodyLine.length() > 0){ 
       System.out.println(bodyLine); 
       output.println(bodyLine); 
       bodyLine = bufferedReader.readLine(); 
      } 

      /* My Request class has a parse method that takes a List and parses in accordingly. getRequestLine() returns the request line of the request and getMethod() its method. */ 

      Request r = Request.parse(list); 
      if (r.getRequestLine().getMethod().equals("GET")){ 
       output.println("HTTP/1.0 200 OK"); 
       output.println("Content-Type: text/html"); 
       output.println(""); 
       output.println("<p>GET REQUEST: </p><p>" + r + "</p>"); 
      } 

      if (r.getRequestLine().getMethod().equals("POST")){ 
       output.println("HTTP/1.0 200 OK"); 
       output.println("Content-Type: text/html"); 
       output.println(""); 
       output.println("<p>POST REQUEST:</p><p>" + r + "</p>"); 
      } 

      output.close(); 
      bufferedReader.close(); 
      clientSocket.close(); 

     } 


    } catch (IOException error) { 
     System.out.println(error); 

    } 

} 

}

요청 분류 :

import java.util.*; 

public class Request { 
private Map<String, String> headers; 
private String body; 
private RequestLine requestLine; 

public Request(Map<String, String> headers, String body, RequestLine requestLine) { 
    this.headers = headers; 
    this.body = body; 
    this.requestLine = requestLine; 
} 

public Map<String, String> getHeaders() { 
    return headers; 
} 

public String getBody() { 
    return body; 
} 

public RequestLine getRequestLine() { 
    return requestLine; 
} 

public String toString() { 
    return "Request Line: " + getRequestLine() + '\n' + "Headers: " + getHeaders(); 
} 

public static Request parse(List<String> lines) { 
    String requestLineStr = lines.get(0); 
    String[] requestLineArr = requestLineStr.split(" "); 
    String method = requestLineArr[0]; 
    String URI = requestLineArr[1]; 
    String status = requestLineArr[2]; 

    RequestLine requestLine = new RequestLine(URI, method, status); 


    // int index = lines.indexOf("\r\n\r\n"); 
    // List<String> headerList = lines.subList(1, index); 
    // List<String> bodyList = lines.subList(index, -1); 

    List<String> headerList = lines.subList(1, lines.size()-1); 
    Map<String, String> headersMap = new HashMap<>(); 

    for(int i = 0; i <headerList.size(); i++) { 
     String line = headerList.get(i); 
     String[] arr = line.split(" "); 
     headersMap.put(arr[0], arr[1]); 
    } 

    /*String bodyString = ""; 
    for(int i = 0; i < bodyList.size(); i++) { 
     bodyString += bodyList.get(i); 
    }*/ 

    return new Request(headersMap, "", requestLine); 
} 

}

+0

요청에 어떤 라이브러리를 사용합니까? 사용자 정의 - 코드를 제공하는 경우 – user3136131

+0

질문에 추가되었지만 입력 스트림을 처리하는 방식에 문제가 있음을 확신합니다. – yinjia

+0

HTTP 요청과 콘솔 출력을 지금까지 추가해 주시겠습니까? –

답변

0

LF = HTTP/1.1이 모든 행의 끝 마커와 같은 시퀀스 CR의 LF 정의 엔티티 본문을 제외한 프로토콜 요소 RFC2616

헤더는 \r\n까지갑니다. 그 후에 시체가 시작됩니다.

내의 readLine

공공 문자열 내의 readLine() 는 IOException이

이 한 줄의 텍스트를 읽어냅니다. 한 줄은 줄 바꿈 ('\ n'), 캐리지 리턴 ('\ r') 또는 캐리지 리턴 다음에 즉시 줄 바꿈으로 끝나는 것으로 간주됩니다. 도달 한 스트림의 마지막에 예외 경우 모든 라인 종료 문자를 포함한 행의 내용이 아닌 를 포함하는 문자열, 또는 null : 반환 IOException이이 - I/O 오류가 BufferedReader#readLine()

발생하는 경우

헤더를 읽고 신체를 읽는 사이에 bufferedReader.readLine();을 추가하십시오.

inputLine = bufferedReader.readLine(); 
     while (inputLine.length() > 0) { 
      System.out.println(inputLine); 
      list.add(inputLine); 
      inputLine = bufferedReader.readLine(); 
     } 
    bufferedReader.readLine(); 
    String bodyLine = bufferedReader.readLine(); 
     while(bodyLine != null && bodyLine.length() > 0){ 
      System.out.println(bodyLine); 
      output.println(bodyLine); 
      bodyLine = bufferedReader.readLine(); 
     }