Apache httpd
글
-
Apache httpd 소스 파헤치기 1: AI와 함께 소스를 읽는 방법과 분석 지도
Apache httpd가 무엇이고 어떻게 동작하며 어디에 쓰는지를 그림과 3분 실습으로 먼저 보고 시작하는, httpd 소스 읽기 연재의 첫 글입니다. 어떤 판(trunk 2.5.1-dev)을 읽는지, 같은 소스를 받아 도커에서 빌드하는 법과 실제로 막혔던 곳, 35만 줄짜리 소스의 폴더 지도, 요청 하나가 지나는 큰 길, 그리고 AI가 쓴 노트를 소스로 다시 확인하며 읽는 방법을 정리합니다.
-
Apache httpd 소스 파헤치기 2: C로 짠 서버를 읽기 전에 — 구조체, 함수 포인터, 매크로
C의 구조체가 C++나 Java의 객체보다 아름답다는 말은 어디서 나왔을까요. 클래스도 인터페이스도 없는 C로 httpd가 모듈을 끼우는 방법을 실제 소스와 실행 결과로 확인합니다. 숨은 것 없는 메모리 모양, 함수 포인터로 만든 인터페이스, void * 배열과 module_index, 매크로로 찍어 내는 훅, 따로 컴파일한 .so를 믿는 MMN 검사, 그리고 C가 대신 해 주지 않는 것들까지.
-
Apache httpd 소스 파헤치기 3: 전체 지도 — 코어, APR, MPM, 모듈과 세 개의 큰 구조체
Apache httpd 소스를 처음 여는 사람을 위한 지도입니다. 운영체제·APR·코어·MPM·모듈로 나뉘는 층, 코어조차 모듈이라는 것, 실행 파일에 묶이는 모듈과 LoadModule로 싣는 모듈의 차이, server_rec·conn_rec·request_rec 세 구조체와 풀 계층, 요청 하나가 지나가는 길을 실제 소스와 직접 돌린 예제로 확인합니다.
-
Apache httpd 소스 파헤치기 4: APR 메모리 풀 — free 없이 메모리를 관리하는 법
httpd 의 C 코드에는 free() 가 거의 보이지 않습니다. 메모리를 하나하나 돌려주는 대신 "요청 하나", "연결 하나" 처럼 수명이 같은 것끼리 풀에 묶어 한꺼번에 버리기 때문입니다. APR 풀의 노드와 allocator, 포인터 하나를 미는 것으로 끝나는 apr_palloc, cleanup 의 실행 순서, httpd 가 풀을 만들고 지우는 자리, 그리고 흔한 실수 두 가지를 실제 소스와 실행 결과로 확인합니다.
-
Apache httpd 소스 파헤치기 5: main()과 기동 — 설정을 두 번 읽는 이유와 재시작
httpd를 켜면 main() 안에서 무슨 일이 일어나는지 server/main.c 914줄을 따라 읽습니다. 설정 파일을 왜 두 번 읽는지, apachectl graceful 한 줄이 어떻게 main()의 루프를 한 바퀴 더 돌게 하는지, 루트로 시작한 서버가 어디서 User로 내려가는지를 소스와 실제 실행 로그로 확인합니다.
-
Apache httpd 소스 파헤치기 6: 모듈과 훅 — 모듈 하나가 서버에 끼어드는 방법
httpd 의 기능은 거의 전부 모듈이고, 모듈은 훅이라는 정해진 자리에 함수를 걸어 서버에 끼어듭니다. module 구조체, 모듈이 등록되는 길(정적 모듈과 LoadModule), 훅을 만드는 매크로가 실제로 무엇으로 펼쳐지는지, RUN_FIRST 와 RUN_ALL 의 차이, 순서 값과 앞뒤 모듈 이름으로 정하는 실행 순서를 기준 커밋의 소스와 직접 만든 모듈 세 개로 확인합니다.
-
Apache httpd 소스 파헤치기 7: 설정 파일과 디렉티브 — httpd.conf 한 줄이 C 구조체가 되기까지
httpd.conf 에 적은 한 줄이 어떻게 모듈의 C 함수를 부르고 구조체에 값을 넣는지 server/config.c 를 따라갑니다. 파일을 트리로 읽는 단계와 그 트리를 걷는 단계, 이름으로 디렉티브를 찾는 해시, TAKE1·FLAG·ITERATE 같은 인자 방식, "not allowed here" 가 나오는 비트 검사와 AllowOverride, 그리고 Directory·Location·VirtualHost 섹션의 값이 언제 병합되는지를 직접 만든 디렉티브로 확인합니다.
-
Apache httpd 소스 파헤치기 8: MPM — prefork, worker, event는 연결을 어떻게 나눠 맡나
httpd.conf 의 LoadModule mpm_event_module 한 줄이 무엇을 바꾸는지 소스로 따라갑니다. MPM 이 모듈 하나로 갈아 끼워지는 원리(mpm 훅과 ap_mpm_query), 프로세스만 쓰는 prefork, 리스너 스레드와 큐로 일을 나누는 worker, keep-alive 연결을 스레드에서 떼어 epoll 에 맡기는 event, 1초마다 자식을 늘리고 줄이는 부모의 루프와 공유 메모리 스코어보드, 그리고 StartServers·MaxRequestWorkers·ThreadsPerChild 가 코드의 어디서 쓰이는지를 ps·mod_status·gdb 실행 결과로 확인합니다.
-
Apache httpd 소스 파헤치기 9: 연결과 요청 읽기 — 소켓 하나가 request_rec가 되기까지
MPM이 받아 넘긴 소켓 하나가 conn_rec가 되고, 요청 줄과 헤더를 읽어 request_rec가 되기까지를 httpd 소스로 따라갑니다. 코어가 훅의 맨 끝에 서는 이유, keep-alive 루프가 MPM에 따라 어디에 있는지, trunk에서 요청 줄을 읽는 일이 필터로 옮겨 간 것, 그리고 Host 헤더로 가상 호스트를 고르는 두 단계를 예제와 함께 확인합니다.
-
Apache httpd 소스 파헤치기 10: 요청 처리 단계 — URL에서 파일과 핸들러까지
GET /hello.html 한 줄이 httpd 안에서 어떤 단계를 거쳐 디스크의 파일과 그것을 내보낼 핸들러로 바뀌는지, ap_process_request_internal()의 단계 순서를 따라 소스에서 확인합니다. Location·Directory·Files 설정이 합쳐지는 세 가지 걷기, mod_dir의 서브요청, ErrorDocument의 내부 리다이렉트도 모든 단계에 로그를 찍는 모듈로 직접 봅니다.
-
Apache httpd 소스 파헤치기 11: 필터와 버킷 브리게이드 — 응답은 어떻게 흘러 나가나
핸들러가 만든 응답이 소켓에 닿기까지 httpd 안에서 어떤 모양으로 흐르는지, 소스를 처음 여는 사람 기준으로 따라갑니다. APR-util 의 버킷과 브리게이드(링), 읽을 때 모양이 바뀌는 PIPE·FILE 버킷, 여섯 단계로 줄 서는 필터와 ap_pass_brigade, chunked 인코딩과 sendfile, 그리고 소켓이 가득 찼을 때 코어 출력 필터가 하는 일을 직접 쓴 필터 모듈의 로그로 확인합니다.
-
Apache httpd 소스 파헤치기 12: 핸들러와 정적 파일 — 파일 하나는 어떻게 응답이 되나
SetHandler와 AddHandler가 정하는 "핸들러"가 Content-Type과 어떻게 다른지, 아무도 맡지 않은 요청을 코어의 default_handler()가 어떻게 파일 버킷 하나로 내보내는지를 소스로 따라갑니다. ETag와 304, Range와 206, 끝 슬래시 301과 DirectoryIndex, 그리고 EnableSendfile·EnableMMAP이 실제로 어떤 시스템 콜을 바꾸는지도 curl과 strace로 확인합니다.
-
Apache httpd 소스 파헤치기 13: 인증과 권한 — Require 한 줄은 어떻게 판정되나
httpd.conf 의 AuthType Basic, AuthUserFile, Require valid-user, <RequireAll> 이 소스에서 어떻게 움직이는지 따라갑니다. "누구인가"를 묻는 인증과 "들어와도 되는가"를 묻는 권한이 왜 다른 모듈로 나뉘었는지, 이름으로 갈아 끼우는 프로바이더, Require 트리와 GRANTED·DENIED·NEUTRAL 판정, 그리고 같은 판정을 두 번 돌리는 request.c 의 순서를 실제 소스와 예제 출력으로 확인합니다.
-
Apache httpd 소스 파헤치기 14: mod_proxy — 리버스 프록시와 로드 밸런서
ProxyPass 한 줄이 요청을 다른 서버로 넘기기까지를 소스로 따라갑니다. URL이 r->filename의 "proxy:..."로 바뀌는 자리, proxy_handler()가 스킴 핸들러 훅에 일을 넘기는 방식, 백엔드마다 하나씩 생기는 워커와 연결 풀, mod_proxy_http가 브리게이드로 응답을 흘려보내는 길, 그리고 byrequests 밸런서가 두 백엔드를 번갈아 고르는 계산을 컨테이너 안의 백엔드 두 대로 직접 확인합니다.
-
Apache httpd 소스 파헤치기 15: mod_ssl — TLS는 어디에 끼어드나
httpd 코어는 TLS를 모릅니다. 그런데도 SSLEngine on 한 줄이면 HTTPS가 됩니다. mod_ssl이 훅으로 기동과 연결에 끼어들고, 연결 필터와 직접 만든 BIO로 OpenSSL을 필터 사슬 사이에 끼우고, SNI로 가상 호스트와 인증서를 바꾸고, SSL_* 변수를 다른 모듈에 내주는 과정을 소스와 예제로 따라갑니다.
-
Apache httpd 소스 파헤치기 16: 로그 — 접근 로그와 오류 로그, 그리고 연재를 마치며
httpd의 두 가지 로그가 소스에서 어떻게 남는지 따라갑니다. ap_log_rerror() 한 줄이 매크로로 레벨을 거르는 방법, LogLevel을 모듈마다 다르게 거는 module_index, ErrorLogFormat과 LogFormat 문자열이 함수 포인터 배열이 되는 과정, 요청이 끝난 뒤 log_transaction 훅이 불리는 때, 파이프 로그를 다시 띄우는 구조를 예제로 확인하고, 16편 연재를 정리합니다.