Lowent 매뉴얼←↑→

http — HTTP/1.1 요청 파서

소스
lib/http.low
층
L0 — 순수 계산
권한
없음

요청 바이트열을 받아 각 필드가 어디서 시작해 몇 바이트인지 답한다(RFC 9112). 자르지 않는다 — 자르는 것은 부르는 쪽이 subslice 로 한다. 모든 실패는 0 이다. 0 은 정당한 자리가 될 수 없다 — 요청은 최소 GET / HTTP/1.1␍␊␍␊ 라 어떤 필드도 0 에서 시작하지 않는다.

무엇을 약속하고 무엇을 하지 않나

서버 쪽 요청 파싱만 한다(응답 파싱 없음). 전송이 없다 — 바이트열은 부르는 쪽이 모아 온다. 청크 전송(Transfer-Encoding: chunked)을 짓지 않았다 — 그 헤더를 찾아 주기만 하므로 부르는 쪽이 거절해야 한다. 트레일러 · 여러 줄 헤더(obs-fold) · URL 퍼센트 해체 · HTTP/2 가 없다. HTTP/1.0 을 받지 않는다 — 지속 연결 규칙이 다르고 그것을 짓지 않았다.
let t u64 be http.target_off b .
let n u64 be http.target_len b .
guard gt n 0 . else return 0 .
let target slice u8 . be subslice b t (add t n) .
op하는 일
method_get · method_head · method_post · method_put · method_delete메서드 코드(1 … 5)
method_code요청 줄의 메서드 → 코드. 0 = 모름
line_next · line_len다음 줄의 자리 · 이 줄의 내용 길이(CRLF 제외)
target_off · target_len요청 대상의 자리 · 길이
version_okHTTP/1.1 인가
headers_off · header_next첫 헤더 · 다음 헤더(빈 줄이면 0)
name_len · value_off · value_len헤더 이름 길이 · 값 자리 · 값 길이
name_eq이 헤더의 이름이 그것인가(대소문자 안 가림)
header_find · header_find_len그 이름의 값 자리 · 길이. 중복이면 0
content_lengthoption u64 — 없으면 some 0, 성하지 않으면 none
body_off몸통이 시작하는 자리

표 50.1 — http 의 op

이 모듈의 알맹이는 거절이다. 파서는 받아들이는 것보다 거절하는 것으로 정의된다. HTTP 에서 잘못 받아들이는 자리에는 이름이 있다 — 요청 밀반입(request smuggling). 앞단(프록시)과 뒷단(서버)이 같은 바이트를 다르게 읽으면 하나가 본 요청을 다른 하나는 못 본다.

거절하는 것왜
맨 LF 를 줄 끝으로앞단이 CRLF 만 인정하면 경계가 갈린다
이름과 콜론 사이 공백(Host : x)RFC 9112 §5.1 이 거절을 요구한다
Content-Length 가 둘값이 같아도 거절한다
Content-Length: 5, 5 · +5 · 빈 값숫자만 받는다 — 그 관용이 밀반입이다
HTTP/1.0지속 연결 규칙이 다른데 짓지 않았다
같은 헤더가 둘(header_find)합쳐도 되는지는 헤더마다 다르고 그 표를 짓지 않았다 — 모르면 거절
빈 대상(GET HTTP/1.1) · 끝나지 않은 헤더(빈 줄 없음)—

표 50.2 — http 가 거절하는 것

content_length 가 option 인 이유. “없다” 와 “틀렸다” 는 다른 답이다. 없으면 some 0(몸통이 없는 정상 요청), 성하지 않으면 none(연결을 끊어야 할 일). 한 값으로 두면 둘이 섞이고, 섞이는 자리가 곧 공격 자리다.

이 모듈이 처리기 결함을 하나 잡았다. 처음에 input b str . 로 썼다. --check 는 통과했는데 21 op 중 16 이 느린 해석 경로로 떨어졌다(약 80 배). str 은 빌트인이 아니라 strings 의 지역 별칭이었고, 검사기는 그 이름을 통과시켰지만 타입 붙은 하강은 뜻을 몰랐다. 답은 맞으므로 시험이 영원히 보지 못하는 조용한 80 배다. 이제 그런 이름을 시그니처에 쓰면 W-NOT-YET 경고가 나온다. 검사가 통과하는 것과 빠른 것은 다른 일이고, --why-slow 를 보지 않았으면 이 파일은 그대로 실렸을 것이다.

확인하는 것 — RFC 9112 예제(정상 8), 거절 9 건, VM·네이티브 일치, 느린 경로로 떨어지는 op 0 개.