Skip to content

soulee-dev/webserv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

437 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Webserv

C++98둜 κ΅¬ν˜„ν•œ HTTP/1.1 μ›Ή μ„œλ²„ ν”„λ‘œμ νŠΈμž…λ‹ˆλ‹€. Nginx와 μœ μ‚¬ν•œ μ„€μ • 방식을 μ‚¬μš©ν•˜λ©°, 정적 파일 제곡, CGI μ‹€ν–‰, 파일 μ—…λ‘œλ“œ λ“± λ‹€μ–‘ν•œ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.

μ£Όμš” κΈ°λŠ₯

  • HTTP/1.1 ν”„λ‘œν† μ½œ 지원: ν‘œμ€€ HTTP μš”μ²­/응닡 처리
  • λ©€ν‹° μ„œλ²„ 지원: μ—¬λŸ¬ ν¬νŠΈμ—μ„œ λ™μ‹œμ— 가상 호슀트 운영
  • 이벀트 λ“œλ¦¬λΈ μ•„ν‚€ν…μ²˜: kqueueλ₯Ό μ‚¬μš©ν•œ 비동기 I/O 처리
  • HTTP λ©”μ†Œλ“œ 지원: GET, POST, PUT, DELETE, HEAD
  • CGI 지원: 동적 μ½˜ν…μΈ  생성을 μœ„ν•œ CGI 슀크립트 μ‹€ν–‰
  • 파일 μ—…λ‘œλ“œ: POST/PUT λ©”μ†Œλ“œλ₯Ό ν†΅ν•œ 파일 μ—…λ‘œλ“œ
  • λ¦¬λ‹€μ΄λ ‰μ…˜: 301 λ¦¬λ‹€μ΄λ ‰νŠΈ 지원
  • μžλ™ 인덱싱: 디렉토리 λͺ©λ‘ μžλ™ 생성
  • μ»€μŠ€ν…€ μ—λŸ¬ νŽ˜μ΄μ§€: HTTP μƒνƒœ μ½”λ“œλ³„ 맞좀 μ—λŸ¬ νŽ˜μ΄μ§€
  • μš”μ²­ λ°”λ”” 크기 μ œν•œ: Location별 μ—…λ‘œλ“œ 크기 μ œν•œ μ„€μ •

ν”„λ‘œμ νŠΈ ꡬ쑰

