녹음 저장소를 붙이면서 작은 파일 하나를 업로드하는 검사를 만들었습니다. SDK를 대역으로 바꾸면 서비스가 SDK를 호출했는지만 볼 수 있습니다. 실제 SDK가 메서드, 경로, 인증 헤더와 본문을 어떤 모양으로 보내는지 보려고 로컬 HTTP 서버를 저장소 주소로 넣었습니다.
원본은 3바이트였습니다. 대역 서버가 받은 본문은 175바이트였고, 본문을 그대로 원본과 비교하던 검사가 실패했습니다.
전송 본문에 붙은 청크 서명
대역이 받은 본문에는 청크 길이와 청크별 서명이 들어 있었습니다. 이 요청의 SDK는 파일 데이터를 aws-chunked 형식으로 감쌌고, 데이터가 끝나는 지점도 크기 0인 청크로 표시했습니다. 그래서 전송 본문의 길이에는 원본 외에 프레이밍과 서명 정보까지 포함됐습니다. AWS 문서에서 x-amz-decoded-content-length는 이 메타데이터를 제외한 원본 길이입니다. AWS SigV4 청크 업로드 문서
HTTP 자체의 Transfer-Encoding: chunked와는 다른 층입니다. 서버가 HTTP 요청 본문을 읽은 뒤에도 본문 안에 AWS 서명 청크가 들어 있을 수 있습니다.
청크를 풀어 원본과 비교
테스트 대역에서 서명 청크의 길이를 읽고 데이터 부분만 이어 붙이도록 바꿨습니다. 그렇게 얻은 바이트 배열을 원본 3바이트와 비교했습니다. 메서드와 객체 경로, 서명 헤더는 별도로 확인했습니다. 원본이 같아도 잘못된 경로로 요청을 보내면 검사에서 드러납니다. 청크를 푼 뒤 원본과의 비교를 포함해 로컬 SDK 업로드 검사가 통과했습니다.
엔드포인트와 체크섬 설정
저장소 연결에서는 SDK에 별도 엔드포인트를 넘기고, 버킷 이름이 호스트가 아니라 요청 경로에 들어가도록 했습니다. 호환 업체마다 체크섬 지원이 다를 수 있어 요청 체크섬 계산과 응답 체크섬 검증도 WHEN_REQUIRED로 설정했습니다. 이는 API가 체크섬을 요구할 때 계산하거나 검증하도록 정한 연결 설정입니다. 테스트 본문의 크기 차이는 이 설정을 바꾸는 대신 서명 청크에서 데이터 부분을 읽어 해결했습니다.
175바이트는 당시 설정의 SDK가 로컬 HTTP 대역에 보낸 요청 한 건의 관측값입니다. 실제 R2의 HTTPS 요청 본문도 같은 크기라는 뜻으로 사용할 수는 없습니다. 이 검사는 저장소를 흉내 내면서도 SDK의 직렬화와 요청 서명 경로를 실제로 거친다는 데 가치가 있었습니다.

댓글
댓글과 반응은 GitHub 계정으로 로그인해 남길 수 있어요.