Summary

  • Byte Range PATCH 05판은 부분 PUT을 지원하지 않는 서버가 Content-Range를 무시하고 받은 조각으로 리소스 전체를 교체할 수 있다고 설명한다.
  • message/byterange는 하나의 연속된 쓰기 범위를 PATCH 문서에 포함한다. 범위를 알 수 없는 패치는 서버가 400 또는 422로 거절해야 한다.
  • 부분에 표시된 Content-Length는 범위의 길이와 정확히 맞아야 한다. 빈 구간이 있는 파일을 허용하더라도 초기화되지 않은 내용은 노출하면 안 된다.

초안의 예시는 아주 작다. 원래 파일에는 0123456789와 줄 끝 문자가 있다. 2번부터 5번 위치에 wxyz를 쓰면 결과는 01wxyz6789와 같은 줄 끝 문자여야 한다. 서버가 요청 본문을 새로운 전체 파일로 받아들이면 wxyz만 남는다. 전송 과정에 오류가 없어도 파일이 사라질 수 있는 이유다.

문제의 핵심은 PUT에 붙인 Content-Range의 권한이다. 초안 2절은 이런 부분 PUT이 서버의 별도 지원을 요구한다고 적는다. 그 지원이 없으면 서버는 범위 필드를 넘기고 PUT의 일반적인 전체 교체를 수행할 수 있다. 클라이언트는 위치를 정확히 밝혔지만, 수신자는 그 위치를 따르겠다고 약속한 적이 없다.

제안된 방법은 PATCH 문서의 형식 자체에 쓰기 위치의 의미를 담는다. message/byterange는 한 범위, multipart/byteranges는 여러 범위, application/byteranges는 이진 형식에 쓰인다. 단일 범위 문서에는 Content-Range: bytes 2-5/12와 wxyz가 함께 들어간다. 서버가 그 형식을 지원하면 지정한 부분을 바꾸고, 모르면 파일을 건드리기 전에 거절해야 한다. 눈에 보이는 거절은 다시 시도할 수 있지만, 조용한 전체 교체는 나중에야 발견된다.

위치를 모르면 쓰지 않는다

각 부분은 연속된 범위 하나를 지정해야 한다. 위치를 모르는 요청에는 400 또는 422가 필요하다. 부분의 Content-Length가 있다면 범위의 길이와 정확히 일치해야 한다. 네 바이트를 쓰라는 명령에 다섯 바이트가 들어왔을 때 서버가 임의로 처리하지 못하게 하는 계산이다. 끝 위치를 알 수 없는 흐름에는 Content-Offset이 시작점을 제공한다. 파일의 최종 크기를 몰라도 어디부터 쓰는지는 알아야 한다.

파일의 끝도 엄격한 경계다. 바로 다음 위치에 쓰면 파일이 길어진다. 더 멀리 뛰어 쓰면 정의되지 않은 빈 구간이 생긴다. 초안은 이런 도약을 거절하라고 권고한다. 빈 구간을 허용하는 서버는 초기화되지 않은 자료를 유출해서는 안 되며, 정의되지 않은 구간을 0으로 채우는 편이 좋다. 성공 코드만 확인하는 시험으로는 저장된 파일의 구멍을 찾을 수 없다.

4절의 Prefer: transaction=atomic과 transaction=persist는 전송이 끊겼을 때 받은 내용을 되돌릴지 남길지에 관한 선호다. 서버는 적용한 선호를 Preference-Applied로 알리는 것이 권장된다. 중단 처리보다 먼저 정해야 할 일이 있다. 이 네 바이트가 기존 파일의 일부인지, 새 파일 전체인지다.

RFC 5789의 Accept-Patch는 서버가 받는 PATCH 형식을 알리는 수단이다. 여러 실제 서버에서 같은 범위 PUT과 message/byterange PATCH를 비교한 공개 기록은 아직 부족하다. 전후 바이트, 응답, ETag를 함께 기록하면 구현의 차이가 드러난다.

초안과 판본 · RFC 5789 · RFC 9110