HTTP 프로토콜 이해
HTTP(HyperText Transfer Protocol)는 웹에서 클라이언트와 서버 간의 통신을 위한 프로토콜입니다. HTTP 요청과 응답은 텍스트 형식으로 전송되며, 요청은 클라이언트에서 서버로, 응답은 서버에서 클라이언트로 전송됩니다.
HTTP 요청의 구성
- 요청 라인: 메서드, 경로, 버전으로 구성됩니다.
- 헤더: 키-값 쌍으로 이루어진 메타데이터입니다.
- 바디: 선택적이며, 주로 POST 요청에서 사용됩니다.
HTTP 요청 예시:
GET /index.html HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.68.0
Accept: */*
HTTP 응답의 구성
- 상태 라인: 버전, 상태 코드, 상태 메시지로 구성됩니다.
- 헤더: 키-값 쌍으로 이루어진 메타데이터입니다.
- 바디: 서버가 클라이언트에 보내는 데이터입니다.
HTTP 응답 예시:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 70
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
HTTP 프로토콜 구현
이제 HTTP 요청을 처리하고, 적절한 HTTP 응답을 생성하는 기능을 구현하겠습니다.
1. HTTP 요청 파싱
HTTP 요청을 파싱하여 메서드, 경로, 버전, 헤더를 추출합니다. 이전 단계에서 구현한 Request
클래스를 사용합니다.
2. HTTP 응답 생성
HTTP 응답을 생성하는 Response
클래스를 사용합니다. 상태 코드, 헤더, 바디를 설정하여 응답을 만듭니다.
HTTP 요청 처리
이제 클라이언트의 HTTP 요청을 처리하고, 적절한 HTTP 응답을 생성하는 코드를 작성합니다.
server.cpp 수정
Server::handleClient
메서드를 구현하여 클라이언트의 요청을 처리하고 응답을 보냅니다.
void Server::handleClient(int clientSocket) {
char buffer[1024];
int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
if (bytesReceived < 0) {
std::cerr << "Failed to receive request" << std::endl;
close(clientSocket);
return;
}
buffer[bytesReceived] = '\0';
std::string requestStr(buffer);
Request request(requestStr);
std::string method = request.getMethod();
std::string path = request.getPath();
std::string version = request.getVersion();
std::cout << "Request: " << method << " " << path << " " << version << std::endl;
Response response(200);
response.setHeader("Content-Type", "text/html");
response.setBody("<html><body><h1>It works!</h1></body></html>");
std::string responseStr = response.toString();
send(clientSocket, responseStr.c_str(), responseStr.size(), 0);
close(clientSocket);
}
이 코드에서는 클라이언트로부터 요청을 수신하고, 요청을 파싱하여 Request
객체를 생성합니다. 요청의 메서드, 경로, 버전을 출력한 다음, 간단한 HTML 응답을 생성하여 클라이언트에게 전송합니다.
3. 서버 실행
이제 서버를 실행하여 클라이언트의 요청을 처리하고 응답을 반환할 수 있습니다.
main.cpp
#include "server.h"
int main() {
try {
Server server("127.0.0.1", 8080);
server.start();
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
테스트
이제 서버를 실행하고 브라우저나 cURL을 사용하여 테스트해볼 수 있습니다.
브라우저 테스트:
브라우저에서 http://localhost:8080
에 접속하면 "It works!" 메시지가 표시된 HTML 페이지가 나타납니다.
cURL 테스트:
터미널에서 다음 명령어를 실행합니다.
curl http://localhost:8080
결과는 다음과 같습니다:
<html><body><h1>It works!</h1></body></html>
이제 16일차의 학습을 마쳤습니다. HTTP 요청과 응답을 처리하는 간단한 웹 서버를 구현해보았습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "요청 처리 및 라우팅 구현"에 대해 학습하고 구현하겠습니다.