webserv/
β”œβ”€β”€ config/
β”‚   └── default.conf           # κΈ°λ³Έ μ„œλ²„ μ„€μ • 파일
β”œβ”€β”€ html/
β”‚   β”œβ”€β”€ error_pages/           # μ—λŸ¬ νŽ˜μ΄μ§€ ν…œν”Œλ¦Ώ
β”‚   β”œβ”€β”€ www/                   # κΈ°λ³Έ μ›Ήμ‚¬μ΄νŠΈ 파일
β”‚   └── YoupiBanane/           # ν…ŒμŠ€νŠΈ μ½˜ν…μΈ 
β”œβ”€β”€ srcs/
β”‚   β”œβ”€β”€ Client.cpp/.hpp        # ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° 처리
β”‚   β”œβ”€β”€ ClientManager.cpp/.hpp # 닀쀑 ν΄λΌμ΄μ–ΈνŠΈ 관리
β”‚   β”œβ”€β”€ Server.cpp/.hpp        # μ„œλ²„ μ„€μ • 클래슀
β”‚   β”œβ”€β”€ ServerManager.cpp/.hpp # λ©€ν‹° μ„œλ²„ 관리
β”‚   β”œβ”€β”€ Event.cpp/.hpp         # Kqueue 이벀트 처리
β”‚   β”œβ”€β”€ Location.cpp/.hpp      # Location 블둝 처리
β”‚   β”œβ”€β”€ Config/
β”‚   β”‚   β”œβ”€β”€ ConfigParser.cpp/.hpp      # μ„€μ • 파일 νŒŒμ‹±
β”‚   β”‚   └── ConfigFunctions.cpp        # μ„€μ • 헬퍼 ν•¨μˆ˜
β”‚   β”œβ”€β”€ Message/
β”‚   β”‚   β”œβ”€β”€ Message.cpp/.hpp   # HTTP λ©”μ‹œμ§€ κΈ°λ³Έ 클래슀
β”‚   β”‚   β”œβ”€β”€ Request.cpp/.hpp   # HTTP μš”μ²­ νŒŒμ‹±
β”‚   β”‚   └── Response.cpp/.hpp  # HTTP 응닡 생성
β”‚   β”œβ”€β”€ Http/
β”‚   β”‚   β”œβ”€β”€ HttpRequestManager.cpp/.hpp  # μš”μ²­ 처리 μ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜
β”‚   β”‚   └── Handler/
β”‚   β”‚       β”œβ”€β”€ Handler.cpp/.hpp         # ν•Έλ“€λŸ¬ κΈ°λ³Έ 클래슀
β”‚   β”‚       β”œβ”€β”€ StaticHandler.cpp/.hpp   # 정적 파일 μ„œλΉ™
β”‚   β”‚       β”œβ”€β”€ DynamicHandler.cpp/.hpp  # CGI 처리
β”‚   β”‚       β”œβ”€β”€ ErrorHandler.cpp/.hpp    # μ—λŸ¬ 응닡
β”‚   β”‚       β”œβ”€β”€ DeleteHandler.cpp/.hpp   # DELETE μš”μ²­ 처리
β”‚   β”‚       β”œβ”€β”€ RedirectHandler.cpp/.hpp # λ¦¬λ‹€μ΄λ ‰νŠΈ 처리
β”‚   β”‚       └── HttpStatusCodes.cpp/.hpp # HTTP μƒνƒœ μ½”λ“œ
β”‚   └── main.cpp               # ν”„λ‘œκ·Έλž¨ μ§„μž…μ 
β”œβ”€β”€ tester/                    # ν…ŒμŠ€νŠΈ 슀크립트
β”œβ”€β”€ Makefile                   # λΉŒλ“œ μ„€μ •
└── README.md

μš”κ΅¬μ‚¬ν•­

  • 컴파일러: C++98 ν‘œμ€€μ„ μ§€μ›ν•˜λŠ” C++ 컴파일러
  • 운영체제: BSD 계열 (macOS, FreeBSD λ“±) - kqueue μ‚¬μš©
  • λΉŒλ“œ 도ꡬ: GNU Make

λΉŒλ“œ

# ν”„λ‘œμ νŠΈ λΉŒλ“œ
make

# 클린 λΉŒλ“œ
make re

# 였브젝트 파일 μ‚­μ œ
make clean

# 전체 μ‚­μ œ (μ‹€ν–‰ 파일 포함)
make fclean

λΉŒλ“œκ°€ μ™„λ£Œλ˜λ©΄ webserv μ‹€ν–‰ 파일이 μƒμ„±λ©λ‹ˆλ‹€.

μ‚¬μš©λ²•

κΈ°λ³Έ μ‹€ν–‰

# κΈ°λ³Έ μ„€μ • 파일(config/default.conf) μ‚¬μš©
./webserv

# μ»€μŠ€ν…€ μ„€μ • 파일 μ‚¬μš©
./webserv path/to/config.conf

μ„œλ²„ ν…ŒμŠ€νŠΈ

# μ›Ή λΈŒλΌμš°μ €μ—μ„œ 접속
http://localhost:80

# curl을 μ‚¬μš©ν•œ ν…ŒμŠ€νŠΈ
curl http://localhost:80
curl -X POST -d "data=test" http://localhost:80/post_test
curl -X DELETE http://localhost:80/soulee/test.html

μ„€μ • 파일 ꡬ쑰

μ„€μ • νŒŒμΌμ€ Nginx와 μœ μ‚¬ν•œ 문법을 μ‚¬μš©ν•©λ‹ˆλ‹€.

