Files
llm-wiki/raw/official-docs/mdn-http-range-fetch-transfer.md

9.8 KiB

title, source_type, url, archive_url, related_branches, related_projects, tags, created
title source_type url archive_url related_branches related_projects tags created
MDN — HTTP Range requests / Fetch 취소·스트림 소비 official-doc https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Range_requests
feature-frontend-large-object-transfer-contract
ca-skeleton-frontend
frontend
http
range
fetch
streaming
transfer
2026-07-28

MDN — HTTP Range requests / Fetch 취소·스트림 소비

Layer: raw/ — 외부 자료의 원문 발췌·출처 기록.

활용 branch (필수, 최소 1개+)

Branch 이 자료가 정당화하는 결정
[[raw/branch-notes/feature-frontend-large-object-transfer-contract]] StreamingDownloadPort 의 재개 프로토콜(D4), part 재시도가 stream 재사용이 아니라 재slice 여야 하는 이유(D6), 취소의 error 매핑(D7)

출처

왜 저장했는지

branch 의 resumeStrategy: range 와 "part 재시도 상한 2회" 가 어떤 프로토콜 사실 위에 서 있는지 확인하지 않은 상태였다. 특히 세 가지가 필요했다. (a) 재개가 서버 지원에 의존한다면 미지원을 어떻게 감지하는가, (b) 재개 중 원본이 바뀌면 무엇이 깨지는가, (c) 실패한 part 를 재시도할 때 이미 소비한 body 를 다시 쓸 수 있는가. (c) 는 재시도 구현이 조용히 빈 body 를 보내는 고전적 버그의 원인이다.

핵심 인용

[§Checking if a server supports partial requests] "If an HTTP response includes the Accept-Ranges header with any value other than none, the server supports range requests."

[§Checking if a server supports partial requests] "If responses omit the Accept-Ranges header, it indicates the server doesn't support partial requests."

[§Requesting a specific range from a server] "If the server supports range requests, you can specify which part (or parts) of the document you want the server to return by including the Range header in a HTTP request."

[§Single part ranges] "The Content-Range response header indicates where this partial message belongs within the full resource."

[§Partial request responses] "A range request that is out of bounds will result in a 416 Requested Range Not Satisfiable status, meaning that none of the range values overlap the extent of the resource."

[§Partial request responses] "If range requests are not supported, an 200 OK status is sent back and the entire response body is transmitted."

[§Conditional range requests] "When resuming to request more parts of a resource, you need to guarantee that the stored resource has not been modified since the last fragment has been received."

[§Conditional range requests] "The If-Range HTTP request header makes a range request conditional: if the condition is fulfilled, the range request will be issued and the server sends back a 206 Partial Content answer with the appropriate body. If the condition is not fulfilled, the full resource is sent back, with a 200 OK status."

[§Using Fetch — Canceling a request] "To make a request cancelable, create an AbortController, and assign its AbortSignal to the request's signal property."

[§Using Fetch — Canceling a request] "To cancel the request, call the controller's abort() method. The fetch() call will reject the promise with an AbortError exception."

[§Using Fetch — Canceling a request] "If the request is aborted after the fetch() call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an AbortError exception."

[§Using Fetch — Streaming the response body] "Request and response bodies are actually ReadableStream objects, and whenever you read them, you're streaming the content."

[§Using Fetch — Locked and disturbed streams] "This means it's not possible to read the same response (or request) body more than once"

[§Using Fetch — Locked and disturbed streams] "if any content has been read from the stream, then the stream is disturbed, and nothing else can read from the stream."

