Кратко
- Смещение указывает место фрагмента, но не версию представления, из которой этот фрагмент получен.
- Вместе
RangeиIf-Rangeзадают развилку: сильное совпадение сохраняет обработку диапазона, несовпадение заставляет сервер игнорировать его и отправить текущее представление полностью. - Механизм экономит второй запрос и не даёт смешать версии, но не гарантирует поддержку диапазонов, приём, хранение, правильность содержания или подлинность источника.
Точная позиция могла оказаться в другом объекте
Соединение закрывается после первых полутора миллионов байтов. Позже клиент просит всё, начиная со следующей позиции. Если файл не менялся, он разумно избегает повторной передачи. Если за это время архив пересобрали или согласование выбрало иное кодирование, та же позиция лежит уже в другой последовательности. Новый хвост может прийти без ошибок и вместе со старым началом образовать файл, которого никогда не было на сервере.
Повторное соединение не наследовало тождество прежнего представления. Транспорт знал лишь, что поток завершился. Range отвечал на вопрос «где», но не на вопрос «из какой версии». Для безопасного продолжения клиенту требовалось принести отдельное ограниченное свидетельство непрерывности.
В 1997 году RFC 2068 определил If-Range в первой стандартизованной версии HTTP/1.1. Обычный условный GET с диапазоном мог отвергнуть предусловие после изменения сущности. Затем клиенту пришлось бы сделать ещё один запрос за полным текущим телом. Новое поле сокращало путь: если сущность прежняя, отправить недостающие части; если новая — отправить её целиком.
RFC 2616 сохранил эту схему в 1999 году. Совпавший Entity-Tag вёл к поддиапазону с 206 Partial Content. Несовпавший — к полной сущности с 200 OK. Ложное условие не запрещало чтение. Оно отменяло только право достроить старую частичную копию.
Один запрос соглашался на две формы успеха
Поля могли выглядеть так:
Range: bytes=1500000-
If-Range: "edition-58"
Клиент не требовал частичный ответ любой ценой. Он принимал его только пока "edition-58" оставался сильным валидатором выбранного сейчас представления. При расхождении сервер игнорировал Range и отвечал полным телом обычного GET. Клиент должен был заменить старый фрагмент телом 200, а не дописать полный ответ в его конец.
Именно форма ответа отличает If-Range от других условий. If-Match способен остановить операцию и дать 412 Precondition Failed. If-None-Match способен превратить GET в 304 Not Modified без тела. If-Range заранее сообщает, что полная текущая версия тоже полезна. Условие выбирает экономию, а не разрешение на метод.
В 2014 году RFC 7233 выделил семантику диапазонов. Клиент не должен посылать If-Range без Range; сервер игнорирует поле, когда диапазона нет или цель его не поддерживает. При совпадении валидатора диапазон следует обработать, при несовпадении его требуется игнорировать. Поле сокращает второй запрос, но не создаёт отсутствующую возможность частичной выдачи.
Действующая сводка RFC 9110 сохраняет порядок. Для GET с обоими полями истинное условие и применимый диапазон дают 206. Иначе Range игнорируется и ответом становится 200. Ошибки и перенаправления, известные раньше, сохраняют приоритет. Валидатор не обходит обычный выбор представления и проверки запроса.
Для сшивания байтов требовалось сильное равенство
Слабые валидаторы полезны, когда два представления достаточно равнозначны по смыслу, хотя их байты различаются. Для проверки свежести страницы это бывает приемлемо. Для пристыковки одного участка к другому — нет. Даже вставка одного байта в начале сдвигает все последующие координаты.
RFC 7232 связывает сильный валидатор с изменением наблюдаемых данных представления и разрешает использовать его для частичных диапазонов. Слабый предназначен для сравнений без требования точного равенства. Поэтому клиент не может поместить слабый ETag в If-Range. Дата Last-Modified допустима только при отсутствии Entity-Tag и только когда сама считается сильным валидатором.
У дат есть проблема точности. Две версии могут появиться в одну секунду и разделить отметку времени. If-Range сравнивает дату с Last-Modified точно, а не по правилу «раньше или равно» из If-Unmodified-Since. Если время не различает байты уверенно, частичную ветвь нужно закрыть.
Сильный ETag всё равно остаётся непрозрачным значением, а не обязательным криптографическим хешем. Его сила означает, что источник не должен повторять значение для наблюдаемо разных представлений этого ресурса в соответствующем периоде. Он не удостоверяет издателя, не оценивает содержание и не доказывает тождество объекту по другому URL. RFC 2616 прямо предупреждал, что одинаковая метка на разных URI не создаёт эквивалентности.
Совпадение ещё не обещало 206
После успешного сравнения сервер проверяет единицу диапазона, синтаксис, текущую длину и возможность выполнить запрос. Поддерживаемый, корректный и удовлетворимый диапазон обычно получает 206 Partial Content. Одна часть сопровождается Content-Range, несколько — multipart/byteranges. Если ни одна запрошенная позиция не попадает в текущее представление, возможен 416 Range Not Satisfiable.
Content-Range располагает пришедшее тело внутри целого, но не устанавливает версию сохранённого префикса. Эту ограниченную связь даёт общий сильный валидатор. Само совпадение, в свою очередь, не доказывает, что клиент получил все байты, правильно их записал и сохранил.
Последствия ошибок неравны. Лишнее несовпадение повторно передаёт целый объект: это затратно, зато копия остаётся связной. Ложное совпадение способно незаметно породить гибрид. Протокол предпочёл видимый расход невидимой подмене непрерывности.
Кэш стал хранителем происхождения частей
Кэш может держать неполный 200, ответ 206 или несколько раздельных участков. Объединяя их, он принимает ответственность за происхождение. RFC 7234 разрешает хранить неполное только кэшу, понимающему Range и Content-Range. Объединять диапазоны можно лишь при общем сильном валидаторе.
Сплошное покрытие координат не доказывает общую версию. Начало понедельника, середина вторника и конец среды способны заполнить всю длину и остаться тремя объектами. При объединении кэш обязан обновлять метаданные и не выдавать неполное за завершённый ответ 200.
Современный RFC 9111 сохраняет границу. Кэш может дополнить неполный ответ последующим диапазоном, но использовать его как полный разрешено лишь после реального завершения. Частичная выдача должна быть явно отмечена 206. If-Range не хранит и не монтирует данные — он даёт версионное условие для одной серверной развилки.
Проверяемая история отдельно хранит цель, параметры согласования, Range, прежний и текущий валидатор, способ сравнения, статус, Content-Range и хеш собранного объекта. Сервер подтверждает, какую ветвь и тело он отправил. Клиент или кэш подтверждает, что принял и соединил. Одного поля недостаточно для всей цепочки.
Непрерывность без мирового реестра версий
HTTP не потребовал центрально нумеровать каждую редакцию файла и не блокировал ресурс ради отключившихся клиентов. Источник создавал валидатор. Клиент сохранял его с фрагментом. Сервер сравнивал текущий вид. Кэш отвечал за свои части. Решение оставалось у участника с соответствующим наблюдением.
Общий вопрос был узок: можно ли считать новый диапазон ещё одной частью уже имеющегося представления? Ответ «нет» отменял экономию, но не доступ к текущей версии. Такая ограниченность позволила возобновлению работать между реализациями, не превращая сеанс загрузки во власть над ресурсом.
RFC определяют контракт, а не поведение современных продуктов. Они не доказывают силу реального ETag, сохранность у посредника, поддержку диапазонов или запись итогового файла. Для этого нужны захваты запросов и ответов, параметры выбора, история валидаторов, хеши частей и журнал сборки.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров
