curl로 저장한 본문이 깨질 때: UTF-8보다 gzip부터 확인한다
curl로 저장한 gzip 응답을 UTF-8 오류로 오해하지 않도록 기본 요청·--compressed·--raw의 실제 저장 바이트를 비교한다. Accept-Encoding 헤더만 추가했을 때의 차이와 자동 해제 뒤에도 남는 응답 헤더를 확인하고, 텍스트 저장과 기존 파일 복원 방법을 설명한다.
빌드노트
HTTP·네트워크 카테고리의 글입니다.
총 48개의 글
curl로 저장한 gzip 응답을 UTF-8 오류로 오해하지 않도록 기본 요청·--compressed·--raw의 실제 저장 바이트를 비교한다. Accept-Encoding 헤더만 추가했을 때의 차이와 자동 해제 뒤에도 남는 응답 헤더를 확인하고, 텍스트 저장과 기존 파일 복원 방법을 설명한다.
쿼리에 직접 붙인 a+b는 form-urlencoded 파싱 뒤 a b로 읽힌다. 로컬 HTTP 요청에서 직접 보간·원문 append·미리 인코딩한 값 append를 비교하고, URLSearchParams에 원문을 전달해 +를 보존하는 방법과 이중 인코딩을 피할 위치를 설명한다.
HEAD 응답의 Content-Length는 같은 요청을 GET으로 보냈을 때의 본문 길이를 나타낼 수 있다. 실제 GET·HEAD의 수신 바이트와 curl -I·-i를 비교하고, 빈 HEAD 본문을 전송 잘림이나 대기 오류로 오해하지 않는 판단을 설명한다.
Node http.request의 생성, 헤더 전송, 본문 종료를 구분한다. loopback 실험으로 write·flushHeaders·end와 http.get의 차이를 확인하고, 서버의 응답 정책과 Content-Length 때문에 응답 유무만으로 end 호출을 판단할 수 없는 이유를 살펴본다.
응답에 ISO-8859-1을 선언해도 Fetch의 text()는 UTF-8로 읽는다. 같은 café 바이트에서 헤더만 바꾼 결과와 실제 UTF-8 변환을 비교하고, 서버 출력 수정과 arrayBuffer·TextDecoder 중 적용할 방법을 고른다.
같은 POST가 keepalive일 때만 큰 본문에서 실패하면 UTF-8 바이트 수와 진행 중 전송을 확인한다. 실제 Chrome에서 65,536·65,537바이트의 서버 수신 차이와 HTTP 413 응답을 비교해, 서버 업로드 제한과 브라우저 예산을 구별한다.
curl --data에 원문 폼 값을 붙이면 값 속의 &가 필드 구분자로 읽힌다. 같은 A&B + C를 POST로 보내 수신 본문과 필드 수·값을 비교하고, 필드마다 --data-urlencode를 쓰는 방법과 사전 인코딩을 제거할 위치를 설명한다.
localhost 요청의 실제 목적지와 Listen 주소를 비교한다. 소유한 IPv4·IPv6 loopback 리스너에서 curl -4/-6와 숫자 주소를 실행해 접속 결과를 확인하고, 기본 요청 성공과 두 계열 수신을 구분한다.
fetch의 Promise 이행과 HTTP 성공은 별개다. Node 내장 fetch로 200·404·500 JSON과 끊긴 연결을 비교하고, HTTP 상태와 오류 본문을 보존하면서 요청 실패와 본문 읽기 실패를 나누는 코드를 확인한다.
Node HTTP 서버의 첫 write 전후에 headersSent를 비교하고, 늦은 setHeader 오류와 실제 클라이언트 응답을 확인했다. 상태·헤더 결정을 본문 쓰기 앞으로 옮기는 수정과, 늦은 statusCode 대입이 예외 없이도 실제 응답을 바꾸지 못한 결과를 설명한다.
--cookie-jar는 쿠키 저장용이고 --cookie는 파일 읽기용이다. 새 curl 프로세스의 실제 Cookie 헤더를 비교해 로딩 누락과 Path 불일치를 구분하고, 갱신된 쿠키를 다음 실행에 보존할 옵션을 고른다.
FormData 전송에 수동 Content-Type을 넣으면 boundary가 누락되거나 본문과 달라질 수 있다. 실제 브라우저의 네 요청에서 헤더·경계 바이트·파싱 결과를 대조하고, 브라우저가 multipart 헤더를 만들도록 수정하는 방법을 설명한다.