κΈ°λ³Έ μ„œλ²„ 블둝

server {
    listen 80;                      # λ¦¬μŠ€λ‹ 포트
    server_name localhost;          # μ„œλ²„ 이름
    error_page 403 404 405 40x.html;  # μ—λŸ¬ νŽ˜μ΄μ§€
    upload_path uploaded_files;     # μ—…λ‘œλ“œ 디렉토리

    location / {
        allow_method GET;           # ν—ˆμš© HTTP λ©”μ†Œλ“œ
        root ./html/www;            # λ¬Έμ„œ 루트
        index index.html index.htm; # 기본 인덱슀 파일
        autoindex on;               # μžλ™ 인덱싱 ν™œμ„±ν™”
    }
}

Location 블둝 μ„€μ •

location /api {
    allow_method GET POST DELETE;   # 닀쀑 λ©”μ†Œλ“œ ν—ˆμš©
    root ./html/api;
    index index.html;
    autoindex on;
}

location /upload {
    allow_method POST PUT;
    root ./html/uploads;
    client_max_body_size 1000;      # μ΅œλŒ€ λ°”λ”” 크기 (λ°”μ΄νŠΈ)
}

location /redirect {
    allow_method GET;
    return 301 http://www.example.com;  # λ¦¬λ‹€μ΄λ ‰νŠΈ
}

μ„€μ • μ§€μ‹œμ–΄ μ„€λͺ…

μ§€μ‹œμ–΄ μ„€λͺ… μ˜ˆμ‹œ
listen λ¦¬μŠ€λ‹ 포트 번호 listen 80;
server_name 가상 호슀트 이름 server_name localhost;
error_page μ»€μŠ€ν…€ μ—λŸ¬ νŽ˜μ΄μ§€ error_page 404 error.html;
upload_path 파일 μ—…λ‘œλ“œ 경둜 upload_path uploads;
allow_method ν—ˆμš©ν•  HTTP λ©”μ†Œλ“œ allow_method GET POST;
root λ¬Έμ„œ 루트 디렉토리 root ./html/www;
index 기본 인덱슀 파일 index index.html;
autoindex μžλ™ 디렉토리 인덱싱 autoindex on;
client_max_body_size μ΅œλŒ€ μš”μ²­ λ°”λ”” 크기 client_max_body_size 1000;
return HTTP λ¦¬λ‹€μ΄λ ‰νŠΈ return 301 http://...;

HTTP λ©”μ†Œλ“œ 지원

GET

정적 νŒŒμΌμ„ μ œκ³΅ν•˜κ±°λ‚˜ CGI 슀크립트λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.

curl http://localhost:80/index.html

POST

데이터λ₯Ό μ„œλ²„λ‘œ μ „μ†‘ν•˜κ±°λ‚˜ νŒŒμΌμ„ μ—…λ‘œλ“œν•©λ‹ˆλ‹€.

curl -X POST -d "key=value" http://localhost:80/post_body
curl -X POST -F "file=@test.txt" http://localhost:80/upload

PUT

νŒŒμΌμ„ μƒμ„±ν•˜κ±°λ‚˜ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.

curl -X PUT -d "content" http://localhost:80/put_test/file.txt

DELETE

μ§€μ •λœ λ¦¬μ†ŒμŠ€λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.

curl -X DELETE http://localhost:80/soulee/file.txt

CGI 지원

μ›Ήμ„œλ²„λŠ” 동적 μ½˜ν…μΈ  생성을 μœ„ν•΄ CGI(Common Gateway Interface)λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

CGI 슀크립트 μ˜ˆμ‹œ

#!/usr/bin/env python3
print("Content-Type: text/html\n")
print("<html><body>")
print("<h1>Hello from CGI!</h1>")
print("</body></html>")