추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
C1 서버의 range 지원 여부는 Accept-Ranges 헤더로 판별하며 none 또는 헤더 부재는 미지원을 뜻한다 [§Checking] "with any value other than none, the server supports range requests" / "If responses omit the Accept-Ranges header, it indicates the server doesn't support partial requests." official-reference 모든 HTTP 응답 특정 스토리지 vendor 가 이 헤더를 보내는지
C2 부분 응답의 위치는 Content-Range 가 알려주며 상태 코드는 206 이다 [§Single part ranges] "The Content-Range response header indicates where this partial message belongs within the full resource." official-reference 206 응답 클라이언트가 요청한 범위와 서버가 준 범위가 항상 같다는 것
C3 범위가 리소스 밖이면 416 Requested Range Not Satisfiable 이 온다 [§Partial request responses] "will result in a 416 Requested Range Not Satisfiable status" official-reference 잘못된 재개 위치 416 이 재시도로 회복 가능한지
C4 range 를 지원하지 않으면 200 OK전체 본문이 온다 — 조용히 성공한 것처럼 보인다 [§Partial request responses] "an 200 OK status is sent back and the entire response body is transmitted." official-reference 재개 시도 200 응답을 받은 클라이언트가 자동으로 이를 알아챈다는 것 — 상태 코드를 검사해야만 안다
C5 재개 시에는 마지막 조각 수신 이후 원본이 변경되지 않았음을 보장해야 한다 [§Conditional range requests] "you need to guarantee that the stored resource has not been modified since the last fragment has been received." official-reference 모든 이어받기 어떤 validator(ETag vs Last-Modified)를 써야 하는지
C6 If-Range 는 조건 충족 시 206, 불충족 시 200 과 전체 리소스를 돌려준다 [§Conditional range requests] "If the condition is not fulfilled, the full resource is sent back, with a 200 OK status." official-reference 조건부 재개 불충족을 오류로 취급해야 하는지 — 프로토콜상 정상 응답이다
C7 AbortControllersignal 로 요청을 취소하며 fetch()AbortError 로 reject 된다 [§Canceling a request] "The fetch() call will reject the promise with an AbortError exception." official-reference 모든 fetch 요청 이미 전송된 바이트가 서버에서 취소된다는 것
C8 응답 수신 후 body 읽기 전에 취소하면 body 읽기가 AbortError 로 reject 된다 [§Canceling a request] "attempting to read the response body will reject with an AbortError exception." official-reference 취소 타이밍이 늦은 경우 두 경로의 error 를 구분해야 하는지
C9 request·response body 는 ReadableStream 이며 읽는 순간 스트리밍된다 [§Streaming the response body] "Request and response bodies are actually ReadableStream objects" official-reference fetch body 요청 body 로 스트림을 넘길 때의 추가 요구사항(duplex 등) — 이 페이지는 다루지 않음
C10 같은 body 를 두 번 읽을 수 없다. 한 번 읽힌 스트림은 disturbed 상태가 되어 누구도 다시 읽지 못한다 [§Locked and disturbed streams] "it's not possible to read the same response (or request) body more than once" / "the stream is disturbed, and nothing else can read from the stream." official-reference 모든 fetch body 재시도가 불가능하다는 뜻은 아님 — 새 body 를 만들면 가능하다

적용 경계

  • 이 자료가 직접 증명하는 것:
    • C1~C6: 이어받기의 지원 판별·위치 표현·실패 코드·조건부 재개
    • C7·C8: 취소의 오류 표면
    • C9·C10: body 스트림의 1회 소비 제약
  • 이 자료가 증명하지 않는 것:
    • 업로드 스트리밍(요청 body 를 ReadableStream 으로 주는 경우)의 요구사항 — duplex 옵션과 HTTP/2 요구를 이 페이지는 언급하지 않는다
    • part 재시도 횟수의 적정값 — 프로토콜은 횟수를 말하지 않는다
    • 어떤 validator(ETag/Last-Modified)를 If-Range 에 써야 하는지
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • 선택할 object storage 가 Accept-RangesIf-Range 를 실제로 지원하는지(FE-Q-012)
    • 스트리밍 업로드가 필요한지, 필요하다면 duplex 지원 매트릭스

메모

  • 인용 1 해석 후보 (미검증): C4 는 조용한 실패의 원천이다. 이어받기를 요청했는데 200 이 오면 클라이언트는 처음부터 다시 받고 있는 중인데도 "재개 성공" 으로 착각하기 쉽다. adapter 는 206 을 명시적으로 확인해야 한다.
  • 인용 2 해석 후보 (미검증): C10 때문에 part 재시도는 원본 Blob 을 다시 slice 해야 한다. 첫 시도에서 만든 body 를 보관했다가 재사용하면 disturbed 스트림을 보내게 된다.
  • 추가로 봐야 할 동일 출처 페이지: Request.duplex, If-Range, Accept-Ranges, AbortSignal.timeout()

관련

  • 같은 주제 다른 official-doc: [[raw/official-docs/aws-s3-multipart-upload-limits]], [[raw/official-docs/mdn-referrer-policy]]
  • 이 자료를 인용한 wiki 요약: 생성 전