Debug a request verbosely

요청·응답의 실제 헤더와 TLS 핸드셰이크까지 자세히 출력해 문제의 원인을 눈으로 확인하는 디버깅 레시피입니다.

개요

요청·응답의 실제 헤더와 TLS 핸드셰이크까지 자세히 출력해 문제의 원인을 눈으로 확인하는 디버깅 레시피입니다.

코드로 보기

# -v prints request/response headers and TLS handshake:
curl -v https://api.example.com/data

# --trace-ascii dumps full request + response bodies to a file:
curl --trace-ascii trace.txt https://api.example.com/data
// Node: log the outgoing request and the response you get back
const opts = { method: 'GET', headers: { Accept: 'application/json' } };
console.log('->', opts);
const res = await fetch('https://api.example.com/data', opts);
console.log('<-', res.status, Object.fromEntries(res.headers));
console.log(await res.clone().text());
import logging, http.client, requests

http.client.HTTPConnection.debuglevel = 1  # dump wire-level traffic
logging.basicConfig(level=logging.DEBUG)

res = requests.get('https://api.example.com/data')
print(res.request.headers)  # what was actually sent

설명

curl `-v`는 보낸 요청 라인·요청 헤더(`>`), 받은 응답 헤더(`<`), TLS 인증서·프로토콜 협상 정보를 모두 보여줍니다. 본문까지 포함해 전체를 파일로 남기려면 `--trace-ascii <파일>` 또는 바이너리까지 보는 `--trace`를 쓰세요.

`requests`에서는 `http.client`의 `debuglevel`을 켜면 소켓 수준 트래픽이 로그로 나오고, `res.request.headers`로 라이브러리가 실제로 붙인 헤더(기본 `User-Agent`, 자동 인코딩 등)를 확인할 수 있습니다. 브라우저에서는 개발자도구 Network 탭이 사실상 최고의 관찰 도구입니다.

주의: verbose 출력에는 `Authorization`·`Cookie`·토큰 같은 민감 정보가 그대로 찍힙니다. 로그를 공유하거나 이슈에 붙일 때는 반드시 마스킹하세요. 401·403·CORS·리다이렉트 루프처럼 '왜 이렇게 동작하지?' 싶을 때 가장 먼저 켜 보는 도구입니다.

관련 헤더

관련 상태코드