CGI μŠ€ν¬λ¦½νŠΈλŠ” μ‹€ν–‰ κΆŒν•œμ΄ ν•„μš”ν•˜λ©°, μ μ ˆν•œ shebang 라인을 포함해야 ν•©λ‹ˆλ‹€.

μ•„ν‚€ν…μ²˜

μš”μ²­ 처리 흐름

Client Request
    ↓
ServerManager (kqueue 이벀트 λŒ€κΈ°)
    ↓
ClientManager (ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° 관리)
    ↓
Request Parser (HTTP μš”μ²­ νŒŒμ‹±)
    ↓
HttpRequestManager (μš”μ²­ λΌμš°νŒ…)
    ↓
Handler 선택 (Static/Dynamic/Error/Redirect/Delete)
    ↓
Response Builder (HTTP 응닡 생성)
    ↓
Client Response

핡심 μ»΄ν¬λ„ŒνŠΈ

  • ServerManager: μ—¬λŸ¬ μ„œλ²„ μΈμŠ€ν„΄μŠ€λ₯Ό κ΄€λ¦¬ν•˜κ³  kqueueλ₯Ό 톡해 이벀트λ₯Ό 처리
  • ClientManager: ν΄λΌμ΄μ–ΈνŠΈ 연결을 μΆ”μ ν•˜κ³  관리
  • ConfigParser: μ„€μ • νŒŒμΌμ„ νŒŒμ‹±ν•˜μ—¬ μ„œλ²„ ꡬ성 생성
  • HttpRequestManager: HTTP μš”μ²­μ„ μ μ ˆν•œ ν•Έλ“€λŸ¬λ‘œ λΌμš°νŒ…
  • Handler 계측: μš”μ²­ μœ ν˜•λ³„λ‘œ νŠΉν™”λœ 처리 둜직 제곡

기술 μŠ€νƒ

  • μ–Έμ–΄: C++98
  • ν‘œμ€€ 라이브러리: STL (Standard Template Library)
  • I/O λͺ¨λΈ: kqueue (BSD 이벀트 μ•Œλ¦Ό μΈν„°νŽ˜μ΄μŠ€)
  • ν”„λ‘œν† μ½œ: HTTP/1.1
  • λΉŒλ“œ μ‹œμŠ€ν…œ: GNU Make
  • 컴파일 ν”Œλž˜κ·Έ: -Wall -Werror -Wextra -std=c++98 -g3

개발 νžˆμŠ€ν† λ¦¬

ν”„λ‘œμ νŠΈλŠ” ν™œλ°œνžˆ 개발 쀑이며, 졜근 컀밋 내역은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • CGI μ—λŸ¬ 처리 κ°œμ„ 
  • 파일 μ‘΄μž¬ν•˜μ§€ μ•Šμ„ λ•Œ 500 μ—λŸ¬ λ°˜ν™˜
  • μ„œλ²„ λΉŒλ“œ μ΅œμ ν™”

ν…ŒμŠ€νŠΈ

tester/ 디렉토리에 ν…ŒμŠ€νŠΈ μŠ€ν¬λ¦½νŠΈκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. μ„œλ²„μ˜ λ‹€μ–‘ν•œ κΈ°λŠ₯을 κ²€μ¦ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λΌμ΄μ„ΌμŠ€

이 ν”„λ‘œμ νŠΈλŠ” ꡐ윑 λͺ©μ μœΌλ‘œ μ œμž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

κΈ°μ—¬μž

Git νžˆμŠ€ν† λ¦¬λ₯Ό μ°Έμ‘°ν•˜μ—¬ ν”„λ‘œμ νŠΈ κΈ°μ—¬μžλ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.


더 λ§Žμ€ μ •λ³΄λ‚˜ 버그 λ¦¬ν¬νŠΈλŠ” ν”„λ‘œμ νŠΈ μ €μž₯μ†Œμ˜ 이슈 트래컀λ₯Ό μ΄μš©ν•΄μ£Όμ„Έμš”.

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors