본문 바로가기

카테고리 없음

HTTP range requests

HTTP range requests

HTTPS range requests에 대해 확인해 본 내용 정리입니다.

아래의 사이트에서 대부분 참고하였습니다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

 

HTTP range request는 서버에게 리소스의 일부를 클라이언트로 다시 전송하도록 요청하는 것을 정의합니다.

Range requests는 랜덤 액세스를 지원하는 미디어 플레이어나 대용량 파일의 일부만 필요한 데이터 소프트웨어, 사용자가 다운로드를 일시 중지했다가 다시 시작할 수 있는 다운로드 관리자 등의 다양한 클라이언트에서 유용하게 사용될 수 있습니다.

서버가 지원하는지 확인하는 방법

HTTP response에 Accept-Ranges가 포함되는지를 확인합니다.

curl -I http://localhost/text.txt
HTTP/1.1 200 OK
Date: Mon, 11 Nov 2024 07:56:04 GMT
Server: Apache/2.4.41 (Ubuntu)
Last-Modified: Mon, 11 Nov 2024 07:55:10 GMT
ETag: "d3-6269e6b7ab28a"
Accept-Ranges: bytes
Content-Length: 211
Vary: Accept-Encoding
Content-Type: text/plain

Accept-Ranges: bytes가 없다면 지원하지 않는 서버입니다.

서버의 응답

테스트 파일

cat /var/www/html/text.txt
0:ABCDEFGH1:IJKLMNOP2:QRSTUVWX3:YZ1234564:789ABCDE5:FGHIJKLM6:NOPQRSTU7:VWXYZ1238:456789AB9:CDEFGHIJ10:KLMNOPQ11:RSTUVWX12:YZ1234513:6789ABC14:DEFGHIJ15:KLMNOPQ16:RSTUVWX17:YZ1234518:6789ABC19:DEFGHIJ20:KLMNOPQ

 

정상 범위

multipart ranges를 요청하는 예제입니다.

curl -v -H "Range: bytes=0-50, 100-150" http://localhost/text.txt
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /text.txt HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> Range: bytes=0-50, 100-150
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 206 Partial Content
< Date: Mon, 11 Nov 2024 07:57:36 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Last-Modified: Mon, 11 Nov 2024 07:55:10 GMT
< ETag: "d3-6269e6b7ab28a"
< Accept-Ranges: bytes
< Content-Length: 291
< Vary: Accept-Encoding
< Content-Type: multipart/byteranges; boundary=abc428311b9ac486
<

--abc428311b9ac486
Content-type: text/plain
Content-range: bytes 0-50/211

0:ABCDEFGH1:IJKLMNOP2:QRSTUVWX3:YZ1234564:789ABCDE5
--abc428311b9ac486
Content-type: text/plain
Content-range: bytes 100-150/211

10:KLMNOPQ11:RSTUVWX12:YZ1234513:6789ABC14:DEFGHIJ1
--abc428311b9ac486--
* Connection #0 to host localhost left intact

정상적인 응답의 경우 206 Partial Content를 확인할 수 있습니다.

 

비정상 범위

curl -v -H "Range: bytes=1000-1050" http://localhost/text.txt
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /text.txt HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> Range: bytes=1000-1050
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 416 Requested Range Not Satisfiable
< Date: Mon, 11 Nov 2024 08:00:32 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>416 Requested Range Not Satisfiable</title>
</head><body>
<h1>Requested Range Not Satisfiable</h1>
<p>None of the range-specifier values in the Range
request-header field overlap the current extent
of the selected resource.</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at localhost Port 80</address>
</body></html>
* Connection #0 to host localhost left intact

범위가 잘못된 경우 416 Range Not Satisfiable 응답이 확인됩니다.

 

multipart requests error

curl -v -H "Range: bytes=2000-2050, 1000-1050" http://localhost/text.txt
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /text.txt HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> Range: bytes=2000-2050, 1000-1050
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 416 Requested Range Not Satisfiable
< Date: Mon, 11 Nov 2024 08:17:03 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>416 Requested Range Not Satisfiable</title>
</head><body>
<h1>Requested Range Not Satisfiable</h1>
<p>None of the range-specifier values in the Range
request-header field overlap the current extent
of the selected resource.</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at localhost Port 80</address>
</body></html>
* Connection #0 to host localhost left intact

잘못된 range를 Range: bytes=2000-2050, 1000-1050로 포함하고 있습니다.

문서에는 아래와 같이 Content-Range가 포함된다고 하는데 서버의 구현 차이인지는 모르겠습니다.

The 416 response message should contain a Content-Range indicating an unsatisfied range (that is a '*') followed by a '/' and the current length of the resource, e.g., Content-Range: bytes */12777

 

 

https://www.rfc-editor.org/rfc/rfc9110#status.416

A server that generates a 416 response to a byte-range request SHOULD generate a Content-Range header field specifying the current length of the selected representation (Section 14.4).

 

For example:

HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022

 

비정상 범위가 혼합된 경우

curl -v -H "Range: bytes=0-50, 1000-1050" http://localhost/text.txt
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /text.txt HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> Range: bytes=0-50, 1000-1050
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 206 Partial Content
< Date: Mon, 11 Nov 2024 08:00:17 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Last-Modified: Mon, 11 Nov 2024 07:55:10 GMT
< ETag: "d3-6269e6b7ab28a"
< Accept-Ranges: bytes
< Content-Length: 51
< Vary: Accept-Encoding
< Content-Range: bytes 0-50/211
< Content-Type: text/plain
<
* Connection #0 to host localhost left intact
0:ABCDEFGH1:IJKLMNOP2:QRSTUVWX3:YZ1234564:789ABCDE5%

multipart ranges의 경우 일부가 범위에 맞다면 잘못된 범위의 값이 있어도 206 Partial Content 응답으로 처리하는 것을 확인할 수 있습니다.

 

curl -v -H "Range: bytes=1000-1050, 0-50" http://localhost/text.txt
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /text.txt HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> Range: bytes=1000-1050, 0-50
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 206 Partial Content
< Date: Mon, 11 Nov 2024 08:04:13 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Last-Modified: Mon, 11 Nov 2024 07:55:10 GMT
< ETag: "d3-6269e6b7ab28a"
< Accept-Ranges: bytes
< Content-Length: 51
< Vary: Accept-Encoding
< Content-Range: bytes 0-50/211
< Content-Type: text/plain
<
* Connection #0 to host localhost left intact
0:ABCDEFGH1:IJKLMNOP2:QRSTUVWX3:YZ1234564:789ABCDE5%

range의 순서가 바뀌어도 동일합니다.
첫 번째 정상 범위의 multipart ranges와 다른 점은 Content-Type: multipart/byteranges;이 아닌 Content-Type: text/plain인 점입니다.
정상 범위에 대한 Content-Range: bytes 0-50/211가 표시됨을 확인할 수 있습니다.