Комментирование скриптов в vbscript
В vbscript символ одиночной кавычки воспринимается, как начало комментария, который продолжается до конца строки. Это может быть использовано для того, чтобы спрятать "-->" от vbscript. Например:
<script type="text/vbscript">
<!--
sub foo()
...
end sub
' -->
</script>
Критерии проектирования
Критерий проектирования, который наиболее часто используется, заключается в том, что суррогатом для ограничения всетерминальной надежности служит ограничение связности, т.е. ограничение, требующее, чтобы связность была, по крайней мере, с. Обобщение этого критерия на SCBS (и на другие классы систем, включая k-терминальные проблемы и определенные меры работоспособности) является ограничением, которое определяет то, что SCBS не содержит набора разрезов с размером с-1 или меньше. Вероятно, наиболее типичным сценарием является случай, где с=2. С с=2 конструктивный критерий утверждает, что система не должна содержать ни одной точки отказа.
Рассмотрим уровень надежности, гарантированный критерием проектирования. Если нет набора разрезов размером с-1 или меньше, тогда нижняя граница надежности системы будет получена в предположении, что каждый набор элементов размером с является набором разрезов. Для m-элемента SCBS надежность этой системы будет равна надежности системы К из N при K=m-c и N=m. Предполагая равные вероятности отказов, надежность системы может быть:
Эта величина равна наилучшей возможной нижней границе уровня надежности системы, гарантированной при ограничении с-связности в предположении, что никакой дополнительной информации о структуре системы не известно. Мы заметим, что при с=2, это ограничение получается для случая всетерминальной надежности с помощью простого цикла.
Обычно очень важно вычислить это ограничение и учесть его при проектировании сети. Часто случается, что значение ограничения ниже, чем ожидалось. Если это происходит, то либо критерий проектирования (значение с) должен быть увеличен, либо должен быть предпринят более детальный анализ надежности совместно с возможными модификациями конструкции. Раз при проектировании сети гарантированы более сложные метрики надежности, задачей сетевого интегратора должно быть не просто получение числового значения надежности, он скорее должен иметь в виду влияние сетевой топологии на возможность сети выполнять необходимые функции. В конечном итоге, рассмотренные здесь методики получения числовых значений надежности, имеют целью не просто дать алгоритм для получения чисел, а скорее предоставить средства для определения того, как определенные части сетевой структуры воздействуют на работоспособность сети.
Локальные оптоволоконные сети для передачи голоса
Оптические кабели - одно из последних достижений современной технологии. Телекоммуникационные сети всего мира переводятся на использование этой техники (смотри, например, T. Flanagan, “Fiber Network Survivability” IEEE Communication Magazine 28 (1990) 46-53). В оптоволоконных каналах данные транспортируются при помощи световых волн, передаваемых по волокнам кварца. Основным преимуществом оптической среды передачи по сравнению с передачей по медным кабелям является существенный рост пропускной способности и снижение уровня шумов. Именно по этой причине многие телефонные сети общего пользования осуществляют быстрый переход на оптику. Как, однако, оказалось, в проблематике надежности сетей существуют более важные проблемы и именно их следует изучать. А именно: пропускная способность оптоволоконных сетей чрезвычайно высока, поэтому структура таких сетей в отличие от обычных имеет более распределенный характер. Старые сети были более разветвленными и имели большое число связей, вопрос сетевой надежности стоял не так остро. При проектировании современных сетей следует серьезно отнестись к проблеме сетевой надежности, т.к. перебои в работе даже одного из оптических каналов могут вызвать разрыв сети.
К оптическим каналам добавляют каналы-дублеры с возможностью переключения между основным и дублирующим каналом. При этом желательно, чтобы трассы их прокладки не совпадали (по стране рыскают бульдозеры и экскаваторы так и норовящие порвать любые кабели). В результате мы сможем применить к оптической сети уже имеющиеся методы оценки надежности.
Меры сетевой надежности
Сетевые меры надежности, которые мы изучаем, являются либо вероятностями определенных случайных событий, либо ожидаемыми значениями случайных переменных, которые зависят от структуры сети, расстояний и пропускной способности, ассоциированными с членами Е и вероятностями соответствующих событий. Большинство исследований по сетевой надежности, также как и большая часть нашей статьи посвящены к-терминальным мерам (см. раздел 1).
Мера работоспособности оценивает надежность сети относительно некоторых критериев функционирования. Было рассмотрено несколько критериев функционирования. Например, в сетях с коммутацией пакетов в качестве параметра используют среднюю задержку, возникающую при доставке пакета или сообщения (RTT). Такие критерии можно рассматривать, как случайные переменные, так как они зависят от набора рабочих дуг, от пропускной способности каждой дуги или расстояния, которые являются случайными переменными. Если Ф случайная переменная критерия, тогда рассматриваются два класса мер работоспособности:
· Pr[Ф?a] или Pr[ФЈa], вероятность достижения порогового значения, и
· Ex[Ф], ожидаемое значение для величины Ф
Пусть заданы два терминала s и t, и распределение пропускной способности (расстояния дуги), определяем ФFLOW как величину max(s,t)-потока, а ФPATH как величину наикратчайшего пути (s,t). Рассмотрим следующие меры производительности:
FT(G,s,t,{се,i, pе,i },fthresh) = Pr[ФFLOW? fthresh]
ST(G,s,t,{dе,i, pе,i}, lthresh) = Pr[ФPATH Јlthresh]
FE(G,s,t,{се,i, pе,i }) = Ex[ФFLOW]
SE(G,s,t,{dе,i, pе,i }) = Ex[ФPATH]
Для этих мер, s относится к исходному узлу, а t - к терминальному.
Метод наиболее вероятных состояний
Метод наиболее вероятных состояний является ограничивающей процедурой, которая может быть применена к достаточно общему классу многопараметрических проблем. Единственным требованием является эффективное вычисление Ф. Мы описываем его применение к метрике работоспособности Pr[ФЈa]. Приложение к E[Ф] осуществляется аналогично. Предположим, что состояния сети упорядочены
, где s = qn, такое что
Метод наиболее вероятных состояний базируется на нумерации состояний в этом порядке. Важность использования этого порядка заключается в том, что процесс может быть завершен раньше с хорошим ограничением. Определим lpФ(k) и upФ(k) как нижнее и верхнее ограничение, для
. Верхнее и нижнее ограничения обычно используются здесь, как легко вычислимые, и, фактически, в большинстве случаев являются тривиальными границами, которые не зависят от k. Для систем с двумя состояниями, если pe равно вероятности “хорошего” состояния для ребра
е, а qe - вероятности “плохого” состояния для ребра
е, типичным предположением служит то, что pe ? qe и как следствие
, так что мы можем установить
и
для всех k. Ограничения для наиболее вероятных состояний определяются как
Здесь
может определяться динамически на основе некоторого критерия остановки. Наиболее типичным критерием является требование того, чтобы разность между верхним и нижним ограничениями лежала в допустимых пределах. Нижнее и верхнее ограничение для ожидаемого значения метрики могут быть определены аналогичным образом.
Сансо и Саумис предположили, что вместо нумерации по наиболее вероятным состояниям, много лучше осуществлять нумерацию по “наиболее важным” состояниям. Аргументация заключается в том, что в некоторых ситуациях определенные мало вероятные состояния, которые могут быть не пронумерованы, оказывают большое влияние на метрику работоспособности системы. Такие состояния могут соответствовать ситуациям, в которых система демонстрирует крайне плохую работоспособность. В частности,
может быть относительно мала, но
может быть очень велико или очень мало. Это особенно важно при вычислении ограничений Е[Ф].
Метод покрытия
Точность схем Монте-Карло, представленных выше обычно оценивается по вариации оценки
. Оценка вариации в каждом случае оказывается грубо равной a/K, где К - число проб, а a - некоторая константа, которая зависит от R и типа производимых испытаний. Таким образом, грубое аналитическое сравнение этих оценок может быть сделано на основе относительных значений a. Действительная величина вариации зависит от многих других факторов, и при линейном уменьшение К время испытаний может стать критическим. Таким образом, сравнения в действительности следует делать на эмпирической основе.
Метод покрытия разработан Карпом и Луби [R.M.Karp, M.Luby “Monte Carlo algorithms for the planar multiterminal network reliability problems”, J. Complexity 1 (1985), 45-64] и базируется на более жестком критерии, требующем большей эффективности от схемы Монте-Карло. В частности, пусть e и d являются положительными скалярами. Предположим, что мы хотим вычислить некоторую относительную меру значения R, и пусть
является результатом оценки R некоторой схемы Монте-Карло. Тогда оценка
является e-d аппроксимацией для R, если
Схема Монте-Карло называется полной полиномиальной рэндомизованной аппроксимацией FPRAS, если, кроме того, время получения оценки
имеет порядок e-1, log(d-1). Грубо говоря, FPRAS является алгоритмом, который эффективно осуществляет оценку R, чья относительная ошибка с высокой вероятностью может быть гарантировано малой.
Схема Монте-Карло Карпа-Луби является в действительности гибридом методов приоритетных и послойных выборок, и использует миниразрезы системы для улучшения наивной схемы выборок. Чтобы сохранить совместимость со статьей Карпа-Луби, мы рассматриваем вычисление R=Pr[Ф=0], т.е., вероятность отказа системы, если даже можно разработать аналогичную схему с точки зрения работы системы. Идея встроить набор F событий отказов в универсальное взвешенное пространство (U,w) - где w является неотрицательной весовой функцией для элементов U, которые удовлетворяют следующим критериям:
· w(F)=Pr(F) = R
· w(U) эффективно вычисляемо (т.е. за полиномиальное время), выборка событий может быть эффективно осуществлена из U с вероятностью, пропорциональной их весу.
· Можно эффективно распознать, когда элемент из U принадлежит также и F.
· w(U)/w(F) ограничено сверху некоторой величиной М для всех случаев класса задач
Тогда ясно, что если осуществлена выборка из U и определена оценка
путем умножения доли этой выборки, которая содержится в F, на w(U), тогда
является несмещенной оценкой R. Установлено, что для любых положительных скаляров e e и d, если размер выборки равен, по крайней мере, Mґln(2/d)4.5/e2, тогда результирующая оценка
является e-d аппроксимацией для R. Другими словами, эта схема выборки является FPRAS.
Теперь рассмотрим метод покрытия с точки зрения его использования для проблемы надежности (s,t)-связности, хотя та же методика может быть применена для широкого круга ситуаций. Пусть (G,s,t,p) является примером проблемы надежности (s,t)-связности и пусть С является минимальным набором (s,t)-разрезов для G. Определяем универсальное взвешенное пространство U, которое состоит из пар (х,С), где х - вектор состояния, СО С, и хе=0 для всех e ОC. Вес, приписываемый каждой паре (х,С) просто равен Р(х). Теперь каждое состояние отказа х системы отражается в элементах U столько раз, сколько требуется мини разрезов для отказа х. Для того чтобы F входило в U, необходимо приписать каждому х уникальное СОС. В проблеме (s,t)-связности это сделано с помощью нахождения набора элементов, которые могут быть достижимы от s через рабочие ребра (с учетом х) и установки СєС(х), соответствующих ребрам их Х в V\X. Элементы F теперь появляются в U, >как (х,С), такие что С=С(х), а элементы U могут быть определены на долгое время соответствующими элементу F путем проверки условия С=С(х). Метод покрытия для задачи (s,t)-связности рассмотрен ниже.
Метод покрытия
1. Определяем множество С набора (s,t)-разрезов G. Для каждого СО С вычисляем w(C)=ПeО Сqe = полному весу всех элементов U со второй компонентой, равной С, и затем вычисляем w(U) =3СО Сw(C).
2. Осуществляем выборку элементов (x,C) из U в пропорции их весов при первом розыгрыше С из С с вероятностью w(C)/w(U) и затем производим розыгрыш х путем установки хе=0, eОС, и приписав другим компонентам х значения согласно их вероятностям.
3. Вычисляем долю
, когда событие (х,С) имеет С=С(х). Тогда
(U) является несмещенной оценкой R.
Рассмотренная выше схема не является FPRAS по двум причинам. Во-первых, необходимо нумеровать все разрезы в наборе С и мощность набора растет экспоненциально с ростом объема задачи. Во-вторых, условие ограничения для w(U)/w(F) не удовлетворяется для общих случаев задачи. Карп и Луби однако, модифицировали процедуру, описанную выше, для случая задач надежности (s,t)-связности, где граф G является плоским и однонаправленным и ограничения сопряжены с множественностью и суммарной вероятностью, а также выполняется условие ограничения сверху ПeО С(1+qe) некоторым фиксированным М.
Мы здесь не вдаемся в детали, главная идея заключается в расширении С, чтобы включить разрезы, которые являются “почти минимальными”, таким образом, чтобы ассоциированное пространство U, определенное выше, удовлетворяло требуемым свойствам с учетом F. Плоскость G используется, чтобы разрешить эффективную выборку элементов расширенного пространства U с правильными вероятностями, так чтобы модифицированная схема для задач надежности (s,t)-связности стала FPRAS.
Методики ограничений
Из-за особо сложной природы проблем надежности сетей с большим числом состояний, центром тяжести разработок в этой области является подготовка методик для ограничений различных систем метрик, представляющих интерес. Эти методики часто существенно отличаются от тех, что используются для проблем с двумя состояниями.
Исторически первой использовалась методика для аппроксимации надежности в стохастических сетях и среди них одна, которой уделялось наибольшее внимание, возникает из интуитивно привлекательной идеи, что ожидаемое значение E[Ф] длины кратчайшего пути/максимального потока/времени завершения может быть получено путем замены случайной длины/максимального потока/времени завершения для каждого ребра на детерминистский параметр, чье значение равно ожидаемой величине, и последующего решения детерминистского варианта проблемы. Это было фактически методикой решения, предложенной в оригинальном рассмотрении PERT в работе Малькольма и др. [D.G.Malcolm et al, “Application of a technique for research and development program evaluation”, Oper. Res. 7 (1959), 646-669]. Кажется фольклором то, что значение, полученное с помощью этой методики является верхней границей истинного значения ЕФ в проблеме PERT и нижней границей в проблемах наикратчайшего пути и максимального потока.
Наиболее успешные исследования концентрируются вокруг аппроксимации значения cdf F(a) =Pr[ФЈa] для Ф. Методика вначале была применена к проблеме PERT с непрерывными значениями параметров ребер, но может быть модифицирована для применения к проблемам кратчайшего пути, наибольшего потока и для случайных переменных ребра с дискретным распределением. В частности, предположим, что нужно вычислить число a, для которого FPERT(a)=b для некоторой специфицированной вероятности b. Заменяем каждую случайную переменную ребра Те на te, для которого Pr[TeЈ te]= b, и решаем для детерминистского значения наикратчайшего времени завершения. Полученная величина снова является верхней границей действительного времени завершения проекта, выдавая cdf значения b.
Улучшения выше описанной схемы для проблемы PERT заключается в вычислении для каждой вершины v в графе распределения для промежуточных случайных переменных
Фv= наидлиннейший маршрут до вершины v.
Во всех случаях вычисления производятся в топологическом порядке v1= s,v2,…,vn, т.е. все ребра, указывающие на vi исходят из вершин vj с j<i. Данная схема служит для вычисления нижней границы
для E[Фvi], используя достаточно простую рекурсивную формулу
j = 2,…,n
суммирование производится по всем векторам b= ( bji: j<I) значений параметра, которые могут быть приняты для ребер, указывающих на вершину vi (члены, где (vj,vi) не существуют, игнорируются). Улучшения этой методики первоначально включали в себя оценки cdf значений Fi(a) для Фvi, в частности, вычисление верхней и нижней границы
и
, соответственно. Заметим, что эти величины могут использоваться по очереди, чтобы вычислить нижнюю и верхнюю границы, соответственно для значений E(Фvi), используя элементарную формулу
Все они используют одну и ту же формулу с
для всех неотрицательных a (и нуль в противном случае).
Соответствующие ограничения для Е[Фvi] могут быть также упорядочены и их нижние ограничения лучше, чем полученные Фулкерсоном, нижние ограничения Фулкерсона и Кляйндорфера не могут быть единообразно сравнены. Ограничения Фулкерсона, Кляйндорфера и Шогана могут быть также модифицированы при использовании для проблемы кратчайшего пути (если исходный граф не содержит циклов) и для случая непрерывных параметров ребра. Ограничения Кляйндорфера априори вычисляемы за полиномиальное время.
Здесь мы предполагаем, что случайное значение пропускной способности Се является двоичным с ”рабочим” состоянием, представляющим нормальную пропускную способность се с вероятностью ре, и состоянием отказа, представляющим пропускную способность нуль с вероятностью 1-ре. Пусть Г1,…,Гr является набором всех цепочек (s,t) в G и пусть h1,…,hr равны потоку для каждого r цепочки (s,t). Этот значение потока верно, если для каждого ребра е в G, сумма потоков цепочки последовательных ребер, проходящих через е, меньше чем или равна пропускной способности е, а величина потока равна
.
Рассмотрим любую фиксированную цепочку потоков h1,…,hr, которая корректна для нормального набора пропускных способностей (се: eОE). В стохастической модели конкретная цепочка Гk может, следовательно, дать запрошенную долю потока hk, если и только если все ее ребра находятся в рабочем состоянии, в противном случае выдается нуль. Крайняя вероятность реализации этого равна, следовательно,
. Во-первых, заметим, что значение Е[ФFLOW] очевидно, по крайней мере, также велико, как ожидаемое значение случайного потока, полученного путем допущения потока вдоль каждой цепочки Гk, равного hk, несмотря на рабочие условия других цепочек, использующих те же ребра, что и Гk. Это ожидание в свою очередь равно сумме ожидаемых значений потоков для каждой из цепочек Г1,…,Гr, рассматриваемых как независимые случайные переменные.
Метод группировки ребер и непересекающихся разрезов, обсужденные в разделах 4.2.1 и 4.2.2, предоставляют также эффективный способ расчета ограничений для проблем сетей с большим числом состояний. В частности, пусть Р1,…,Рq и Г1,…,Гr являются наборами разъединенных (s,t)-маршрутов и (s,t)-разрезов, соответственно. Эти два набора дают естественные верхние и нижние границы функций ФL и ФU для действительной функции Ф, зависящей от проблемы:
Кратчайший путь:
Максимальный поток:
Работоспособность сети PERT:
Эти функциональные ограничения в свою очередь дают естественные границы как для cdf, так и для действительной функции Ф, в частности,
и
Далее, каждая функция, описанная выше, состоит из одного min/max и одной свертки, поэтому cdf и ожидания для всех этих функций могут быть вычислены за полиномиальное время.
Две разные методики ограничений, представленные в разделе 4.2.4, были изучены в контексте проблем для систем со многими состояниями.
Методы, базирующиеся на маршрутах и разрезах
Когда базовые редуцирования выполнены, для завершения вычислений можно применить полный подсчет состояний. Если только редуцирования не приводят к существенному уменьшению размера графа, такая схема непрактична. Несмотря на это, можно сформировать все минимальные пути сети и, следовательно, метод, использующий минимальные маршруты, будет работать. Предположим тогда, что минимальные пути P1,…,Ph графа G посчитаны. Пусть Ei является случаем, когда все ребра минимаршрута Pi работоспособны. Тогда надежность равна вероятности того, что произошло одно (или более) событий {Ei}. К сожалению, {Ei} не являются независимыми и, следовательно, мы не можем просто суммировать вероятности их реализации. Точнее Pr[E1 или E2] равна Pr[E1] + Pr[E2] - Pr[E1 и E2]. Теперь Rel(G) = Pr[E1 или E2 или … или Es], и, следовательно,
(1)
где EI является событием, когда все пути Pi c iОI находятся в рабочем состоянии. Это является стандартным расширением включения-исключения.
Имея список минимальных путей, вычисляется вероятность для каждого реализованного субнабора минимальных путей. Чтобы вычислить надежность, необходимо только определить выше представленную сумму. Выполняя это, следите, чтобы нечетные минипути давали вклад с плюсом, а четные - с минусом. Это сводит нашу проблему к определению набора всех минимаршрутов. Наивная реализация этого подхода фактически хуже, чем полный подсчет состояний. Число наборов путей h может быть показательной функцией n и, следовательно, только формирование минипутей требует экспоненциального времени. Однако более серьезным недостатком является то, что генерирование всех субнаборов наивным способом занимает 2h времени, которое предоставляет нам дважды экспоненциальный алгоритм вычисления надежности.
Приняв меры, можно избежать двойного экспоненциального поведения. Каждый субнабор минипутей соответствует субграфу, ребра которого являются объединением наборов ребер минипутей. Учитывая это, i-структура субграфа является набором i минипутей, чье объединение является субграфом.
Структура является нечетной, когда i нечетно, и четным, когда i четно. Граф, имеющий структуру, является К-субграфом. Каждая нечетная структура субграфа вносит положительный вклад в надежность, а каждая четная структура дает негативный вклад. Знаковая доминантность G с терминальным набором вершин К, sdom(G,K), равна числу нечетных структур G минус число четных структур G. Доминантность dom(G,K) равна абсолютному значению знаковой доминантности. Мы обычно пишем sdom(G), а подразумеваем dom(G) с терминальным набором К. С учетом этих определений Сатианарайана и Прабхокар существенно упростили выражение для надежности:
,
где Н пробегает все состояния G. Это упрощение является существенным, так как влечет за собой только формирование всех состояний, а не генерацию всех субнаборов минимаршрутов. Однако нужны еще некоторые усилия, если мы должны улучшить подсчет всех состояний. В частности, нам теперь нужна знаковая доминантность каждого состояния.
Первой целью является определение того, какие состояния имеют знаковую доминантность равную нулю, и могут, следовательно, игнорироваться в выражении для надежности. Учитывая это, состояние (субграф) является релевантным, если он не содержит нерелевантных дуг. Субграф, содержащий нерелевантные дуги, не имеет каких-либо структур и, следовательно, имеет нулевую знаковую доминантность. Таким образом, мы ограничиваем наше рассмотрение только релевантными субграфами. Среди релевантных субграфов многие имеют нулевую знаковую доминантность: точнее циклические субграфы (субграфы с ориентированными циклами). Более того, нециклические релевантные диграфы с m дугами и n узлами имеют знаковую доминантность sdom(G)=(-1)m-n+1.
Изучение доминантности в отношении проблем надежности является разумным приложением комбинаторных аргументов. Метод, который в простейшем случае требует двойного экспоненциального времени, сводится к требованию формирования нециклических релевантных графов и тривиальным расчетам для каждого из них. На практике это позволяет существенно улучшить полный подсчет состояний.
Однако число нециклических субграфов является экспоненциальной функцией n. Следовательно, несмотря на существенное сокращение вычислительных усилий, объем вычислений остается значительным.
Использование знаковой доминантности в задачах без ориентированности осуществляется совсем другим образом. В задачах без ориентированности циклические релевантные графы имеют ненулевую доминантность. Таким образом, алгоритмы включения-исключения, использующие минимаршруты, требуют алгоритмов вычисления знаковой доминантности. Однако настоящий алгоритм вычисления знаковой доминантности отдельного графа является тем же, что и алгоритм для рекурсивного расчета надежности с привлечением факторизации. Фактически, оптимальные стратегии факторизации, использующие последовательные и параллельные редукции, реализуют столько же шагов факторизации, что и в доминантности.
Предположим, что у нас есть перечень минипроходов P1,…,Ph и пусть Ei является случаем, когда все ребра/дуги минипрохода Pi являются работоспособными. Как было замечено, события {Ei} не являются независимыми. Мы рассматриваем стратегию формирования набора независимых событий. Пусть
обозначает дополнение события Ei. Теперь определим событие D1=E1, и вообще,
. События Di являются независимыми, и, поэтому часто называются событиями “независимого произведения”. Более того, Rel(G)=
. При использовании этого подхода нужно получить формулу для Pr[Di] в терминах состояний ребер/дуг. Каждое событие Ei может быть записано в виде булевого выражения, которое является произведением состояний ребер/дуг минимаршрута Pi. Следовательно, Di может быть также записано в виде булева выражения. По этой причине алгоритмы, которые используют независимые произведения, называются иногда методами “булевой алгебры”.
Существует большое разнообразие методов булевой алгебры. Во-первых, заметим, что выражение для события Di является комплексным булевым выражением, включающим дополнения событий Ei, а не только состояния ребер и дополнения состояний ребер.
Вычисление Di требует упрощения булевого выражения к такому виду, который включает только состояния ребер и их дополнения. Большинство методов связано первоначально с эффективностью этого упрощения и с получением результирующих выражений, которые настолько малы насколько возможно. Во-вторых, чтобы облегчить упрощение, большинство методов использует некоторую простую стратегию для упорядочения кратчайших проходов прежде чем определять события {Di}. Конкретные, определенные события сильно зависят от выбранного порядка минипроходов. Типовой эвристикой здесь является упорядочение кратчайших проходов путем помещения в начало проходов с меньшим числом ребер/дуг. Несмотря на эти эвристические улучшения, вообще не существует известной полиномиальной границы для длины упрощенного булевого выражения Rel(G) через число минипроходов.
В случае всетерминальной надежности и достижимости, такая полиномиальная граница может быть получена с помощью алгоритма Болла и Немхаузера. При этом получается булева формула, описывающая независимые события и базирующаяся на минипроходах, в которой число членов равно числу этих проходов.
Кольбурн и Пулейбланк [S.J.Colbourn and W.R. Pulleyblank, “Matroid Steiner problems< , the Tutte polynomial and network reliability” J. Combinatorial theory B41 (1989), 20-31] сформулировали алгоритм упорядочения минипроходов для проблем k-терминальной надежности, где число членов не превышает числа деревьев связи. Однако это число может превышать число минипроходов при экспоненциальном факторе.
Каждый алгоритм, упомянутый здесь, в худшем случае требует экспоненциального времени реализации вне зависимости оттого, вычисляет ли он число состояний, минипроходов или миниразрезов. Полный граф с n узлами, например, имеет 2n-1 миниразрезов, nn-2 деревьев связи и
состояний. Если экспоненциальные алгоритмы оказываются наилучшими, можно надеяться, что разумно рассмотреть алгоритмы, которые используют относительно малое число состояний. Из многих алгоритмов, упомянутых здесь, три метода наиболее достойны внимания.
Методы, основанные на доминантности, гарантируют, что будут просматриваться только релевантные состояния и, таким образом, достигается улучшение в отношении почти всех других методов включения-исключения. Методы, базирующиеся на факторизации (для неориентированного случая), также генерируют только релевантные состояния. Подход Сатайанарайана-Чанга реализует наилучшее возможное время вычисления, используя последовательные и параллельные сокращения. Фактически, во всетерминальном случае, так как число деревьев связи превышает доминантность, алгоритм улучшает все методы, основанные на минипроходах. Наконец, методы, основанные на независимых произведениях, хотя и сопряжены с трудностями анализа, дают два важных алгоритма: алгоритм Болла-Немхаузера для вычисления всетерминальной надежности за полиномиальное время при заданном числе минипроходов, и алгоритм Прована-Болла, который вычисляет двухтерминальную надежность за полиномиальное время при заданном числе миниразрезов.
Этот полезный механизм измерения сложности в терминах числа минипроходов, миниразрезов или релевантных состояний позволяет видеть, что отобранные методы в действительности лучше остальных алгоритмов оценки сетевой надежности.
Методы, базирующиеся на состояниях
Когда преобразования, сохраняющие надежность не могут сократить сеть до класса, где существует эффективный точный метод расчета надежности, мы вынуждены обратиться к методам с потенциально экспоненциальными временами расчетов. Первый главный класс таких точных методов расчета рассматривает возможные состояния сети.
Состояние сети G=(V,E) определяется субнабором SНE работоспособных ребер. Концептуально простейшим точным алгоритмом является полный подсчет состояний. Пусть O является набором всех рабочих состояний. Тогда
При генерации всех состояний и определении того, какое является рабочим, надежность вычисляется легко (но неэффективно).
Конечно, можно легко определить работоспособность больших групп состояний, не просматривая их одно за другим. Следовательно, можно сразу достичь улучшения путем генерации состояний более разумным образом. Базовой составляющей при этом является теорема факторизации:
Rel(G)=peRel(GЧe)+(1-pe)Rel(G-e)
для любого ребра е из G. Факторизация продолжается до тех пор, пока не будут подсчитаны все состояния. Однако некоторые простые наблюдения могут дать определенные улучшения. Когда G - е не работает, любая последовательность сокращений и удалений приводит к неработающему состоянию сети, и по этой причине нет нужды факторизовать G - е. Более того, хотя мы можем не иметь возможности упростить G с помощью преобразования, сохраняющего надежность, мы можем упростить GЧe или G - e.
Факторизация с удалением нерелевантных ребер, стягивание необходимых ребер, а также последовательные, параллельные и 2-степенные редуцирования образуют основу многих точных алгоритмов. Для полных графов полный подсчет подразумевает рассмотрение
состояний, в то время как алгоритм факторизации, использующий последовательное и параллельное редуцирование выявляет только (n - 1)!.
Ниже мы определяем метод факторизации более явно:
procedure factor (graph G)
используем преобразования, сохраняющие надежность G, следующим образом
удаляем нерелевантные ребра
стягиваем необходимые ребра
используем последовательные редуцирования
используем параллельные редуцирования
используем 2-ступенчатые редуцирования
используем другие редуцирования, такие как многогранник-цепочка, содержащие G, каждое ребро которого имеет вероятность, полученную в результате последовательности редуцирований, а также поддерживаем мультипликативный фактор mult, который получен в результате редуцирований.
если G имеет только один оставшийся терминал, return(mult)
в противном случае
выбираем ребро е из G
return(mult*(factor(G Чe)+factor(G-e)))
end (конец)
Дальнейшие улучшения возможны путем разделения графа на двухсвязные или трехсвязные компоненты на каждом этапе.
Методы Монте-Карло
В связи с крайней сложностью точных вычислений различных характеристик надежности и невозможностью для полиномиальных алгоритмов выдать жесткие ограничения этих характеристик, необходимо обратиться к методикам моделирования с целью получения точных оценок. Это, конечно, имеет свою цену - полученные оценки имеют некоторый уровень неопределенности. Несмотря на это, данный недостаток обычно вполне оправдан благодаря тому, что моделирование позволяет получить лучшие результаты по сравнению с детерминистскими методами. Из-за относительно простой структуры этих проблем вполне естественно использовать для моделирования стохастического поведения системы мощные и хорошо исследованные методы Монте-Карло.
Кроме того, каждый граф всегда содержит, по крайней мере, один однородно ориентированный (s,t)-разрез.
Большинство методик Монте-Карло, представленных выше, используется также для проблем наикратчайшего пути и, в общем, не требуют того, чтобы базовый граф не имел циклических структур, как это имеет место во многих методиках ограничения для проблем PERT. Как было показано выше, пусть для еОЕ параметр ребра Xe имеет cdf Fe(x). Предположим, что вы имеете функциональные ограничения ФL и ФU для мультивариантной меры Ф, удовлетворяющей условиям
· ФL(x) Ј Ф(х) Ј ФU(x) для каждого вектора состояния х
· Для любого присвоения
величинам первой компоненты х при k=0,…,m, условная cdf имеет вид
и
может быть вычислено за полиномиальное время. Пространство Х важности в мультивариантной версии проблемы равно теперь
X={xО{0,1}E:ФL(x)Ј a, Ф>U(x)>a}
а модификация метода розыгрыша, базирующегося на ограничениях, представленная в разделе 5.1 приобретает вид
1. Разыгрывается событие
из пространства Х путем последовательного розыгрыша для k=1,…,m компонент состояния
из cdf
2. Вычисляется доля
тех выборок, для которых Ф(х) Ј a. Число
равно теперь несмещенной оценке R.
Функциональные ограничения на основе группирования ребер или непересекающихся разрезов, описанные в разделе 6.4, также дают хорошие функции ограничения для этого метода, так как условные cdf для этих функций могут быть легко вычислены. Хотя в работах Фишмана и др. эти ограничения используются только для задач максимального потока, как это описано в разделе 6.4, они могут применяться также к проблемам PERT и кратчайшего пути так, как это предложено выше.
Многогранные комплексы и матроидные порты
В случае проблемы достижимости Прован [J.S.Provan, “Polyhedral combinatorics and network reliability”, Math. Oper. Res., 11 (1986) 36-61] замечает, что F-комплекс является “многогранным комплексом” и использует теорему Биллеры и Ли, чтобы получить эффективно вычисляемые ограничения надежности, которые жестче для многогранных комплексов.
Структура матроида для всетерминальной проблемы и многогранная структура достижимости позволяют получить существенное улучшение по сравнению с ограничениями Крускала-Катона для общей когерентной проблемы надежности. Пусть для связного графа с n вершинами, имеющего k терминалов, и набор ребер Е, |E|=m, F является его F-комплексом. Блокирующий комплекс F* из F является {E\S:SО2E\F }. F-вектор (F0,...,Fm) из F и F-вектор
удовлетворяет условию
для 0 Ј i Ј m. Чари показал, что субкомплекс F(m-n+1), полученный путем удаления всех наборов из F с мощностью, превосходящей m-n+1, является оболочечным комплексом. Следовательно, задав ограничение на отдельный коэффициент Fm-n+1, можно применить стратегию Балл-Прована к этой k-терминальной проблеме, для того чтобы ограничить (F0,…,Fm-n+1). Что можно сказать об остальных коэффициентах? Чари далее доказал, что F*(n-2), полученный из F* путем удаления всех наборов с мощностью, превосходящей n-2, также является оболочечным. Следовательно, границы Балл-Прована могут быть применены снова для ограничения (F*0,…,F*n-1) или эквивалентно ограничить (Fm,…,Fm-n+2).
Все подходы, разработанные для равных вероятностей отказов ребер, до настоящего времени рассматривали экстремальные результаты для комплексов, которые являются более общими, чем те, что в действительности возникают в проблемах надежности. Остается очень активная область исследования - определение наименее или наиболее надежного графа, а не комплексов, заданных значениями некоторых специфицированных параметров графа. Даже определение наименее надежных графов для заданного числа вершин и ребер остается, однако, не решенной проблемой.
На что нужна надежность?
Хотя вся эта глава посвящена надежности, было бы неточно создать впечатление, что надежность была единственным критерием, представляющим интерес, или даже наиболее важным критерием при разработке большинства сетей. Фактически, обычно имеется несколько конкурирующих критериев, включающих стоимость, полную полосу пропускания системы, реальную пропускную способность и другие эксплуатационные параметры. Наиболее типичным сценарием, с которым приходится сталкиваться при проектировании сети, является:
· Минимизируем стоимость объекта с учетом:
- ограничений пропускной способности
- ограничений эксплуатационных характеристик
- ограничений надежности.
Ограничения на полосу пропускания обычно декларируют, что сеть должна обеспечить достаточную полосу пропускания, чтобы удовлетворить требованиям коммуникаций для заданного набора пар отправитель-получатель. Доминирующим рабочим параметром для сетей с коммутацией пакетов является задержка доставки пакетов или сообщений, а в сетях с коммутацией каналов наиважнейшим параметров является потеря или блокировка вызовов. В идеале ограничения на рабочие параметры и надежность должны задавать точные выражения, определяющие границы на все указанные характеристики. Однако как было заявлено во введении, из-за того, что вычисление надежности и рабочих параметров обычно очень сложно, используются какие-то суррогаты. Типичным суррогатом для задержки является ограничение на длину пути, а типичным суррогатом для надежности являются ограничения на связность. Следует также заметить, что даже если будут включены точные меры для пределов работоспособности и надежности, модель, представленная выше, будет содержать аппроксимации, так как пропускная способность, работоспособность и надежность рассматривались как отдельные ограничения. Идеально желательна конструкция, которая бы удовлетворяла определенным критериям по полосе пропускания и работоспособности, даже при наличии отказов. Все эти недостатки приводят к использованию детализованных алгоритмов анализа работоспособности и надежности.
То есть, раз исходная конструкция системы получена, она обычно усовершенствуется вручную или автоматически на основе результатов анализа работоспособности и надежности.
В результате либо возникает необходимость в специфических ограничениях работоспособности или надежности, либо оказывается необходим алгоритм анализа работоспособности и надежности, в зависимости от специфики постановки задачи. Например, если бы сеть, спроектированная на основе лишь стоимостных и рабочих критериев, оказалась достаточно надежной, то анализ надежности и ограничения на надежность могли бы быть не нужными. Этот сценарий может реализоваться при следующих обстоятельствах:
1. Компоненты сети сами по себе являются высоко надежными.
2. Случайные отказы сети не являются разрушительными.
3. Сети были спроектированы на основе других (не надежностных) критериев, которые достаточно часты и обеспечивают высокую надежность (это может случиться, если полоса канала мала по сравнению с требующейся пропускной способностью).
Аналогичный набор заявлений может быть сделан в отношении критериев работоспособности и пропускной способности. С другой стороны, если полоса сетевых каналов достаточно высока, при проектировании возникает тенденция к созданию распределенных схем, так что явные ограничения на надежность становятся необходимы.
Надписи и таблица Элемент caption
<!element caption - - (%inline;) +>
<!entity % calign "(top|bottom|left|right)">
<!attlist caption | -- Надпись для таблицы -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| align %CAlign; #implied | -- относительно таблицы -- > |
Определение атрибута
align = top|bottom|left|right
Этот атрибут определяет положение подписи по отношению к таблице. Возможные значения:
top: подпись над таблицей. Это значение по умолчанию.
bottom: подпись под таблицей.
left: подпись слева от таблицы.
right: подпись справа от таблицы.
Надпись, если она присутствует, должна описывать природу таблицы. Элемент caption должен располагаться непосредственно после начальной метки table. Например:
<table cols="3">
<caption>cups of coffee consumed by each senator</caption>
… остальная часть таблицы …
</table>
Наивная схема генерации событий
Мы сначала введем нотацию, которая будет использоваться в этом разделе. Пусть (Ф,p) конкретный пример проблемы надежности с вектором компонентов оперативных вероятностей р=(p1, …, pm). Пусть q =(q1,…, qm) = (1-p1,…,1-pm) является вектором 0 вероятностей, обозначим вероятность того, что реализуется конкретный вектор х, как Р(х)
Мы заинтересованы в получении оценки R для истинной надежности системы R=Pr[Ф=1].
Простой метод генерации событий достаточно прямолинеен. Набор из К векторов,
, k=1,…,k формируется из распределения Р, путем получения mK независимых псевдослучайных событий Ukj, k=1,…, K, j=1,…,m от однородного генератора случайных чисел и последующей установки
k=1,…,K, j=1,…,m.
Пусть ‚ число векторов xk, для которых Ф(xk)=1. Тогда несмещенной оценкой для R является R=‚/K, а его вариация ограничена сверху R(1-R)/K. Уменьшение этой вариации может быть получено разнообразными методами генерации событий Монте-Карло, такими как антитетический способ, с управляемыми случайными величинами, а также с помощью условной, приоритетной и послойной выборки.
Некоторые другие процедуры Интернет
Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru
NFS
NFS (network file system, sun microsystems, RFC-1094) обеспечивает прозрачный доступ к удаленным файлам так, что с точки зрения программиста эти файлы выглядят, как местные. При этом даже в написании имен файлов никак не проявляется их истинное местонахождение. NFS является частью операционной системы. Различие работы с местными и удаленными файлами проявляется лишь на системном уровне. Пользователь может почувствовать различие лишь по времени выполнения соответствующих операций обмена. nfs поддерживает операции по созданию, переименованию, копированию и стиранию файлов или каталогов и т.д.
Основой системы NFS является вызов удаленных процедур RPC, схема взаимодействия "клиент-сервер". NFS-сервер получает запросы от клиента в виде UDP-дейтограмм через порт 2049 (Рис. 4.5.16.1).
Рис. 4.5.16.1. Схема реализации nfs-системы клиент-сервер
RPC (Remote Procedure Call, RFC-1057) процедура, разработанная SUN microsystem, в настоящее время используется практически во всех системах, базирующихся на UNIX. RPC - это программа, которая реализует вызов удаленных подпрограмм, способствуя построению распределенных программ. Она позволяет программе, называемой клиентом, послать сообщение серверу. Далее программа-клиент ожидает сообщения-отклика. RPC работает совместно с универсальной системой представления внешней информации XDP (External Data Representation). Сообщение запрос содержит параметры, которые определяют, что должно быть сделано на удаленной ЭВМ. В свою очередь отклик несет в себе информацию о результатах выполнения запроса.
RPC может работать как на TCP, так и UDP транспортных уровнях. Использование RPC-техники упрощает программирование, так как не требует написания сетевых программ. Если используется протокол UDP, все что связано с обработкой тайм-аутов, повторных пересылок и пр. спрятано в внутри системных RPC-модулей. Формат RPC-запроса для UDP-версии показан на рис. 4.5.16.2.
Рис. 4.5.16.2. Формат RPC-запроса
Поле идентификатор процедуры устанавливается программой-клиента, пакет- отклик использует тот же идентификатор, что позволяет контролировать их соответствие. Каждый новый RPC-запрос имеет новый идентификатор. В настоящее время номер версии rpc равен 2. Следующие три поля содержат переменные: номер программы, номер версии и номер процедуры, которые определяют тип запрашиваемой клиентом процедуры. В поле идентификатор клиента может быть записан цифровой код клиента, идентификатор группы или вообще ничего. Поле верификатор используется при пересылке зашифрованных сообщений. Формат параметров процедуры зависит от типа этой процедуры. Размер поля параметров равен длине UDP-дейтограммы минус сумма длин остальных полей, включая верификатор. В случае работы с TCP-сегментами, где длина пакета не определена, между TCP-заголовком и XID вводится 4-x октетное поле длины RPC-сообщения. Формат RPC-отклика для UDP-версии (Рис. 4.5.16.3):
Рис. 4.5.16.3. Формат RPC-отклика
Поле отклик, содержащее 1, указывает на то, что данное сообщение представляет собой отклик на поступивший ранее запрос. Поле статус содержит 0 в случае, если запрос воспринят. Запрос игнорируется при конфликте кодов RPC-версии или неудачной идентификации клиента. Поле флаг результата принимает значение 0 при успешной обработке запроса. Ненулевое значение этого поля указывает на ошибку.
Для записи параметров RPC-запросов, откликов, параметров и результатов выполнения процедуры используется внешнее представление данных (XDR - External Data Representation, RFC-1014). Отправитель, формируя RPC-сообщение, использует XDR-формат, а получатель преобразует данные из этого формата в традиционное представление.
Существует два базовых вида отклика: MSG_ACCEPTED (сообщение принято) и MSG_DENIED (не принято). Факт приема сообщения не означает выполнение запрошенных процедур, поэтому клиенту выдается дополнительная информация о результатах взаимодействия его запроса с удаленной системой. RPC может найти применение при построении больших распределенных информационных систем, баз данных и систем управления.
XDR позволяет программисту избежать написания специальных программ преобразования. Например, в разных ЭВМ используются различные форматы представления чисел с плавающей запятой. XDP берет на себя согласование форматов и делает написание прикладных программ машинно-независимым.
Программы RPC-сервера используют большое число портов с нестандартизованными номерами. Для управления использованием этих портов имеется специальная программа (portmapper), которая имеет номер 100000, номер версии -2 и сама пользуется портом номер 111. Распределение номеров портов можно посмотреть с помощью программы:
/usr/etc/rpcinfo -p
program | vers | proto | port | |
[программа | версия | протокол | порт | название программы] |
100000 | 2 | tcp | 111 | portmapper |
100000 | 2 | udp | 111 | portmapper |
100029 | 1 | udp | 664 | keyserv |
100005 | 1 | udp | 702 | mountd (монтирует демон для NFS) |
100005 | 2 | udp | 702 | mountd |
100005 | 1 | tcp | 705 | mountd |
100005 | 2 | tcp | 705 | mountd |
100003 | 2 | udp | 2049 | nfs (сама NFS) |
100026 | 1 | udp | 714 | bootparam |
100024 | 1 | udp | 717 | status |
100024 | 1 | tcp | 719 | status |
100021 | 1 | tcp | 720 | nlockmgr (NFS-менеждер) |
100021 | 1 | udp | 1031 | nlockmgr |
100021 | 3 | tcp | 724 | nlockmgr |
100021 | 3 | udp | 1032 | nlockmgr |
100010 | 1 | udp | 718 | etherstatd |
100020 | 2 | udp | 1033 | llockmgr |
100020 | 2 | tcp | 729 | llockmgr |
100021 | 2 | tcp | 732 | nlockmgr |
100021 | 2 | udp | 1034 | nlockmgr |
100011 | 1 | udp | 1041 | rquotad |
100001 | 2 | udp | 1042 | rstatd |
100001 | 3 | udp | 1042 | rstatd |
100001 | 4 | udp | 1042 | rstatd |
100002 | 1 | udp | 1043 | rusersd |
100002 | 2 | udp | 1043 | rusersd |
100012 | 1 | udp | 1044 | sprayd |
100008 | 1 | udp | 1045 | walld |
Отсюда видно, что некоторые программы имеют несколько версий, а каждая комбинация номера программы, версии и протокола имеет свой собственный номер порта. В таблице 4.5.16.1 приведены ссылки на некоторые RPC-программы, используемые с NFS.
Таблица 4.5.16.1. Коды программ, используемых в NFS
Назначение программы | Номер программы | Номер версии | Номер процедуры |
Менеджер портов (port mapper) | 100000 | 2 | 4 |
NFS | 100003 | 2 | 15 |
Монтировщик | 100005 | 1 | 5 |
Менеджер блокировки | 100021 | 1,2,3 | 19 |
Статус-монитор | 100024 | 1 | 6 |
Монтировщик вызывается NFS-клиентом для обеспечения доступа к файловой системе сервера.
Взаимодействие с файловой системой производится с помощью указателей файлов (handle), которые для версии 2 требуют 32 байт, а для версии 3 - 64 байт. Хотя NFS с самого начала была сориентирована на применение UDP (что было оправдано для локальных сетей), в настоящее время она в равной мере использует и TCP. Это позволяет NFS работать уже в масштабе всего Интернет. Третья версия NFS предполагает увеличение числа байт на одну команду READ или WRITE с 8192 до 65535 (ограничение, связанное с размером IP-дейтограммы). Увеличена в третьей версии и предельная длина файлов, которая задается уже 64-, а не 32-битным числом.
RLOGIN (RFC-1281) - процедура удаленного доступа, реализованная в 4BSD UNIX. RLOGIN позволяет администратору сети определить список ЭВМ, авторизация и доступ к которым является общими. Пользователь может организовать групповой доступ к разным ЭВМ, где он авторизован, сохраняя для себя возможность общения с любой из машин, не вводя каждый раз пароль. Одной из реализаций RLOGIN является RSH. RSH включает в себя интерпретатор команд. Форма обращения имеет вид: RSH имя_ЭВМ команда. RLOGIN позволяет взаимодействовать как с внутренними, так и с внешними ресурсами сети и с этой точки зрения предоставляет большие возможности чем Telnet.
REXECD представляет собой резидентную управляющую программу (демон), которая позволяет исполнять команды на удаленной ЭВМ в рамках TCP/IP сетей. Команда, выданная одной ЭВМ, может быть выполнена на другой ЭВМ, при этом автоматически, если необходимо, осуществляется процедура авторизации. REXECD использует TCP в качестве транспортной среды. Существуют реализации для сред UNIX, AIX и DOS.
Непересекающиеся разрезы
Использование набора проходов и разрезов с разъединенными ребрами до сих пор мотивировалось первоначально необходимостью вычислить вероятность того, что один набор проходов работает (как в лемме 4.1) или что один набор разрезов приводит к отказу (как в лемме 4.2). Разработан метод, который позволяет наборам разрезов иметь общие ребра, сохраняя эффективность вычисления вероятности того, что один из наборов разрезов приводит к отказу. Для графа G=(V,E) секция (А,В) из V образует набор разрезов, содержащий все ребра, имеющие один конец в А, а другой в В. Два таких набора разрезов (А,В) и (
) являются
непересекающимися, если, по крайней мере, один из АЗВ, АЗ
,
ЗВ и
является пустым. Коллекция разрезов является непересекающейся или ламинарной, если каждый из двух наборов в коллекции являются непересекающимися. В n-узловом графе с
k терминалами набор непересекающихся разрезов содержит по большей части n-1+k-2 Ј 2n-3 непересекающихся разрезов.
Базис разрезов n-вершинного графа является набором из n-1 разреза С1,…,Сn-1, для которых каждый разрез может быть записан как сумма по модулю 2 этих n-1 разрезов. Ломоносов и Полесски показали, что для любого базиса разрезов С1,…,Сn-1 всетеринальное значение надежности удовлетворяет равенству
Ограничение на базис, ограничивает число разрезов, которые могут быть использованы до уровня меньше, чем число терминалов. Более общее расширение получается при допущении использования наборов непересекающихся разрезов. Ограничение получено путем установления вероятности того, что ни один из непересекающихся разрезов не приводит к отказу. Это согласуется с k-терминальной узловой надежностью графа специального типа - ориентированного графа проходов. Тогда простая динамичная стратегия программирования обеспечит получение значений границ за полиномиальное время.
Ограничения, использующие непересекающиеся разрезы, существенно расширяют возможности стратегий группирования ребер при рассмотрении больших наборов разрезов, но при полиномиальном их числе.
Неупорядоченные (ul) и упорядоченные (ol) списки
<!entity % ulstyle "disc|square|circle">
<!element ul - - (li) +>
<!attlist ul | -- неупорядоченный список -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| type (%ulstyle) #implied | -- список, где элементы отмечены жирной точкой в начале строки -- |
| compact (compact) #implied | -- уменьшенное расстояние между элементами списка -- > |
<!entity % olstyle "cdata" | -- определяет стиль нумерации: [1|a|a|i|i] -- > |
<!element ol - - (li) +> |
<!attlist ol | -- упорядоченный список -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| type (%olstyle) #implied | -- нумерованный список -- |
| compact (compact) #implied | -- уменьшенное расстояние между элементами списка -- |
| start number #implied | -- начальный номер элемента списка -- > |
<!entity % listyle "cdata" | -- ограничение: "(%ulstyle|%olstyle)" -- > |
<!element li - o %block | -- элемент списка -- > |
<!attlist li %attrs; | -- %coreattrs, %i18n, %events -- |
| type %listyle) #implied | -- стиль элемента списка -- |
| value number #implied | -- сброс счетчика элементов списка -- > |
Определение атрибутов
type = style-information
Этот атрибут определяет стиль элемента списка.
start = integer
Работает только для ol. Устанавливает начальное значение счетчика элементов упорядоченного списка, значение по умолчанию равно единице.
value = integer
Работает только для LI. Устанавливает текущее значение номера элемента списка.
compact
Не рекомендуется использовать. При использовании требует от агента пользователя отображать список в возможно более компактном виде.
Упорядоченные и не упорядоченные списки во многом схожи. Оба типа представляют собой последовательность элементов, описанных элементом LI (конечная метка этого элемента обычно опускается). Ниже приведены примеры списков.
<ul>
| <li> … первый элемент списка … |
| <li> … второй элемент списка … |
| …………. |
</ul>
Списки могут быть вложенными.
<ul>
|
<li> …Уровень 1, номер 1 … |
| <ol> |
| | <li> … Уровень 2, номер 1 … |
| | <li> … Уровень 2, номер 2 … |
| | <ol start="10"> |
| | | <li> … Уровень 3, номер 1 … |
| | </ol> |
| | <li> … Уровень 2, номер 3 … |
| </ol> |
| <li> …Уровень 1, номер 2 … |
</ul>
В упорядоченных списках невозможно продолжать нумерацию с предыдущего списка или убрать нумерацию, но можно установить счетчик принудительно с помощью атрибута value. Например:
<ol>
<li value="30"> присваивает этому элементу списка номер 30.
<li value="40"> присваивает этому элементу списка номер 40.
<li> этот элемент списка будет иметь номер 41.
</ol>
12.1. Списки, форматируемые визуальным агентом пользователя
Для OL и UL атрибут type определяет опцию отображения визуальным агентом пользователя. Для элемента UL возможны значения атрибута type: disc, square и circle. Значение по умолчанию зависит от уровня вложения текущего списка. Агент пользователя попытается представить "disc" в виде небольшого заполненного кружочка, "circle" - в виде незаполненного кружочка, а "square" - в виде квадратика.
Для элемента ol возможные значения атрибута type представлены в таблице.
Тип | Стиль нумерации |
1 | Арабские цифры | 1,2,3,… |
a | Строчные буквы латинского алфавита | a,b,c,… |
a | Прописные буквы латинского алфавита | a,b,c, … |
i | Малые римские цифры | i, ii, iii, … |
i |
Большие римские цифры | i, ii, iii, … |
Оболочечность
У нас нет надежды без дополнительной информации улучшить ограничения Крускал-Катона. Такая дополнительная информация может быть получена разными путями. Одним из таких путей мог бы быть эффективный алгоритм вычисления (или установления более жестких границ) одного или более неизвестных Fi. Другим - может быть выявление того, что конкретное наследственное семейство, имеет некоторую специальную комбинаторную структуру. Этот последний подход является многообещающим, так как, несмотря на то, что компоненты наборов маршрутов в когерентных системах образуют наследственные семейства, не все наследственные семейства образуются таким путем.
Фактически, F-комплекс в проблеме всетерминальной надежности является матроидом, кографическим матроидом графа. В описании F-векторов кографических матроидов отсутствует прогресс, и можно задать вопрос, чем может быть F-вектор матроида вообще. Даже для этой проблемы прямого прогресса не достигнуто. Однако мы можем идентифицировать класс наследственных систем, который является промежуточным между матроидами и наследственными системами вообще, результаты представлены ниже.
Прован и Биллера доказали важный результат, связанный со структурой матроидов, который (вместе с другими результатами) накладывает ограничения на их F-векторы. Они показали, что матроиды являются “оболочечными” комплексами. Важность результата Прован-Биллера в исследованиях надежности заключается в том, что они предлагают возможность использования оболочечности для улучшения ограничений Крускал-Катона. Конечно, это требует введения структурной теоремы для оболочечных систем. Интервал [L,U] является семейством субнаборов {S:LНSНU}. Часть интервала комплекса является набором разъединенных интервалов, для которых каждый набор в комплексе принадлежит строго одному интервалу. Комплекс разделим, если он имеет секции интервалов [Li,Ui], 1 Јi Ј J с Ui в качестве базы для всех i. Оболочечные комплексы всегда являются разделимыми.
Рассмотрим оболочечный комплекс с b базами.
Пусть {[Li,Ui]|1 Јi Ј b} является секцией интервала для этого комплекса. [Li,Ui] является компактной записью для всех наборов в интервале. Вероятность того, что какой-то из этих наборов реализуется, равна тогда pm-|Ui|(1-p)|Li|. Другими словами, ребра |Li| должны отказать, а ребра m-Ui должны работать. Состояние остальных ребер не играет никакой роли. Каждый Ui является базой в комплексе; следовательно, мощности всех Ui равны (ранг d базы). Однако ранги Li не являются идентичными; мы, следовательно, определяем Hi=|{Lj:1Јj Ј b,|Lj|=i}|. Это дает увеличение Н-вектора (Н0,…,Нd). Коэффициенты Hi определяют интервалы в секции, чей младший набор имеет ранг i.
Это предлагает еще одну форму полинома надежности:
Здесь
l - мощность набора маршрутов с минимальной мощностью (дерево связей), а d=m-l является рангом базы. Более конкретно, в графе с n-вершинами и m-ребрами i=n-1, а d=m-n+1.
Естественно, любая информация о Н-векторе также предоставляет данные о полиноме надежности. Однако чтобы поместить Н-вектор в соответствующий контекст, важно рассмотреть отношения между Н-вектором и F-вектором для оболочечного комплекса. Н-вектор для любого комплекса может быть определен непосредственно в терминах F-вектора. В секционном случае, однако, соответствие может быть легко установлено комбинаторно.
Рассмотрим наборы ранга k в комплексе. Они подсчитываются с помощью Fk. Теперь любой интервал [Li,Ui] отвечает за определенные наборы. Пусть
r является рангом Li. Если r > k, интервал отвечает за 0 наборов в Fk; однако, если rЈ k, он отвечает за наборы
. Отсюда мы нашли, что
. Приравнивание форм F-вектора и Н-вектора полинома надежности дает выражение для Hi в терминах F-вектора, а именно
Это выражение позволяет нам эффективно вычислить Н0,…,Нs. Другой очевидный, но полезный факт заключается в том, что
.
Стенли получил нижнюю границу
для Нi-1, заданном Нi, которая вообще является жесткой для оболочечных комплексов. Это, в свою очередь дает верхнюю границу
для Нi, заданном Нi-1.
Для наших целей важны три вещи. Прежде всего, для k і jі i, x<k/i> = x<j/i><k/j>. Во-вторых, при заданных x, j и i мы можем эффективно вычислить x<j/i>. В-третьих, всякий раз, когда xіy, x<j/i> іy<j/i>.
Теорема Стенли может быть использована для получения эффективно вычисляемых ограничений полинома надежности. Задав префикс (F0,…,Fs) F-вектора, мы можем эффективно вычислить префикс (Н0,…,Нs) Н-вектора.
Зная этот префикс, мы можем получить некоторые простые ограничения; они вообще применимы к оболочечным системам, но мы представляем их здесь для всетерминального случая.
Здесь используется информация о размере набора разрезов минимальной мощности и, где возможно, числа таких разрезов. Эта простая формулировка игнорирует существенную часть информации, число деревьев связи. Это получено с учетом того, что
.
Ставим в соответствие каждому Нi “корзину”. Теперь предположим, что мы имеем Fd “мячей”. Наша задача заключается в том, чтобы поместить все мячи в корзины, так чтобы номера мячей в i-ой корзине, удовлетворяли условию
.
Как следует распределить мячи так, чтобы максимизировать или минимизировать полином надежности? Эти распределения, когда будут найдены, дадут верхнее и нижнее ограничение полинома надежности. Тщательно рассмотрим сумму полиномов надежности:
. Так как 0<р<1, сумма больше, когда коэффициенты нижнего порядка больше. Фактически для двух Н-векторов (Н0,…,Нd) и (J0,…,Jd) всякий раз, когда
для всех i, полином надежности Нi доминирует над полиномом надежности для Ji.
Это последнее простое наблюдение предлагает методику получения ограничений. В практической модели верхняя граница получается путем помещения мячей в самую левую корзину (с корзинами пронумерованными 0,…,d слева направо); аналогично, нижняя граница получается помещением мячей в самую правую корзину. Мы делали это размещение не без ограничений, так как мы заранее знали содержимое корзин 0,…,s.
Теперь мы формируем коэффициенты
для полинома верхней границы и
для полинома нижней границы, используя префикс (Н0,…,Нs) и Fd.
Шаги включают в себя: Для i=0,…,s устанавливаем
=Нi=
Для i=
В каждом ограничении мы определяем число мячей в каждой корзине от 0 до d по порядку. Как мы заметили, содержимое корзин 0,…,s известно. Для последующих корзин верхняя граница определяется следующим образом. Число мячей, которые могут попасть в текущую корзину, ограничено теоремой Стенли, и лимитируется также тем фактом, что существует фиксированное число мячей, подлежащих распределению. Если осталось больше мячей, чем мы можем поместить в текущую корзину, мы кладем столько, сколько сможем. Если все может быть помещено в текущую корзину, мы делаем это; в этом случае все мячи оказались распределены, а остальные корзины пусты. Нижняя граница определяется путем помещения минимально возможного числа мячей.
Метод приводит к очень мощному набору ограничений, границам Болл-Провена:
В отличие от ограничений Крускала-Катона в случае ограничений Болла-Прована обычно не имеет место неравенство
.
Оценка коэффициентов полиномов надежности
Одной из проблем, связанных с методами, которые рассматривались до сих пор, является то, что они только оценивают надежность для одиночного вектора вероятностей p. Больший интерес часто представляет оценка функциональной формы полинома вероятности. Это становится особенно важно, когда вероятности отказа связей (ребер) все равны р, так что надежность системы может быть записана как это представлено в разделе 2 - в одной из двух полиномиальных форм:
В этом случае более полезной схемой Монте-Карло была бы та, которая оценивает каждый коэффициент Fi или Hi, тогда эти оценки можно было бы использовать для получения значения надежности для любой заданной величины p.
Нел и Кольбурн исследовали проблему надежности всех терминалов и предлагают схему для оценки коэффициентов Hi для данной задачи. Так как сумма коэффициентов Hi равна числу деревьев в графе G, в противоположность числу подключенных наборов G, которое равно сумме коэффициентов Fi, тогда число состояний, дающих вклад в оценки коэффициентов Hi, много меньше того, которое нужно разыграть для оценки коэффициентов Fi. Сошлемся на раздел 4.1.5 и предположим, что U={[Li,Ui]| i=1,….b} является какой-то оболочкой F-комплекса G. Из определения Hi, как мощности i Lj, следует, что для любой однородной выборки интервалов [Lj,Uj] в U, пропорция Lj мощности i является несмещенной оценкой Hi. Нел и Кольбурн развили этот подход, чтобы получить методику для однородной выборки из множества интервалов канонической оболочки F-комплекса G, базирующейся на однородной выборке деревьев связи в G.
Описание функции надежности, когда имеются отказы в соединениях, является проблематичным, так как сама полиномиальная форма имеет экспоненциально большое число членов. Предположим, что нам нужно знать надежность R, как функцию вероятностей работоспособности p1,…,pk выбранного набора из k ребер графа e1,…,ek, при заданных конкретных вероятностях работоспособности
для остальных ребер ek+1,…,em. Теперь мы вычисляем “коэффициенты” частичного описания надежности, реализуя вариант послойных испытаний (или условных испытаний, в зависимости от точки зрения).
Опции
Метод OPTIONS представляет собой запрос информации о коммуникационных опциях, доступных в цепочке запрос/отклик, идентифицированной Request-URI. Этот метод позволяет клиенту определить опции и/или требования, связанные с ресурсами, или возможности сервера, не прибегая к операциям по извлечению и пересылке каких-либо файлов.
Если отклик сервера не сигнализирует об ошибке, отклик не должен включать никакой информации об объекте, отличной оттого, что считается коммуникационными опциями (напр., Allow подходит под эту категорию, а Content-Type нет). Отклики на этот метод не должны кэшироваться.
Если Request-URI тождественен символу звездочка ("*"), то запрос OPTIONS будет относиться ко всему серверу. Отклик 200 должен включать в себя любые поля заголовка, которые указывают на опционные характеристики используемого сервера (например, Public), включая любые расширения неопределенные в данной спецификации, в дополнение к любым общим используемым полям заголовка. Как описано в разделе 4.1.2, запрос "OPTIONS *" может быть реализован через прокси путем спецификации сервера места назначения в Request-URI без указания прохода. Если Request-URI не равен звездочке, запрос OPTIONS относится только к опциям, которые доступны при обмене с данным ресурсом. Отклик 200 должен включать любые поля заголовка, которые указывают опционные характеристики используемого сервера и применимы к данному ресурсу (напр., Allow), включая любые расширения, не описанные в данной спецификации. Если запрос OPTIONS проходит через прокси, то он должен редактировать отклик и удалять те опции, которые не доступны для реализации через данный прокси-сервер.
8.3 Метод GET
Метод GET предполагает извлечение любой информации (в форме объекта), заданной Request-URI. Если Request-URI относится к процессу, генерирующему данные, то в результате в виде объекта будут присланы эти данные, а не исходный текст самого процесса, если только этот текст не является результатом самого процесса.
Семантика метода меняется на "условный GET", если сообщение-запрос включает в себя поля заголовка If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match или If-Range.
Метод условного GET запрашивает, пересылку объекта только при выполнении требований, описанных в соответствующих полях заголовка. Метод условного GET имеет целью уменьшить ненужное использование сети путем разрешения актуализации кэшированых объектов без посылки множественных запросов или пересылки данных, которые уже имеются у клиента. Семантика метода GET меняется на "частичный GET", если сообщение запроса включает в себя поле заголовка Range. Запросы частичного GET, которые предназначены для пересылки лишь части объекта, описаны в разделе 13.36. Метод частичного GET ориентирован на уменьшение ненужного сетевого обмена, допуская пересылку лишь части объекта, которая нужна клиенту, и не пересылая уже имеющихся частей.
Отклик на запрос GET буферизуется, тогда и только тогда, когда это согласуется с требованиями буферизации, рассмотренными в разделе 12.
8.4. Метод HEAD
Метод HEAD идентичен GET за исключением того, что сервер не должен присылать тело сообщения. Метаинформация, содержащаяся в заголовках отклика на запрос HEAD должна быть идентичной информации посланной в отклик на запрос GET. Этот метод может использоваться для получения метаинформации об объекте, указанном в запросе, без передачи тела самого объекта. Этот метод часто используется для тестирования гипертекстных связей на корректность, доступность и актуальность.
Отклик на запрос HEAD может кэшироваться в том смысле, что информация, содержащаяся в отклике, может использоваться для актуализации кэшированных ранее объектов данного ресурса. Если новые значения поля указывают на то, что кэшированный объект отличается от текущего объекта (как это индицируется изменением Content-Length, Content-MD5, ETag или Last-Modified), тогда запись в кэше должна рассматриваться как устаревшая.
8.5. Метод POST
Метод POST используется при заявке серверу принять вложенный в запрос объект в качестве нового вторичного ресурса, идентифицированного Request-URI в Request-Line. POST создан для обеспечения однородной схемы реализации следующих функций:
Аннотация существующего ресурса;
Помещение сообщения на электронную доску объявлений, в группу новостей, почтовый список или какую-то другую группу статей;
Выдача блока данных, такого как при передаче формы процессу ее обработки;
Расширение базы данных с помощью операции добавления (append).
Реальная операция, выполняемая методом POST, определяется сервером и обычно зависит от Request-URI. Присланный объект является вторичным по отношению к URI в том же смысле, в каком файл является вторичным по отношению к каталогу, в котором он находится, а статья новостей - вторичной по отношению к группе новостей, куда она помещена, или запись - по отношению к базе данных.
Операция, выполняемая методом POST, может не иметь последствий для ресурса, который может быть идентифицирован URI. В этом случае приемлемым откликом является 200 (OK) или 204 (No Content - никакого содержимого), в зависимости от того, включает ли в себя отклик объект, описывающий ресурс.
Если ресурс был создан на исходном сервере, отклик должен быть равен 201 (Created - создан) и содержать объект, который описывает статус запроса и относится к новому ресурсу и заголовку Location (см. раздел 13.30).
Отклики на этот метод не могут кэшироваться, если только не содержат поля заголовка Cache-Control или Expires. Однако отклик 303 (см. Other) может быть использован для того, чтобы направить агента пользователя для извлечения кэшируемого ресурса.
Запросы POST должны подчиняться требованиям, предъявляемым к передаче сообщений, рассмотренным в разделе 7.2.
8.6. Метод PUT
Метод PUT требует, чтобы вложенный объект был запомнен с использованием Request-URI. Если Request-URI относится к уже существующему ресурсу, то вложенный объект следует рассматривать как модифицированную версию объекта на исходном сервере. Если Request-URI не указывает на существующий ресурс и запрашивающий агент пользователя может определить этот URI как новый ресурс, исходный сервер может создать ресурс с этим URI. Если новый ресурс создан, исходный сервер должен информировать об этом агента пользователя, послав код отклик 200 (OK) или 204 (No Content - никакого содержимого) и тем самым, объявляя об успешно выполненном запросе.
Если ресурс не может быть создан или модифицирован с помощью Request-URI, должен быть послан соответствующий код отклика, который отражает характер проблемы. Получатель объекта не должен игнорировать любой заголовок Content-* (например, Content-Range), который он не понял или не использовал, а должен в таком случае вернуть код отклика 501 (Not Implemented - не использовано).
Если запрос проходит через кэш и Request-URI идентифицирует один или более кэшированных объектов, эти объекты должны рассматриваться как устаревшие. Отклики этого метода не должны кэшироваться.
Фундаментальное отличие между запросами POST и PUT отражается в различных значениях Request-URI. URI в запросе POST идентифицирует ресурс, который будет работать со вложенным объектом. Этот ресурс может быть процессом приемки данных, шлюзом к другому протоколу или отдельным объектом, который воспринимает аннотации. Напротив, URI в запросах PUT идентифицируют объекты, заключенные в запросе, - агент пользователя знает, какой URI применить и сервер не должен пытаться посылать запрос другому ресурсу. Если сервер хочет, чтобы запрос был направлен другому URI, он должен послать отклик 301 (Moved Permanently). Агент пользователя может принять свое собственное решение относительно того, следует ли переадресовывать запрос.
Один и тот же ресурс может быть идентифицирован многими URI. Например, статья может иметь URI для идентификации "текущей версии", которая отличается от URI, идентифицирующей каждую конкретную версию. В этом случае запрос PUT на общий URI может дать в результате несколько других URI, определенных исходным сервером. HTTP/1.1 не определяет то, как метод PUT воздействует на состояние исходного сервера. Запросы PUT должны подчиняться требованиям передачи сообщения, заданным в разделе 7.2.
8.7. Метод DELETE
Метод DELETE требует, чтобы исходный сервер уничтожил ресурс, идентифицируемый Request-URI. Этот метод на исходном сервере может быть отвергнут вмешательством человека (или каким-то иным путем).
Клиент не может гарантировать, что операция была выполнена, даже если возвращенный статусный код указывает, что операция завершилась успешно. Однако, сервер не должен сообщать об успехе, если за время отклика он не намерен стереть ресурс или переместить его в недоступное место.
Сообщение об успехе должно иметь код 200 (OK), если отклик включает объект, описывающий статус; 202 (Accepted - принято), если операция еще не произведена или 204 (No Content - Никакого содержимого), если отклик OK, но объекта в нем нет.
Если запрос проходит через кэш, а Request-URI идентифицирует один или более кэшированных объектов, эти объекты следует считать устаревшими (stale). Отклики на этот метод не кэшируемы.
8.8. Метод TRACE
Метод TRACE используется для того, чтобы запустить удаленный цикл сообщения-запроса на прикладном уровне. Конечный получатель запроса должен отослать полученное сообщение назад клиенту в виде тела объекта (код = 200 (OK)). Конечным получателем является либо исходный сервер, либо первый прокси или шлюз для получения значения Max-Forwards (0) в запросе (см. раздел 13.31). Запрос TRACE не должен включать в себя объект.
TRACE позволяет клиенту видеть, что получено на другом конце цепи запроса и использовать эти данные для тестирования или диагностики. Значение поля заголовка Via (раздел 13.44) представляет особый интерес, так как оно позволяет отследить всю цепочку запроса. Использование поля заголовка Max-Forwards позволяет клиенту ограничить длину цепи запроса, которая полезна для тестирования цепи прокси, переадресующих сообщения по замкнутому кругу.
В случае успеха отклик должен содержать все сообщение-запрос с Content-Type = "message/http". Отклики этого метода не должны кэшироваться.
4.5.6.1.9. Определения статусных кодов
Ниже описаны статусные коды, включая то, каким методам они соответствуют, и какая метаинформация должна присутствовать в откликах.
9.1. Информационный 1xx
Этот класс статусного кода индицирует информационный отклик, состоящий только из статусной строки и опционных заголовков с пустой строкой в конце.
Так как HTTP/1.0 не определяет каких- либо статусных кодов 1xx, серверы не должны посылать отклики 1xx клиентам HTTP/1.0 за исключением случаев отладки экспериментальных протокольных версий.
9.1.1. 100 Continue (продолжение)
Клиент может продолжать работу, получив этот отклик. Этот промежуточный отклик используется для информирования клиента о том, что начальная часть запроса получена и пока не отклонена сервером. Клиенту следует продолжить отправлять оставшуюся часть запроса, если же запрос уже отправлен, то игнорировать этот отклик. Сервер должен послать окончательный отклик по завершении реализации запроса.
9.1.2. 101 Switching Protocols (Переключающие протоколы)
Сервер оповещает клиента о том, что он понял и принял к исполнению запрос. С помощью поля заголовка сообщения Upgrade (раздел 13.41) клиент уведомляется об изменении прикладного протокола для данного соединения. Сервер переходит на протокол, определенный в поле заголовка отклика Upgrade, немедленно после получения пустой строки, завершающей отклик 101.
Протокол следует изменять лишь в случае, если он предоставляет существенные преимущества. Например, переключение на новую версию HTTP предоставляет преимущества по отношению к старой версии, а переключение на синхронный протокол реального времени может иметь преимущество, когда ресурс использует это свойство.
9.2. Successful 2xx (Успешная доставка)
Этот класс статусного кода индицирует, что запрос клиента благополучно получен, понят и принят к исполнению.
9.2.1. 200 OK
Запрос успешно исполнен. Информация, возвращаемая вместе с откликом, зависит от метода, использованного запросом, например:
GET - в качестве отклика посылается объект, соответствующий запрошенному ресурсу;
HEAD - в качестве отклика посылаются поля заголовка объекта (без какого-либо тела), соответствующего запрошенному ресурсу;
POST - объект, описывающий или содержащий результат операции;
TRACE - объект, содержащий сообщение-запроса, в виде, полученном оконечным сервером.
9.2.2. 201 Created (Создано)
Запрос исполнен и в результате создан новый ресурс. Вновь созданный ресурс может быть доступен через URI, присланный в объекте отклика, со значащей частью URL ресурса в поле заголовка Location. Исходный сервер должен создать ресурс до отправки статусного кода 201. Если операция не может быть выполнена немедленно, сервер вместо этого должен откликнуться статусным кодом 202 (Accepted).
9.2.3. 202 Accepted (Принято)
Запрос был принят для исполнения, но обработка запроса не завершена. Запрос может обрабатываться или нет, так как он был блокирован в процессе исполнения. Не существует механизма повторной посылки статусного кода для асинхронных операций вроде этой.
Целью отклика 202 является разрешить серверу принять запрос для некоторого другого процесса (возможно процесса, запускаемого раз в день), не требуя того, чтобы соединение агента пользователя с сервером сохранялось до завершения процесса. Объект, возвращаемый этим откликом должен включать в себя текущий статус запроса и указатель на статус-монитор или некоторую оценку того, когда пользователь может ожидать завершения реализации запроса.
9.2.4. 203 Non-Authoritative Information (Не надежная информация)
Присылаемая в ответ метаинформация в заголовке объекта не идентифицируется, как полученная от исходного сервера, ее следует скорее считать косвенной, полученной опосредовано. Например, включение местной аннотационной информации о ресурсе может иметь последствия для мета информации, известной исходному серверу. Использование данного кода отклика не является обязательным и целесообразно лишь в случае, когда отклик мог бы быть равен 200 (OK).
9.2.5. 204 No Content (Никакого содержимого)
Сервер исполнил запрос, но нет никакой новой информации для отсылки. Этот отклик первоначально предназначался для разрешения ввода, не вызывая изменения активного документа агента пользователя. Отклик может включать новую метаинформацию в форме заголовков объектов, которая должна быть передана для документа, отображаемого агентом пользователя.
Отклик 204 не должен включать тела сообщения и всегда завершается пустой строкой после полей заголовка.
9.2.6. 205 Reset Content (Сброс содержимого)
Сервер исполнил запрос и агент пользователя должен вернуть документ к виду, который он имел в момент посылки запроса. Этот отклик первоначально предназначался для обеспечения ввода при выполнении пользователем операции, за которой следует очистка формы, в которую произведен ввод, так что пользователь может начать другую операцию ввода. Отклик не должен включать в себя объект.
9.2.7. 206 Partial Content (Частичное содержимое)
Сервер исполнил частично запрос GET для заданного ресурса. Запрос должен включать поле заголовка Range (раздел 13.36), указывающее на желательный интервал (range). Отклик должен включать поле заголовка Content-Range (раздел 13.17), указывающее диапазон данных, включенных в отклик, или множественные байтные интервалы (multipart/byteranges) Content-Type, включающие поля Content-Range для каждой из частей. Если множественные байтные интервалы не используются, поле заголовка Content-Length в отклике должно соответствовать действительному числу октетов в теле сообщения. Кэш, который не поддерживает заголовки Range и Content-Range, не должен кэшировать отклики 206 (Partial).
9.3. Redirection 3xx (Переадресация)
Этот класс статусных кодов указывает, что для выполнения запроса, нужны дальнейшие действия агента пользователя. Необходимые действия могут быть выполнены агентом пользователя без взаимодействия с пользователем, тогда и только тогда, когда используемый метод соответствует GET или HEAD. Агент пользователя не должен автоматически переадресовывать запрос более чем 5 раз, так как такая переадресация обычно свидетельствует о зацикливании запроса.
9.3.1. 300 Multiple Choices (Множественный выбор)
Запрошенный ресурс соответствует какому-то представлению из имеющегося набора представлений, каждое со своим адресом. Имеется информация (раздел 11), полученная в результате согласования под управлением агента пользователя, так что пользователь (или агент пользователя) может выбрать предпочтительное представление и переадресовать свой запрос по соответствующему адресу.
Если это только не был запрос HEAD, отклик должен включать объект, содержащий список характеристик ресурсов и их адресов, из которых пользователь или агент пользователя может выбрать наиболее подходящий. Формат объекта специфицируется типом среды, заданным полем заголовка Content-Type. В зависимости от формата и возможностей агента пользователя, выбор наиболее подходящего варианта может быть выполнен автоматически. Однако, эта спецификация не определяет какого-либо стандарта для такого автоматического выбора.
Если сервер имеет предпочтительный вариант представления, ему следует включить соответствующий URL этого представления в поле Location. Агент пользователя может использовать значение поля Location для реализации автоматического выбора. Этот отклик может кэшироваться, если не указано обратного.
9.3.2. 301 Moved Permanently (Постоянно перемещен)
Запрошенному ресурсу был приписан новый постоянный URI и любая будущая ссылка на этот ресурс должна делаться с использованием одного из присланных URI. Клиенты с возможностью редактирования связей должны, где возможно, автоматически менять связи для ссылок Request-URI на одну или более новых ссылок, присланных сервером. Этот отклик можно кэшировать, если не указано обратного.
Если новый URI является адресом (location), его URL должен быть задан в поле Location отклика. Если метод запроса не HEAD, объект отклика должен содержать короткое гипертекстное замечание с гиперсвязью, указывающей на новый URI.
Если получен статусный код 301 в ответ на запрос, отличный от GET или HEAD, агент пользователя не должен автоматически переадресовывать запрос, если только это не может быть подтверждено пользователем, так как такая переадресация может изменить условия, при которых направлен запрос.
Замечание: При автоматической переадресации запроса POST, получив статусный код 301, некоторые существующие агенты пользователя HTTP/1.0 ошибочно меняют его на запрос GET.
9.3.3. 302 Moved Temporarily (Временно перемещен)
Запрошенный ресурс размещается временно под различными URI.
Так как переадресация может быть случайно изменена, клиент должен продолжать использовать Request-URI для будущих запросов. Этот отклик допускает кэширование, если имеются соответствующие указания в полях заголовка Cache-Control или Expires.
Если новый URI является адресом (location), его URL должен задаваться полем Location отклика. Если запрошенный метод не HEAD, объект отклика должен содержать короткое гипертекстное замечание с гиперсвязью, указывающей на новый URI.
Если в ответ на запрос, отличный от GET или HEAD, получен статусный код 302, агент пользователя не должен автоматически переадресовывать запрос, если это не может быть подтверждено пользователем, так как это может изменить условия, при которых был выдан запрос.
Замечание: Когда после получения статусного кода 302 автоматически переадресуется запрос POST, некоторые существующие агенты пользователя HTTP/1.0 ошибочно меняют его на запрос GET.
9.3.4. 303 See Other (смотри другие)
Отклик на запрос может быть найден под разными URI. Его следует извлекать с помощью метода GET. Этот метод первоначально создан для того, чтобы позволить переадресацию агента пользователя на выбранный ресурс при запуске скрипта с помощью POST. Новый URI не является заменой ссылки для первоначально запрошенного ресурса. Отклик 303 не кэшируется, но отклик на второй (переадресованный) запрос может кэшироваться.
Если новый URI является адресом (location), его URL должно быть задано в поле Location отклика. Если метод запроса не HEAD, объект отклика должен содержать гипертекстовую ссылку на новый URI.
9.3.5. 304 Not Modified (Не модифицировано)
Если клиент выполнил условный запрос GET и получил доступ, а документ не был модифицирован, сервер должен реагировать этим статусным кодом. Отклик не должен содержать тела сообщения.
Отклик должен включать поля заголовка:
Дата
ETag и/или Content-Location, если заголовок был послан в рамках отклика 200 на тот же самый запрос
Expires, Cache-Control и/или Vary, если значение поля может отличаться от посланного в каком-либо предыдущем отклике того же типа
Если условный GET использовал строгий валидатор кэша (см. раздел 12.8.3), отклик не должен содержать других заголовков объекта. В противном случае (напр., условный GET использовал слабый валидатор), отклик не должен включать в себя другие заголовки. Это предотвращает несогласованности между кэшированными телами объектов и актуализованными заголовками (updated headers).
Если отклик 304 указывает на то, что объект не кэширован, тогда кэш должен игнорировать отклик и повторить запрос уже в безусловном режиме.
Если кэш использует полученный отклик 304 для актуализации записи в кэше, то кэш должен выполнить актуализацию с учетом новых значений полей, присланных в отклике.
Отклик 304 не должен включать в себя тело сообщения и, по этой причине всегда завершается пустой строкой после полей заголовка.
9.3.6. 305 Use Proxy (Используйте прокси)
Запрошенный ресурс должен иметь доступ через прокси-сервер, указанный в поле Location. Поле Location задает URL прокси-сервера. Предполагается, что получатель повторит запрос через прокси.
9.4. Client Error 4xx (Ошибка клиента)
Класс статус кодов 4xx предназначен для случаев, когда клиент допустил ошибку. За исключением случая отклика на запрос HEAD, серверу следует включить объект, содержащий объяснение ошибочной ситуации, а также указать, является ли ситуация временной или постоянной. Эти статусные коды применимы к любому методу запросов. Агенту пользователя следует отобразить все объекты.
Замечание. Если клиент посылает данные, реализация сервера, использующая протокол TCP, должна позаботиться о том, чтобы клиент получил пакет, содержащий отклик, до того как сервер закроет данное соединение. Если клиент продолжает посылку данных серверу после закрытия связи, TCP-уровень сервера должен послать клиенту пакет reset (сброс), который может стереть содержимое входного буфера клиента до того, как оно будет прочитано и интерпретировано приложением HTTP.
9.4.1. 400 Bad Request (Плохой запрос)
Запрос может быть не понят сервером из-за ошибочного синтаксиса.
Клиенту не следует повторять запрос без модификации.
9.4.2. 401 Unauthorized (Не авторизован)
Запрос требует авторизации пользователя. Отклик должен включать в себя поле заголовка WWW-Authenticate (раздел 13.46), содержащее требование (challenge), применимое к запрошенному ресурсу. Клиент может повторить запрос с соответствующим содержимым поля заголовка Authorization (раздел 13.8). Если запрос уже включал допуск в поле Authorization, тогда отклик 401 указывает на то, что данный допуск не работает. Если отклик 401 содержит то же требование, что и предшествующий отклик, а агент пользователя уже пробовал пройти идентификацию по крайней мере хотя бы раз, тогда пользователю следует предоставить объект, содержащийся в отклике, так как он может содержать полезную диагностическую информацию. Идентификация доступа HTTP описана в разделе 10.
9.4.3. 402 Необходима оплата
Этот код зарезервирован для использования в будущем.
9.4.4. 403 Forbidden (Запрещено)
Сервер понял запрос, но отказался его исполнить. Авторизация не поможет и повторять запрос не следует. Если метод запроса не HEAD, а сервер желает открыто объявить причину неисполнения запроса, то ему следует описать соображения, по которым запрос отклонен Этот статусный код обычно используется, когда сервер не хочет показывать, почему запрос отклонен, или когда другой отклик не подходит.
9.4.5. 404 Not Found (Не найдено)
Сервер не нашел ничего, отвечающего Request-URI. Не приводится никаких данных о том, являются ли эта ситуация временной или постоянной.
Если сервер не хочет сделать эту информацию открытой для клиента, вместо этого может использоваться статусный код 403. Статусный код 410 (Gone - Утрачен) следует использовать, если сервер знает за счет некоторого внутреннего механизма конфигурации, что старый ресурс постоянно недоступен и не имеет нового адреса его размещения.
9.4.6. 405 Method Not Allowed (Метод не разрешен)
Метод, специфицированный в Request-Line, не разрешен для ресурса, указанного Request-URI.
Отклик должен включать заголовок Allow, содержащий список разрешенных методов для запрошенного ресурса.
9.4.7. 406 Not Acceptable (Не приемлемо)
Ресурс, идентифицированный запросом, способен только генерировать объекты откликов, которые имеют характеристики, неприемлемые согласно заголовкам accept, присланным в запросе.
Если это не запрос HEAD, отклик должен включать объект, содержащий список доступных характеристик объекта и адреса, где пользователь или агент пользователя может выбрать нечто наиболее подходящее. Формат объекта специфицируется типом среды, приведенным в поле заголовка Content-Type. В зависимости от формата и возможностей агента пользователя, оптимальный выбор может быть сделан автоматически. Однако данная спецификация не определяет какого-либо стандарта для такого автоматического выбора.
Замечание. HTTP/1.1 серверам разрешено присылать отклики, которые неприемлемы согласно заголовкам accept, присланным в запросе. В некоторых случаях, может оказаться предпочтительнее послать отклик 406. Агенты пользователя могут просматривать заголовки приходящих откликов с тем, чтобы определить, являются ли они приемлемыми. Если отклик не может быть воспринят, агенту пользователя следует временно прервать прием данных и запросить пользователя принять решение о дальнейших действиях.
9.4.8. 407 Proxy Authentication Required (Необходима идентификация прокси)
Этот статусный код подобен 401 (Unauthorized), но указывает, что клиент должен сначала авторизоваться на прокси-сервере. Прокси должен прислать в ответ поле заголовка Proxy-Authenticate (раздел 13.33), содержащего требования, реализуемые на прокси для запрошенного ресурса. Клиент может повторить запрос с подходящим полем заголовка Proxy-Authorization (раздел 13.34). Авторизация доступа HTTP описана в разделе 10.
9.4.9. 408 Request Timeout (Таймаут запроса)
Клиент не выдал запрос в пределах временного интервала, в течение которого сервер его ожидал. Клиент может повторить запрос без модификаций в любое время.
9.4.10. 409 Conflict (Конфликт)
Выполнение запроса не может быть завершено из-за конфликта с текущим состоянием ресурса. Этот статусный код разрешен в ситуациях, где предполагается, что пользователь может разрешить конфликт и повторно послать запрос. Тело отклика должно включать достаточно информации, чтобы пользователь мог понять причину конфликта. В идеале, объект отклика должен был бы включать достаточно информации для пользователя или агента пользователя для того, чтобы уладить конфликт, однако это невозможно и необязательно.
Конфликты наиболее вероятно происходят в результате запроса PUT. Если задействована версия и объект операции PUT вызывает изменение ресурса, которые конфликтуют с изменениями внесенными запросом, выполненным ранее, сервер может использовать отклик 409 для того, чтобы указать на невозможность завершить выполнение запроса. В этом случае объект отклика должен содержать список отличий между двумя версиями формата, определенном откликом Content-Type.
9.4.11. 410 Gone (Исчез)
Запрошенный ресурс не является более доступным на сервере и не известен указатель переадресации. Это условие следует считать постоянным. Клиенты с возможностями редактирования связей должны ликвидировать ссылки на Request-URI после подтверждения пользователем. Если сервер не знает или не имеет возможности определить, является ли данное условие постоянным или временным, следует использовать отклик со статусным кодом 404 (Not Found). Этот отклик можно кэшировать, если не указано обратного.
Отклик 410 первоначально предназначался для того, чтобы помочь работе задач в WWW-среде путем сообщения получателю о том, что ресурс заведомо недостижим и владелец сервера хотел бы, чтобы связи с этим ресурсом были удалены. Такое событие является типичным для ограниченного периода времени и для ресурсов, принадлежащих частным лицам, которые не работают более с данным сервером. Не обязательно отмечать все постоянно недоступные ресурсы, как исчезнувшие (Gone) или сохранять такую пометку произвольное время - это оставлено на усмотрение собственника сервера.
9.4.12. 411 Length Required (Необходима длина)
Сервер отказывается принять запрос без определенного значения Content-Length. Клиент может повторить запрос, если он добавит корректное значение поля заголовка Content-Length, содержащего длину тела сообщения.
9.4.13. 412 Precondition Failed (Предварительные условия не выполнены)
Предварительные условия, заданные в одном или более полях заголовка запроса, воспринимаются как не выполненные, когда это проверено сервером. Этот код отклика позволяет клиенту установить предварительные условия для метаинформации (данные поля заголовка) текущего ресурса и, таким образом, предотвратить возможность использования запрошенного метода для ресурса, отличного от указанного.
9.4.14. 413 Request Entity Too Large (Объект запроса слишком велик)
Сервер отказывается обрабатывать запрос, потому что объект запроса больше, чем сервер способен обработать. Сервер может закрыть соединение, чтобы помешать клиенту продолжать посылать запросы.
Если условие является временным, серверу следует включить поле заголовка Retry-After, чтобы указать на временность этого условия, что означает возможность повторения запроса некоторое время спустя.
9.4.15. 414 Request-URI Too Long (URI запроса слишком велик)
Сервер отказывается обслужить запрос, потому что Request-URI длиннее, чем сервер способен интерпретировать. Это редкое обстоятельство может возникнуть только, когда клиент не корректно преобразует запрос POST в GET с длинной информацией запроса. При этом клиент ныряет в "черную дыру" переадресаций. Примером может служить преадресованный URL префикс, который указывает на свой суффикс, или случай атаки сервера клиентом, который пытается использовать дыры в системе безопасности, имеющиеся у клиентов с фиксированной емкостью буферов для работы с Request-URI.
9.4.16. 415 Unsupported Media Type (Неподдерживаемый тип среды)
Сервер отказывается обслужить запрос, потому что объект запроса имеет формат, неподдерживаемый запрашиваемым ресурсом для указанного метода.
9.5. Сервер ошибок 5xx
Статусный код отклика, начинающийся с цифры "5", указывает на случаи, когда сервер опасается, что он ошибся или не может реализовать запрос. За исключением случаев, когда обрабатывается запрос HEAD, серверу следует включить объект, содержащий объяснение создавшейся ошибочной ситуации и указывающей на то, является ли ситуация временной или постоянной. Агенту пользователя следует отобразить пользователю любой объект, включенный в отклик. Эти коды откликов применимы для любых методов запроса.
9.5.1. 500 Internal Server Error (Внутренняя ошибка сервера)
Сервер столкнулся с непредвиденными условиями, которые мешают ему исполнить запрос.
9.5.2. 501 Not Implemented (Не применимо)
Сервер не поддерживает функцию, которая должна быть реализована в ходе исполнения запроса. Это адекватный отклик, когда сервер не распознает метод запроса и не способен поддерживать его для данного ресурса.
9.5.3. 502 Bad Gateway (Плохой шлюз)
Сервер при работе в качестве шлюза или прокси получил неверный отклик от вышестоящего сервера, к которому он обратился, выполняя запрос.
9.5.4. 503 Service Unavailable (Услуга не доступна)
Сервер в данный момент не может обработать запрос в связи с временной перегрузкой или другими сложившимися обстоятельствами.
Замечание. Существование статусного кода 503 не предполагает, что сервер должен использовать его, когда оказывается перегруженным. Некоторые серверы могут захотеть просто отказаться устанавливать соединение.
9.5.5. 504 Gateway Timeout (Таймаут шлюза)
Сервер при работе в качестве внешнего шлюза или прокси-сервера не получил своевременно отклик от вышестоящего сервера, к которому он обратился, пытаясь исполнить запрос.
9.5.6. 505 HTTP Version Not Supported (Версия не поддерживается)
Сервер не поддерживает или отказывается поддерживать версию протокола HTTP, которая была использована в сообщении-запросе. Сервер индицирует, что он не способен или не хочет завершать обработку запроса в рамках главной версии клиента, как это описано в разделе 2.1, в отличие от сообщения об ошибке.
Отклику следует содержать объект, описывающий, почему эта версия не поддерживается и какие другие протоколы поддерживаются сервером.
4.5.6.1.10. Идентификация доступа
HTTP предлагает простой механизм аутентификации с помощью отклика, который может использоваться сервером, чтобы потребовать от клиента прислать запрос, содержащий аутентификационную информацию. Для определения схемы идентификации он использует лексему произвольной длины, не зависящую от применения строчных или прописных символов, за ней следует список пар атрибут-значение. Элементы списка отделяются друг от друга запятыми. Атрибуты представляют собой параметры, которые определяют аутентификацию в рамках выбранной схемы.
Auth-scheme | = token |
auth-param | = token "=" quoted-string |
Сообщение-отклик 401 (Unauthorized) используется исходным сервером для посылки требования авторизации агенту пользователя. Этот отклик должен включать в себя поле заголовка WWW-Authenticate, содержащее, по крайней мере, одно требование доступа к запрашиваемому ресурсу.
Challenge |
= auth-scheme 1*SP realm *( "," auth-param ) |
Realm |
= "realm" "=" realm-value |
realm-value | = quoted-string |
Атрибут области realm (не зависит от применения строчных или прописных букв) необходим для всех схем идентификации (authentication), которые посылают требования. Значение атрибута realm (чувствительно к применению строчных и прописных букв), в комбинации с каноническим корневым URL (см. раздел 4.1.2) сервера доступа, определяет пространство защиты. Эти области позволяют разделить защищенные ресурсы на сервере на ряд защищенных зон, каждая со своей собственной схемой идентификации и/или идентификационной базой данных. Значением атрибута области является строка, обычно присваиваемая исходным сервером, которая может иметь специфическую емантику для каждой схемы идентификации.
Агент пользователя, который хочет идентифицировать себя на сервере, после получения отклика 401 или 411 может сделать это, включив в запрос поле заголовка Authorization.
Значение поля Authorization состоит из записей, содержащих идентификационную информацию агента пользователя для области (realm) запрошенного ресурса.
credentials = basic-credentials
| auth-scheme #auth-param
Домен, в пределах которого может автоматически использоваться идентификационная информация, определяется зоной защиты. Если предыдущий запрос был авторизован, та же идентификационная информация может быть использована для всех других запросов в пределах зоны защиты и во временных рамках, заданных схемой идентификации, параметрами и/или предпочтениями пользователя. Если не определено обратного схемой авторизации, одна зона защиты не может быть распространена за пределы ее сервера.
Если сервер не хочет принимать идентификационную информацию, присланную в запросе, он должен прислать отклик 401 (Unauthorized). Отклик должен включать поле заголовка WWW-Authenticate, содержащее требование (возможно новое), применимое для запрошенного ресурса, и объект, объясняющий причину отказа.
Протокол HTTP не ограничивает приложения только этим простым механизмом авторизации (требование-отклик). Может быть применен дополнительный механизм, такой как шифрование на транспортном уровне или использование инкапсуляции сообщений. Однако в данной спецификации эти дополнительные механизмы не определены.
Прокси-серверы должны быть полностью прозрачны по отношению авторизации агентов пользователя. То есть, они должны переадресовывать в неприкосновенном виде заголовки WWW-Authenticate и Authorization, согласно правилам описанным в разделе 13.8.
HTTP/1.1 позволяет клиенту передать идентификационную информацию в прокси и обратно с использованием заголовков Proxy-Authenticate и Proxy-Authorization.
10.1 Базовая схема идентификации (Authentication)
Базовая схема авторизации базируется на модели, в которой агент пользователя должен идентифицировать себя с помощью имени пользователя и пароля, необходимого для каждой области (realm). Значение атрибута realm должно рассматриваться в виде неотображаемой строки символов, которая может сравниваться с другим значение realm на этом сервере.
Сервер обслужит запрос только в случае, если убедится в корректности имени и пароля пользователя для данной зоны защиты Request-URI. Не существует каких-либо опционных параметров авторизации.
При получении неавторизованного запроса для URI в пределах зоны защиты (protection space), сервер может реагировать посылкой требования в виде:
WWW-Authenticate: Basic realm="WallyWorld"
где "WallyWorld" - строка присвоенная сервером для идентификации зоны защиты Request-URI.
Чтобы получить авторизацию клиент посылает свое имя и пароль, разделенные символом двоеточие (":"), и закодированные согласно base64.
basic-credentials = "Basic" SP basic-cookie
basic-cookie =
user-pass = userid ":" password
userid = *
password = *TEXT
Идентификационная информация может быть чувствительной к применению строчных или прописных букв.
Если агент пользователя хочет послать имя пользователя "Aladdin" и пароль "Сезам открой", он использует следующее поле заголовка:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Смотри раздел 14 по поводу соображений безопасности, связанных с базовой авторизацией.
10.2 Краткое изложение схемы авторизации
Краткое изложение идей авторизации для HTTP представлено в документе RFC-2069 [32].
4.5.6.1.11. Согласование содержимого
Большинство HTTP откликов включают в себя объекты, которые содержат информацию для интерпретации человеком-пользователем. Естественно, желательно обеспечить пользователя наилучшим объектом, соответствующим запросу. К сожалению для серверов и кэшей не все пользователи имеют одни и те же предпочтения и не все агенты пользователя в равной степени способны обрабатывать все типы объектов. По этой причине, HTTP имеет несколько механизмов обеспечения согласования содержимого - процесс выбора наилучшего представления для данного отклика, когда доступны несколько возможностей.
Замечание. Это не называется "согласование формата " потому, что альтернативные представления могут принадлежать к одному и тому же типу среды, но использовать различные возможности этого типа, например, различные иностранные языки.
Любой отклик, содержащий тело объекта может быть предметом согласования, включая отклики об ошибках. Существует два вида согласования содержимого, которые возможны в HTTP: согласование под управлением сервера и под управлением агента пользователя. Эти два сорта согласования могут использоваться по отдельности или в сочетании. Один из методов, называемый прозрачным согласованием, реализуется, когда кэш использует информацию, полученную от исходного сервера в результате согласования под управлением агента пользователя. Эта информация используется для последующих запросов, где осуществляется согласование под управлением сервера.
11.1 Согласование, управляемое сервером
Если выбор наилучшего представления для отклика выполнен с использованием некоторого алгоритма на сервере, такая процедура называется согласованием под управлением сервера. Выбор базируется на доступных представлениях отклика (размеры, в пределах которых он может варьироваться, язык, кодировка и т.д.) и на содержимом конкретных полей заголовка в сообщении-запросе или другой информации, имеющей отношение к запросу (например, сетевой адрес клиента).
Согласование, управляемое сервером предпочтительнее, когда алгоритм выбора из числа доступных представлений трудно описать агенту пользователя. Согласование под управлением сервера привлекательно тогда, когда сервер хочет послать свои "наилучшие предложения" клиенту вместе с первым откликом (надеясь избежать задержек RTT последующих запросов, если предложение удовлетворит пользователя). Для того чтобы улучшить предложения сервера, агент пользователя может включить в запрос поля заголовка (Accept, Accept-Language, Accept-Encoding, и т.д.), которые описывают его предпочтения для данного запроса. Согласование под управлением сервера имеет следующие недостатки:
Для сервера трудно определить, что является "лучшим" для любого заданного пользователя, так как это потребовало бы полного знания как возможностей агента пользователя, так конкретного назначения отклика (напр., хочет ли пользователь видеть отклик на экране или отпечатать на принтере?).
Заставлять агента пользователя описывать свои возможности при каждом запросе крайне неэффективно (ведь лишь небольшой процент запросов имеют несколько вариантов представления) и потенциально нарушает конфиденциальность пользователя.
Это усложняет реализацию исходного сервера и алгоритм генерации откликов на запросы.
Это может ограничить возможность общедоступного кэша использовать один и тот же отклик для запросов многих пользователей.
HTTP/1.1 включает в себя следующие поля заголовка запроса для активации согласования, управляемого сервером, через описание возможностей агента пользователя и предпочтений самого пользователя: Accept (раздел 13.1), Accept- Charset (раздел 13.2), Accept-Encoding (раздел 13.3), Accept-Language (раздел 13.4) и User-Agent (раздел 13.42). Однако, исходный сервер не ограничен этими рамками и может варьировать отклик, основываясь на свойствах запроса, включая информацию помимо полей заголовка запроса или используя расширения полей заголовка нерассмотренные в данной спецификации.
Исходные серверы HTTP/1.1 должны включать соответствующие, управляемом сервером. Поле Vary описывает пределы, в которых может варьироваться отклик (то есть, пределы, в которых исходный сервер выбирает свои "наилучшие предложения" отклика из многообразия редставлений).
HTTP/1.1 общедоступный кэш должен распознавать поле заголовка Vary, когда оно включено в отклик и подчиняется требованиям, описанным в разделе 12.6, где рассматриваются взаимодействия между кэшированием и согласованием содержимого.
11.2. Согласование, управляемое агентом (Agent-driven Negotiation)
При согласовании, управляемом агентом, выбор наилучшего представления для отклика выполняется агентом пользователя после получения стартового отклика от исходного сервера. Выбор базируется на списке имеющихся представлений отклика, включенном в поля заголовка (эта спецификация резервирует имя поля Alternates, как это описано в приложении 16.6.2.1,) или в тело объекта исходного отклика, при этом каждое представление идентифицируется своим собственным URI.
Выбор из числа представлений может быть выполнен автоматически (если агент пользователя способен на это) или вручную пользователем, выбирая вариант из гипертекстного меню.
Согласование, управляемое агентом, имеет преимущество тогда, когда отклик варьируется в определенных пределах (таких как тип, язык или кодирование), когда исходный сервер не способен определить возможности агента пользователя, проанализировав запрос, и вообще, когда общедоступные кэши используются для распределения нагрузки серверов и для снижения сетевого трафика.
Согласование под управлением агента имеет тот недостаток, что требуется второй запрос для получения наилучшего альтернативного представления. Этот второй запрос эффективен только тогда, когда используется кэширование. Кроме того, эта спецификация не определяет какого-либо механизма поддержки автоматического выбора, хотя она и не препятствует применению любого такого механизма в рамках расширения HTTP/1.1.
HTTP/1.1 определяет статусные коды 300 (Multiple Choices - множественный выбор) и 406 (Not Acceptable - Не приемлем) для активации согласования под управлением агента, когда сервер не хочет или не может обеспечить свой механизм согласования.
11.3 Прозрачное согласование (Transparent Negotiation)
Прозрачное согласование представляет собой комбинацию управления сервера и агента. Когда кэш получает форму списка возможных представлений откликов (как в согласовании под управлением агента) и кэшу полностью поняты пределы вариации, тогда кэш становится способным выполнить согласование под управлением сервера для исходного сервера при последующих запросах этого ресурса.
Прозрачное согласование имеет преимущество распределения работы согласования, которое в противном случае было бы выполнено исходным сервером. При этом удаляется также задержка, сопряженная со вторым запросом при схеме согласования под управлением агента, когда кэш способен правильно прогнозировать отклик.
Эта спецификация не определяет какого-либо механизма для прозрачного согласования, хотя она и не препятствует использованию таких механизмов в будущих версиях HTTP/1.1.
Выполнение прозрачного согласования кэшем HTTP/1.1 должно включать в отклик поле заголовка Vary (определяя пределы его вариаций), обеспечивая корректную работу со всеми клиентами HTTP/1.1.
4.5.6.1.12 Кэширование в HTTP
HTTP обычно используется для распределенных информационных систем, где эксплуатационные характеристики могут быть улучшены за счет применения кэширования откликов. Протокол HTTP/1.1 включает в себя много элементов, предназначенных для оптимизации такого кэширования. Благодаря тому, что эти элементы завязаны с другими аспектами протокола и из-за их взаимодействия друг с другом, полезно описать базовую схему кэширования в HTTP отдельно от детального рассмотрения методов, заголовков, кодов откликов и т.д.
Кэширование представляется бесполезным, если оно значительно не улучшит работу. Целью кэширования в HTTP/1.1 является исключение во многих случаях необходимости посылать запросы, а в некоторых других случаях - полные отклики. При этом уменьшается число необходимых RTT для многих операций. Для этих целей используется механизм "истечения срока" (expiration) (см. раздел 12.2). Одновременно снижаются требования к полосе пропускания сети, для чего применяется механизм проверки пригодности (см. раздел 12.3).
Требования к рабочим характеристикам, доступности и работе без соединения заставляют нас несколько снизить семантическую прозрачность. Протокол HTTP/1.1 позволяет исходным серверам, кэшам и клиентам снизить прозрачность, когда необходимо. Так как непрозрачность операций может поставить в тупик недостаточно опытных пользователей, а также привести к определенной несовместимости для некоторых серверных приложений (таких как торговля по заказу), протокол рекомендует не убирать прозрачность полностью, а лишь несколько ослабить.
Следовательно, протокол HTTP/1.1 обеспечивает следующие важные моменты:
Протокольные особенности, которые гарантируют полную семантическую прозрачность, когда это требуется всеми участниками процесса.
Протокольные особенности, которые позволяют исходному серверу или агенту пользователя запросить и управлять непрозрачными операциями.
Протокольные особенности, которые позволяют кэшу присоединить предупреждения к откликам, которые не сохраняют запрошенный уровень семантической прозрачности.
Базовым принципом является возможность для клиентов детектировать любое ослабление семантической прозрачности.
Замечание. Разработчики серверов, кэшей или клиентов могут столкнуться с решениями, которые не обсуждались в данной спецификации. Если решение может повлиять на семантическую прозрачность, разработчик может ошибаться относительно прозрачной работы, не проведя детального анализа и не убедившись, что нарушение такой прозрачности дает существенные преимущества.
12.1 Корректность кэша
Корректный кэш должен реагировать на запрос откликом новейшей версии, которой он владеет. Разумеется, отклик должен соответствовать запросу (см. разделы 12.5, 12.6, и 12.12) и отвечать одному из следующих условий:
Он был проверен на эквивалентность с тем, который бы прислал исходный сервер при соответствующем запросе (раздел 12.3);
Он достаточно нов (см. раздел 12.2). В варианте по умолчанию это означает, что он отвечает минимальным требованиям клиента, сервера и кэша по новизне (см. раздел 13.9). Если исходный сервер задает такие требования, то это только его требования на новизну.
Он включает в себя предупреждение, о нарушении требований новизны клиента или исходного сервера (см. разделы 12.5 и 13.45).
Это сообщение-отклик 304 (Not Modified), 305 (Proxy Redirect), или ошибка (4xx или 5xx).
Если кэш не может осуществлять обмен с исходным сервером, он должен реагировать в соответствии с вышеприведенными правилами, если отклик может быть корректно обслужен, в противном случае он должен отослать сигнал ошибки или предупреждения, указывающий, что имел место отказ в системе коммуникаций.
Если кэш получает отклик (полный отклик или код 304 (Not Modified)), который уже не является свежим, кэш должен переадресовать его запросившему клиенту без добавления нового предупреждения, и не удаляя существующего заголовка Warning.
Кэшу не следует пытаться перепроверить отклик, так как это может привести к бесконечному зацикливанию. Агент пользователя, который получает устаревший отклик без Warning, может отобразить предупреждение для пользователя.
12.2 Предупреждения
Когда кэш присылает опосредованный отклик, который "недостаточно свеж" (с точки зрения условия 2 раздела 12.1), к нему должно быть присоединено предупреждение об этом с использованием заголовка Warning. Это предупреждение позволяет клиентам предпринять соответствующие действия.
Предупреждения могут использоваться для других целей, как кэшами так и другими системами. Использование предупреждения, а не статусного кода ошибки, отличает эти отклики от действительных отказов в системе.
Предупреждения всегда допускают кэширование, так как они никогда не ослабляют прозрачности отклика. Это означает, что предупреждения могут передаваться HTTP/1.0 кэшам без опасения, что такие кэши просто передадут их как заголовки объектов отклика.
Предупреждениям приписаны номера в интервале от 0 до 99. Данная спецификация определяет номера кодов и их значения для каждого из предупреждений, позволяя клиенту или кэшу обеспечить во многих случаях (но не во всех) автоматическую обработку ситуаций.
Предупреждения несут в себе помимо кода и текст. Текст может быть написан на любом из естественных языков (предположительно базирующемся на заголовках Accept клиента) и включать в себя опционное указание того, какой набор символов используется.
К отклику может быть присоединено несколько предупреждений (исходным сервером или кэшем), включая несколько предупреждений с идентичным кодом. Например, сервер может выдать одно и то же предупреждение на английском и мордовском.
Когда к отклику присоединено несколько предупреждений, не будет практичным и разумным отображать их все на экране для пользователя. Эта версия HTTP не специфицирует строгих правил приоритета для принятия решения, какие предупреждения отображать и в каком порядке, но предлагает некоторые эвристические соображения.
Заголовок Warning и определенные в настоящий момент предупреждения описаны в разделе 13.45.
12.3 Механизмы управления кэшем
Базовым механизмом кэша в HTTP/1.1 (времена таймаутов и валидаторы) являются неявные директивы кэша. В некоторых случаях серверу или клиенту может потребоваться выдать прямую директиву кэшу. Для этих целей используется заголовок Cache-Control.
Заголовок Cache-Control позволяет клиенту или серверу передать большое число директив через запросы или отклики. Эти директивы переписывают указания, которые действуют по умолчанию при реализации алгоритма работы кэша. Если возникает явный конфликт между значениями заголовков, то используется наиболее регламентирующее требование (то есть, то, которое наиболее вероятно сохраняет прозрачность семантики).
Однако в некоторых случаях директивы Cache-Control сформулированы так, что явно ослабляют семантическую прозрачность (например, "max-stale" или "public"). Директивы Cache-Control подробно описаны в разделе 13.9.
12.4 Прямые предупреждения агента пользователя
Многие агенты пользователя позволяют переписывать базовый механизм кэширования. Например, агент пользователя может специфицировать то, какие кэшированные объекты (даже явно старые) не проверять на новизну. Или агент пользователя может всегда добавлять "Cache-Control: max-stale=3600" к каждому запросу.
Если пользователь переписал базовый механизм кэширования, агент пользователя должен явно указать всякий раз, когда это важно, что отображаемая информация не отвечает требованиям прозрачности (в частности, если отображаемый объект известен как устаревший). Так как протокол обычно разрешает агенту пользователя определять, является ли отклик устаревшим, такая индикация нужна только тогда, когда это действительно случится. Для такой индикации не нужно диалоговое окно; это может быть иконка (например, изображение гнилой рыбы) или какой-то иной визуальный индикатор.
Если пользователь переписал механизм кэширования таким образом, что он непомерно понизил эффективность кэша, агент пользователя должен непрерывно отображать индикацию (например, изображение горящих денег), так чтобы пользователь, беспечно расходующий ресурсы, страдал от заметной задержки откликов на его действия.
12.5 Исключения для правил и предупреждений
В некоторых случаях оператор кэша может выбрать такую конфигурацию, которая возвращает устаревшие отклики, даже если клиенты этого не запрашивали. Это решение не должно приниматься легко, но может быть необходимо по причинам доступности или эффективности, особенно когда кэш имеет плохую связь с исходным сервером. Всякий раз, когда кэш возвращает устаревший отклик, он должен пометить его соответствующим образом (используя заголовок Warning). Это позволяет клиентскому программному обеспечению предупредить пользователя о возможных проблемах.
Такой подход позволяет также агенту пользователя предпринять шаги для получения "свежего" отклика или информации из первых рук. По этой причине кэшу не следует присылать устаревшие отклики, если клиент запрашивает информацию из первых рук, если только невозможно это сделать по техническим или политическим причинам.
12.6 Работа под управлением клиента
Когда основным источником устаревшей информации является исходный сервер (и в меньшей мере промежуточные кэши), клиенту может быть нужно контролировать решение кэша о том, следует ли присылать кэшированный отклик без его проверки. Клиенты выполняют это, используя несколько директив заголовка Cache-Control.
Запрос клиента может специфицировать максимальный возраст, который он считает приемлемым для не верифицированного отклика. Клиент может также специфицировать минимальное время, в течение которого отклик еще считается пригодным для использования. Обе эти опции увеличивают ограничения, накладываемые на работу кэша.
Клиент может также специфицировать то, что он будет воспринимать устаревшие отклики с возрастом не более заданного. Это ослабляет ограничения, налагаемые на работу кэшей и, таким образом, может привести к нарушению семантической прозрачности, заданной исходным сервером, хотя это может быть необходимо для поддержания автономной работы кэша в условиях плохой коннективности.
12.7. Модель истечения срока годности
12.7.1 Определение срока годности под управлением сервера
Кэширование в HTTP работает наилучшим образом, когда кэши могут полностью исключить запросы к исходному серверу. Другими словами, кэш должен возвращать "свежий" отклик без обращения к серверу.
Предполагается, что серверы припишут в явном виде значения времени пригодности (expiration time) откликам в предположении, что объекты вряд ли изменятся семантически значимым образом до истечения этого времени. Это сохраняет семантическую прозрачность при условии, что время жизни выбрано корректно.
Механизм времени пригодности (expiration) применим только к откликам, взятым из кэша, а не к откликам, полученным из первых рук и переадресованных запрашивающему клиенту.
Если исходный сервер хочет усилить семантическую прозрачность кэша, тогда он может установить время истечения действия в прошлое, чтобы проверялся каждый запрос. Это означает, что всякий запрос изначально будет считаться устаревшим, и кэш будет вынужден проверить его прежде чем использовать для последующих запросов. О более жестких методах вынуждения проверки действенности отклика смотри раздел 13.9.4.
Если исходный сервер хочет заставить любой HTTP/1.1 кэш, вне зависимости от его конфигурации проверять каждый запрос, он может использовать директиву Cache-Control "must-revalidate" (см. раздел 13.9).
Серверы определяют реальные времена сроков пригодности, используя заголовок Expires, или директиву максимального возраста заголовка Cache-Control.
Время пригодности (expiration time) не может использоваться для того, чтобы заставить агента пользователя обновить картинку на дисплее или перезагрузить ресурс; его семантика применима только для механизма кэширования, а такой механизм нуждается только в контроле истечения времени жизни ресурса, когда инициируется новый запрос доступа к этому ресурсу.
12.7.2 Эвристический контроль пригодности
Так как исходные сервера не всегда предоставляют значение времени пригодности в явном виде, HTTP кэши присваивают им значения эвристически, используя алгоритмы, которые привлекают для оценки вероятного значения времени пригодности другие заголовки (такие как Last-Modified time).
Спецификация HTTP/1.1 не предлагает каких- либо специальных алгоритмов, но налагает предельные ограничения на полученный результат. Так как эвристические значения времени жизни могут подвергнуть риску семантическую прозрачность, они должны использоваться с осторожностью. Предпочтительнее, чтобы исходные серверы задавали время пригодности явно.
12.7.3. Вычисление возраста
Для того чтобы узнать является ли запись в кэш свежей, кэшу нужно знать превышает ли его возраст предельное время жизни. То, как вычислить время пригодности, обсуждается в разделе 12.7.4. Этот раздел описывает метод вычисления возраста отклика или записи в кэше.
В этом обсуждении используется термин "сейчас" для обозначения "текущего показания часов на ЭВМ, выполняющей вычисление". ЭВМ, которая использует HTTP, и в особенности ЭВМ, работающие в качестве исходных серверов и кэшей, должны использовать NTP [28] или некоторый схожий протокол для синхронизации их часов с использованием общего точного временного стандарта.
Следует обратить внимание на то, что HTTP/1.1 требует от исходного сервера посылки в каждом отклике заголовка Date, сообщая время, когда был сгенерирован отклик. Мы используем термин "date_value" для обозначения значения заголовка Date, в форме, приемлемой для арифметических операций.
HTTP/1.1 использует заголовок отклика Age для того, чтобы облегчить передачу информации о возрасте объектов между кэшами. Значение заголовка Age равно оценке отправителя времени, прошедшего с момента генерации отклика исходным сервером. В случае кэшированного отклика, который был перепроверен исходным сервером, значение Age базируется на времени перепроверки, а не на времени жизни оригинального отклика.
По существу значение Age равно сумме времени, в течение которого отклик был резидентен в каждом из кэшей вдоль пути от исходного сервера, плюс время распространения данных по сети.
Мы используем термин "age_value" для значения поля заголовка Age, в удобном для выполнения арифметических операций формате.
Возраст отклика может быть вычислен двумя совершенно независимыми способами.
Текущее время минус date_value, если местные часы синхронизованы с часами исходного сервера. Если результат отрицателен, он заменяется на нуль.
age_value, если все кэши вдоль пути отклика поддерживают HTTP/1.1.
Таким образом, мы имеем два независимых способа вычисления возраста отклика при его получении, допускается их комбинирование, например:
corrected_received_age = max(now - date_value, age_value)
и, поскольку мы имеем синхронизованные часы, или все узлы вдоль пути поддерживают HTTP/1.1, получается надежный (консервативный) результат.
Заметьте, что поправка применяется в каждом кэше HTTP/1.1 вдоль пути так, что, если встретится на пути кэш HTTP/1.0, правильное значение возраста будет получено потому, что его часы почти синхронизованы. Нам не нужна сквозная синхронизация (хотя ее не плохо бы иметь).
Из-за задержек, вносимых сетью, значительное время может пройти с момента генерации отклика сервером и получением его следующим кэшем или клиентом. Если не внести поправки на эту задержку, можно получить неправдоподобные значения возраста отклика.
Так как запрос, который определяет возвращаемое значение Age, должен быть инициирован до генерации этого значения Age, мы можем сделать поправку на задержки, вносимые сетью путем записи времени, когда послан запрос. Затем, когда получено значение Age, оно должно интерпретироваться относительно времени посылки запроса, а не времени когда был получен отклик. Этот алгоритм выдает результат, который не зависит от величины сетевой задержки. Таким образом, вычисляется:
corrected_initial_age = corrected_received_age + (now - request_time)
где "request_time" равно времени (согласно местным часам), когда был послан запрос, вызвавший данный отклик.
Резюме алгоритма вычисления возраста при получении отклика кэшем:
/*
* age_value
* |
равно значению Age: заголовок, полученный кэшем с этим откликом. |
* date_value
* | равно значению Date исходного сервера: заголовок |
* request_time
* | равно местному времени, когда кэш сделал запрос, который явился причиной этого кэшированного отклика |
* response_time
* | равно местному времени, когда кэш получил отклик |
* now
* | равно текущему (местному) времени |
*/
apparent_age = max(0, response_time - date_value);
corrected_received_age = max(apparent_age, age_value);
response_delay = response_time - request_time;
corrected_initial_age = corrected_received_age + response_delay;
resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;
Когда кэш посылает отклик, он должен добавить к corrected_initial_age время, в течение которого отклик оставался резидентно локальным. Он должен ретранслировать этот полный возраст, используя заголовок Age, следующему кэшу-получателю.
Заметьте, что клиент не может надежно сказать, что отклик получен из первых рук, но присутствие заголовка Age определенно указывает на то, что это не так. Кроме того, если значение в отклике соответствует более раннему времени, чем местное время запроса клиента, отклик, вероятно, получен не из первых рук (в отсутствие серьезного сбоя часов).
12.7.4 Вычисление времени жизни (Expiration)
Для того, чтобы решить, является ли отклик свежим или устаревшим, нам нужно сравнить его время жизни с возрастом. Возраст вычисляется так, как это описано в разделе 12.3. Этот раздел описывает то, как вычисляется время жизни, и как определяется, истекло ли время жизни отклика. В обсуждении, приведенном ниже, величины могут быть представлены в любой форме, удобной для выполнения арифметических операций.
Мы используем термин "expires_value" для обозначения содержимого заголовка Expires. Для обозначения числа секунд, определенного директивой максимального возраста заголовка Cache-Control отклика (см. раздел 13.9), используется термин "max_age_value".
Директива максимального возраста имеет приоритет перед Expires, так если max-age присутствует в отклике, вычисление производится просто:
freshness_lifetime = max_age_value
В противном случае, если в отклике присутствует Expires, то вычисления осуществляются следующим образом:
freshness_lifetime = expires_value - date_value
Заметьте, ни одно из этих вычислений не зависит от синхронизации и корректной работы местных часов, так как вся исходная информация получается от исходного сервера.
Если ни Expires, ни Cache-Control: max- age не определяют максимальный возраст отклика, а отклик не содержит других ограничений на кэширование, кэш может вычислить время жизни, используя эвристику. Если эта величина больше 24 часов, кэш должен присоединить к отклику Warning 13, если такое предупреждение еще не добавлено.
Кроме того, если отклик имеет время Last-Modified, эвристическое значение времени жизни должно быть не больше некоторой доли времени, прошедшего со времени модификации. Типичное значение этой доли может составлять 10%.
Расчет того, истекло ли время жизни отклика, достаточно прост:
response_is_fresh = (freshness_lifetime > current_age)
12.7.5 Устранение неопределенности значений времени жизни
Из-за того, что значения времени жизни часто назначаются оптимистически, может так случиться, что два кэша содержат две "свежих" записи одного и того же ресурса, которые различаются.
Если клиент, выполняя извлечение ресурса, получает отклик не из первых рук на запрос, который был свежим в своем собственном кэше, а заголовок Date в его кэше новей, чем Date нового отклика, тогда клиент может игнорировать этот отклик. Если это так, он может повторить запрос с директивой "Cache-Control: max-age=0" (см. раздел 13.9), чтобы усилить контроль со стороны исходного сервера.
Если кэш имеет два свежих отклика для одного и того же представления с различными указателями корректности (validator), он должен использовать тот, который имеет современный заголовок Date. Эта ситуация может возникнуть, когда кэш извлекает отклик из других кэшей, или потому, что клиент запросил перезагрузку или повторную проверку корректности заведомо свежего объекта.
12.7.6 Неопределенность из-за множественных откликов
Из-за того, что клиент может получать отклики по большому числу различных маршрутов, так что некоторые отклики проходят через одну последовательность кэшей, а другие, через другую, клиент может получить их не в той последовательности в какой они были посланы исходным сервером.
Хотелось бы, чтобы клиент использовал наиболее свежие оклики, даже если срок годности старых еще не истек.
Ни метка объекта, ни значение времени жизни не могут определять порядок откликов, так как возможно, что более поздний отклик имеет срок годности, который истекает раньше. Однако, спецификация HTTP/1.1 требует передачи заголовка Date в каждом отклике, а значения Date должны быть кратны одной секунде.
Когда клиент пытается перепроверить запись в кэше, а отклик, который он получает, содержит заголовок Date, который оказывается старше, чем у другой уже существующей записи, тогда клиенту следует безусловно повторить запрос и включить
Cache-Control: max-age=0
Чтобы заставить некоторые промежуточные кэши сверить свои копии непосредственно с исходным сервером, или
Cache-Control: no-cache
Чтобы заставить любые промежуточные кэши получит новые копии от исходного сервера.
Если значения Date равны, тогда клиент может использовать любой отклик (или может, если он особенно осторожен, затребовать новый отклик). Серверы не должны зависеть от возможности клиентов четкого выбора между откликами, сгенерированными в пределах одной и той же секунды, если их сроки пригодности перекрываются.
12.8 Модель проверки пригодности
Когда кэш имеет устаревшую запись, которую бы он хотел использовать в качестве отклика на запрос клиента, он сначала должен произвести сверку с базовым сервером (или возможно промежуточным кэшем, содержащим свежий отклик), чтобы убедиться, что кэшированная запись все еще применима. Мы это называем проверкой пригодности записи кэша ("validating"). Так как мы не хотим пересылки всей записи, если с ней все в порядке, и мы не хотим тратить лишнее время из-за RTT в случае, если запись более не пригодна, протокол HTTP/1.1 поддерживает использование условных методов.
Ключевой особенностью протокола для поддержки условных методов являются так называемые "валидаторы" кэша. Когда исходный сервер генерирует полный отклик, он подключает к нему некоторые виды валидаторов, которые хранятся вместе с самой записью в кэше.
Когда клиент (агент пользователя или прокси-кэш) выполняет условный запрос ресурса, для которого он имеет запись в кэше, он добавляет соответствующий валидатор к запросу.
Сервер сверяет полученный валидатор с текущим валидатором объекта и, если они совпадают, посылается отклик с соответствующим статусным кодом (обычно, 304 (Not Modified)) и без тела объекта. В противном случае он возвращает полный отклик (включая тело объекта). Таким образом, мы избегаем передачи полного отклика, если валидаторы взаимно согласованы.
Замечание. Функции сравнения, используемые при решении, согласуются ли между собой валидаторы, определены в разделе 12.8.3.
В HTTP/1.1 условный запрос выглядит точно также как и обычный запрос того же самого ресурса, за исключением того, что он несет в себе специальный заголовок (который содержит валидатор), и неявно меняет метод (обычный GET) на условный.
Протокол предусматривает как положительное, так и отрицательное значения условий проверки пригодности записей кэша. То есть, можно запросить, чтобы был реализован этот метод тогда и только тогда, когда валидатор подходит, или тогда и только тогда, когда ни один валидатор не подходит.
Замечание. Отклик, который не имеет валидатора, может кэшироваться и использоваться до истечения его срока годности, если только это явно не запрещено директивой Cache-Control. Однако, кэш не может выполнить условную доставку ресурса, если он не имеет валидатора для запрашиваемого объекта, что означает отсутствие возможности его актуализации после истечения срока годности.
12.8.1 Даты последней модификации
Значение поля заголовка объекта Last-Modified часто используется кэшем в качестве валидатора. Иными словами, запись в кэше рассматривается как пригодная, если объект не был модифицирован с момента, указанного в Last-Modified.
12.8.2 Валидаторы кэша для меток объектов (Entity Tag Cache Validators)
Значение поля заголовка объекта ETag (Entity Tag - метка объекта), представляет собой "непрозрачный" валидатор кэша.
Это может гарантировать большую надежность при контроле пригодности в ситуациях, когда неудобно запоминать модификации дат, где недостаточно односекундного разрешения для значения даты HTTP или где исходный сервер хочет избежать определенных парадоксов, которые могут возникнуть от использования дат модификации.
Метки объекта обсуждаются в разделе 3.10. Заголовки, используемые с метками объектов, рассмотрены в разделах 13.20, 13.25, 13.26 и 13.43.
12.8.3 Слабые и сильные валидаторы
Так как исходные серверы и кэши будут сравнивать два валидатора, чтобы решить, представляют ли они один и тот же объект, обычно подразумевается, что, если объект (тело объекта или любой заголовок) изменяется каким-либо образом, то и сопряженный валидатор изменится. Если это так, такой валидатор называется "сильным ".
Однако могут встретиться случаи, когда сервер предпочитает изменять валидатор только при семантически существенных изменениях. Валидатор, который не изменяется всякий раз при изменении ресурса, называется "слабым".
Метки объекта обычно являются "сильными валидаторами", но протокол предлагает механизм установки "слабой" метки объекта. Можно считать, что сильный валидатор это такой, который изменяется, если меняется хотя бы один бит в объекте, в то время как значение слабого изменяется при вариации значения объекта. Альтернативой можно считать точку зрения, при которой сильный валидатор является частью идентификатора конкретного объекта, в то время как слабый валидатор является частью идентификатора набора семантически эквивалентных объектов.
Замечание. Примером сильного валидатора является целое число, которое увеличивается на единицу всякий раз, когда в объект вносится какое-либо изменение.
Время модификации объекта при односекундном разрешении может быть лишь слабым валидатором, так как имеется возможность того, что ресурс может быть модифицирован дважды в течение одной и той же секунды.
Поддержка слабых валидаторов является опционной.
Однако слабый валидатор позволяет более эффективно кэшировать эквивалентные объекты.
Валидатор используется либо, когда клиент генерирует запрос и включает валидатор в поле заголовка проверки годности, или когда сервер сравнивает два валидатора.
Сильные валидаторы могут использоваться в любом контексте. Слабые валидаторы применимы только в контексте, который не зависит от точной эквивалентности объектов. Например, как один, так и другой вид валидаторов применим для условного GET. Однако, только сильный валидатор применим для фрагментированного извлечения ресурсов, так как в противном случае клиент может прервать работу с внутренне противоречивым объектом.
Единственной функцией протокола HTTP/1.1, определенной для валидаторов, является сравнение. Существует две функции сравнения валидаторов, в зависимости от того, допускает ли контекст использование слабых валидаторов или нет:
Функция сильного сравнения. Для того, чтобы считаться равными оба валидатора должны быть идентичными, и не один из них не должен быть слабым.
Функция слабого сравнения. Для того, чтобы считаться равными оба валидатора должны быть идентичными, но либо оба, либо один из них могут иметь метку "слабый" без какого-либо воздействия на результат.
Функция слабого сравнения может быть использована для простых (non-subrange - не фрагментных) GET-запросов. Функция сильного сравнения должна быть использована во всех прочих случаях.
Метка объекта является сильной, если она не помечена явно как слабая. В разделе 2.11 рассматривается синтаксис меток объектов.
Параметр Last-Modified time, при использовании в качестве валидатора запроса, является неявно (подразумевается) слабым, если не возможно установить, что он сильный, используя следующие правила:
Валидатор сравнивается исходным сервером с текущим рабочим валидатором для данного объекта и,
Исходный сервер твердо знает, что соответствующий объект не изменялся дважды за секунду, к которой привязан настоящий валидатор. Или
Валидатор предполагается использовать клиентом в заголовке If-Modified-Since или If-Unmodified-Since, так как клиент имеет запись в кэше для соответствующего объекта, и
Эта запись в кэш включает в себя значение Date, которое определяет время, когда исходный сервер послал оригинал запроса, и
Предлагаемый параметр Last-Modified time соответствует моменту времени, по крайней мере, на 60 секунд раньше значения Date.
или
Валидатор сравнивается промежуточным кэшем с валидатором, запомненным в записи для данного объекта, и
Эта запись в кэше включает в себя значение Date, которое определяет время, когда исходный сервер послал оригинал запроса, и
Предлагаемый параметр Last-Modified time соответствует моменту времени, по крайней мере, на 60 секунд раньше значения Date.
Этот метод базируется на том факте, что, если два различных отклика были посланы исходным сервером в пределах одной и той же секунды, но оба имеют одно и то же время Last-Modified, тогда, по крайней мере, один из этих откликов имеет значение Date равное его времени Last-Modified. Произвольный 60-секундный лимит предохраняет против возможности того, что значения Date и Last-Modified сгенерированы с использованием различных часов или в несколько разные моменты времени при подготовке отклика. Конкретная реализация может использовать величину больше 60 секунд, если считается, что 60 секунд слишком мало.
Кэш или исходный сервер, получающий условный запрос кэша, отличный от GET-запроса, должен использовать функцию сильного сравнения, чтобы оценить условие.
Эти правила позволяют кэшам HTTP/1.1 и клиентам безопасно произвести фрагментный доступ к ресурсам на глубину, которая получена от серверов HTTP/1.0.
12.8.4 Правила того, когда использовать метки объекта и даты последней модификации
Мы принимаем набор правил и рекомендаций для исходных серверов, клиентов и кэшей относительно того, когда должны использоваться различные типы валидаторов и для каких целей.
Исходный сервер HTTP/1.1:
Должен послать валидатор метки объекта, если только возможно его сгенерировать.
Может послать слабую метку объекта вместо сильной, если рабочие соображения поддерживают использования слабых меток объекта или если невозможно послать сильную метку объекта.
Должен послать значение Last-Modified, когда это возможно сделать, если только риск нарушения семантической прозрачности, которое может явиться следствием использования этой даты в заголовке, не приведет к серьезным проблемам.
Другими словами предпочтительным поведением для исходного сервера HTTP/1.1 является посылка сильной метки объекта и значения Last-Modified.
Для сохранения легальности сильная метка объекта должна изменяться всякий раз, когда каким-либо образом меняется ассоциированное значение объекта. Слабую метку объекта следует менять всякий раз, когда соответствующий объект изменяется семантически значимым образом.
Замечание. Для того, чтобы обеспечить семантически прозрачное кэширование, исходный сервер должен избегать повторного использования специфических, сильных меток для двух разных объектов, или повторного использования специфических, слабых меток для двух семантически разных объектов. Записи в кэш могут существовать сколь угодно долгое время вне зависимости от времени годности. Таким образом, может оказаться неразумным ожидать, что кэш никогда вновь не попытается перепроверить запись, используя валидатор, который он получил в какой-то момент в прошлом.
Клиенты HTTP/1.1:
Если метка объекта была прислана исходным сервером, эта метка должна быть использована в любом условном запросе кэша (с If-Match или If-None-Match).
Если только значение Last-Modified было прислано исходным сервером, оно должно использоваться в нефрагментных, условных запросах кэша (с использованием If-Modified-Since).
Если только значение Last-Modified было прислано исходным сервером HTTP/1.0, оно может использоваться в фрагментных, условных запросах кэша (с использованием If-Unmodified-Since:). Агенту пользователя следует обеспечить способ блокировки этого в случае возникновения трудностей.
Если и метка объекта и значение Last-Modified были присланы исходным сервером, в условных запросах кэша следует использовать оба валидатора. Это позволяет корректно реагировать кэшам, поддерживающим как HTTP/1.0, так и HTTP/1.1.
Кэш HTTP/1.1 при получении запроса должен использовать наиболее регламентирующий валидатор, когда проверяется, соответствуют ли друг другу запись в буфере клиента и собственная запись в кэше. Это единственный выход, когда запрос содержит как метку объекта, так и валидатор last-modified-date (If-Modified-Since или If-Unmodified-Since).
Базовым принципом всех этих правил является то, что HTTP/1.1 серверы и клиенты должны пересылать как можно больше надежной информации в своих запросах и откликах. HTTP/1.1 системы, принимая эту информацию, используют наиболее консервативное предположение относительно валидаторов, которые они получают.
Клиенты HTTP/1.0 и кэши будут игнорировать метки объектов. Вообще, значения времени последней модификации, полученные или используемые этими системами, будут поддерживать прозрачное и эффективное кэширование и, по этой причине, исходные серверы HTTP/1.1 должны присылать значения параметров Last-Modified. В тех редких случаях, когда в качестве валидатора системой HTTP/1.0 используется значение Last-Modified, могут возникнуть серьезные проблемы, и тогда исходные серверы HTTP/1.1 присылать их не должны.
12.8.5 Условия пригодности
Принцип использования меток объектов базируется на том, что только автор услуг знает семантику ресурсов достаточно хорошо, чтобы выбрать подходящий механизм контроля кэширования. Спецификация любой функции сравнения валидаторов более сложна, чем сравнение байтов. Таким образом, для целей проверки пригодности записи в кэше никогда не используется сравнение любых других заголовков кроме Last-Modified, для совместимости с HTTP/1.0.
12.9. Кэшируемость отклика
Если только нет специального ограничения директивой Cache-Control (раздел 13.9), система кэширования может всегда запоминать отклик (см. раздел 12.8) в качестве записи в кэш, может прислать его без проверки пригодности, если он является свежим, и может послать его после успешной проверки пригодности. Если нет ни валидатора кэша ни времени пригодности, ассоциированного с этим откликом, мы не ожидаем, что такой отклик будет кэширован, но некоторые кэши могут нарушить это правило (например, когда имеется плохая коннективность или она вообще отсутствует).
Клиент обычно может детектировать, что такой отклик был взят из кэша после сравнения заголовка Date с текущим временем.
Заметьте, что некоторые кэши HTTP/1.0 нарушают эти правила, даже не присылая предупреждения.
Однако, в некоторых случаях может быть неприемлемо для кэша сохранять объект или присылать его в ответ на последующие запросы. Это может быть потому, что автор сервиса полагает необходимой абсолютную семантическую прозрачность по соображениям безопасности или конфиденциальности. Определенные директивы Cache-Control предназначены для того, чтобы сервер мог указать, что некоторые объекты ресурсов или их части не могут кэшироваться ни при каких обстоятельствах.
Заметьте, что раздел 13.8 в норме препятствует кэшу запоминать и отсылать отклик на предыдущий запрос, если этот запрос включает в себя заголовок авторизации.
Отклик, полученный со статусным кодом 200, 203, 206, 300, 301 или 410, может быть запомнен кэшем и использован в ответе на последующие запросы, если директива не препятствует кэшированию. Однако, кэш, который не поддерживает заголовки Range и Content-Range не должен кэшировать отклики 206 (Partial Content).
Отклик, полученный с любым другим статусным кодом, не должен отсылаться в ответ на последующие запросы, если только нет директив Cache-Control или других заголовков, которые напрямую разрешают это. К таким, например, относятся: заголовок Expires (раздел 13.21); "max-age", "must-revalidate", "proxy-revalidate", "public" или "private" директива Cache-Control (раздел 13.9).
12.10 Формирование откликов кэшей
Целью кэша HTTP является запоминание информации, полученной в откликах на запросы, для использования в ответ на будущие запросы. Во многих случаях, кэш просто отсылает соответствующие части отклика отправителю запроса. Однако, если кэш содержит объект, базирующийся на предшествующем отклике, он может быть вынужден комбинировать части нового отклика с тем, что хранится в объекте кэша.
12.10.1 Заголовки End-to-end (точка-точка) и Hop-by-hop (шаг-за-шагом)
Для целей определения поведения кэшей и некэшурующих прокси-серверов заголовки HTTP делятся на две категории:
Заголовки End-to-end, которые должны быть пересланы конечному получателю запроса или отклика. Заголовки End-to-end в откликах должны запоминаться как часть объекта кэша и пересылаться в любом отклике, полученном из записи кэша.
Заголовки Hop-by-hop, которые имеют смысл только для одноуровневого транспортного соединения, они не запоминаются кэшем и не переадресуются прокси-серверами.
Следующие заголовки HTTP/1.1 относятся к категории hop-by-hop:
Connection
Keep-Alive
Public
Proxy-Authenticate
Transfer-Encoding
Upgrade
Все другие заголовки, определенные HTTP/1.1 относятся к категории end-to-end.
Заголовки Hop-by-hop, вводимые в будущих версиях HTTP, должны быть перечислены в заголовке Connection, как это описано в разделе 13.10.
12.10.2 Немодифицируемые заголовки
Некоторые черты протокола HTTP/1.1, такие как Digest Authentication, зависят от значения определенных заголовков end-to-end. Кэш или некэширующий прокси не должны модифицировать заголовок end-to-end, если только определение этого заголовка не требует или не разрешает этого.
Кэш или некэширующий прокси не должны модифицировать любое из следующих полей запроса или отклика или добавлять какие-либо поля, если они еще не существуют:
Content-Location
Etag
Expires
Last-Modified
Кэш или некэширующий прокси не должны модифицировать или добавлять следующие поля в любых запросах и в откликах, которые содержат директиву no-transform Cache-Control:
Content-Encoding
Content-Length
Content-Range
Content-Type
Кэш или некэширующий прокси могут модифицировать или добавлять эти поля в отклик, который не включает директиву no-transform. Если же он содержит эту директиву, следует добавить предупреждение 14 (Transformation applied), если оно еще не занесено в отклик.
Предупреждение. Ненужная модификация заголовков end-to-end может вызвать отказы в авторизации, если в поздних версиях HTTP использован более строгий механизм.
Такие механизмы авторизации могут использовать значения полей заголовков не перечисленных здесь.
12.10.3 Комбинирование заголовков
Когда кэш делает запрос серверу о пригодности ресурса и сервер выдает отклик 304 (Not Modified), кэш должен подготовить и отправить отклик, чтобы послать клиенту. Кэш использует тело объекта из записи в кэше при формировании отклика. Заголовки end-to-end записанные в кэше, используются для конструирования отклика. Исключение составляют любые end-to-end заголовки, поступившие в рамках отклика 304, они должны заместить соответствующие заголовки из записи в кэше. Если только кэш не решил удалить запись, он должен также заменить end-to-end заголовки своей записи соответствующими заголовками из полученного отклика.
Другими словами, набор end-to-end заголовков, полученный вместе откликом переписывает все соответствующие end-to-end заголовки, из записи в кэше. Кэш может добавить к этому набору заголовки предупреждений (см. раздел 13.45).
Если имя поля заголовка приходящего отклика соответствует более чем одной записи в кэше, все старые заголовки заменяются.
Замечание. Это правило позволяет исходному серверу использовать отклик 304 (Not Modified) для актуализации любого заголовка, связанного с предыдущим откликом для того же объекта, хотя это может не всегда иметь смысл. Это правило не позволяет исходному серверу использовать отклик 304 (not Modified) для того, чтобы полностью стереть заголовок, который был прислан предыдущим откликом.
12.10.4 Комбинирование байтовых фрагментов
Отклик может передать только субдиапазон байтов тела объекта, либо потому, что запрос включает в себя один или более спецификаций Range, либо из-за преждевременного обрыва соединения. После нескольких таких передач кэш может получить несколько фрагментов тела объекта.
Если кэш запомнил не пустой набор субфрагментов объекта, а входящий отклик передает еще один фрагмент, кэш может комбинировать новый субфрагмент с уже имеющимся набором, если для обоих выполняются следующие условия:
Оба приходящие отклика и запись в кэше должны иметь валидатор кэша.
Оба валидатора кэша должны соответствовать функции сильного сравнения (см. раздел 12.8.3).
Если любое из условий не выполнено, кэш должен использовать только наиболее поздний частичный отклик и отбросить другую частичную информацию.
12.11. Кэширование согласованных откликов
Использование согласования содержимого под управлением сервера (раздел 11), что индицируется присутствием поля заголовка Vary в отклике, изменяет условия и процедуру, при которой кэш может использовать отклик для последующих запросов.
Сервер должен использовать поле заголовка Vary (раздел 13.43), чтобы информировать кэш о том, какие пределы для поля заголовка используются при выборе представления кэшируемого отклика. Кэш может использовать выбранное представление для ответов на последующие запросы, только когда они имеют те же или эквивалентные величины полей заголовка, специфицированных в заголовке отклика Vary. Запросы с различными значениями одного или нескольких полей заголовка следует переадресовывать исходному серверу.
Если представлению присвоена метка объекта, переадресуемый запрос должен быть условным и содержать метки в поле заголовка If-None-Match всех его кэшированных записей для Request-URI. Это сообщает серверу набор объектов, которые в настоящее время хранятся в кэше, так что, если любая из этих записей соответствует запрашиваемому объекту, сервер может использовать заголовок ETag в своем отклике 304 (Not Modified), чтобы сообщить кэшу, какой объект подходит. Если метка объекта нового отклика соответствует существующей записи, новый отклик должен быть использован для актуализации полей заголовка существующей записи, а результат должен быть прислан клиенту.
Поле заголовка Vary может также информировать кэш, что представление было выбрано с использованием критериев помимо взятых из заголовков запросов. В этом случае, кэш не должен использовать отклик в ответ на последующий запрос, если только кэш не передает исходному серверу условный запрос.
Сервер при этом возвращает отклик 304 (Not Modified), включая метку объекта или поле Content-Location, которые указывают, какой объект должен быть использован.
Если какая-то запись кэша содержит только часть информации для соответствующего объекта, его метка не должна содержаться в заголовке If-None-Match, если только запрос не лежит в диапазоне, который полностью покрывается этим объектом.
Если кэш получает позитивный отклик с полем Content-Location, соответствующим записи в кэше для того же Request-URI, с меткой объекта, отличающейся от метки существующего объекта, и датой современнее даты существующего объекта, данная запись не должна использоваться в качестве отклика для будущих запросов и должна быть удалена из кэша.
12.12. Кэши коллективного и индивидуального использования
По причинам безопасности и конфиденциальности необходимо делать различие между кэшами совместного и индивидуального использования. Индивидуальные кэши доступны только для одного пользователя. Доступность в этом случае должна определяться соответствующим механизмом, обеспечивающим безопасность. Все другие кэши рассматриваются как коллективные. Другие разделы этой спецификации накладывают определенные ограничения на работу совместно используемых кэшей, для того, чтобы предотвратить потерю конфиденциальности или управления доступом.
12.13. Ошибки и поведение кэша при неполном отклике
Кэш, который получает неполный отклик (например, с меньшим числом байтов, чем специфицировано в заголовке Content-Length) может его запомнить. Однако, кэш должен воспринимать эти данные как частичный отклик. Частичные отклики могут компоноваться, как это описано в разделе 12.5.4. Результатом может быть полный или частичный отклик. Кэш не должен возвращать частичный отклик клиенту без явного указания на то, что он частичный, используя статусный код 206 (Partial Content). Кэш не должен возвращать частичный отклик, используя статусный код 200 (OK).
Если кэш получает отклик 5xx при попытке перепроверить запись, он может переадресовать этот отклик запрашивающему клиенту или действовать так, как если бы сервер не смог ответить на запрос.
В последнем случае он может вернуть отклик, полученный ранее, если только запись в кэше не содержит директиву Cache-Control "must-revalidate" (см. раздел 13.9).
12.14. Побочные эффекты методов GET и HEAD
Если исходный сервер напрямую не запрещает кэширование своих откликов, методы приложения GET и HEAD не должны давать каких-либо побочных эффектов, которые вызывали бы некорректное поведение, если эти отклики берутся из кэша. Они все же могут давать побочные эффекты, но кэш не обязан рассматривать такие побочные эффекты, принимая решение о кэшировании. Кэши контролируют лишь прямые указания исходного сервера о запрете кэширования.
Обратим внимание только на одно исключение из этого правила: некоторые приложения имеют традиционно используемые GET и HEAD с запросами URL (содержащими "?" в части rel_path) для выполнения операций с ощутимыми побочными эффектами. Кэши не должны обрабатывать отклики от таких URL, как свежие, если только сервер не присылает непосредственно значение времени жизни. Это в частности означает, что отклики от серверов HTTP/1.0 для этих URI не следует брать из кэша. Дополнительную информацию по смежным темам можно найти в разделе 8.1.1.
12.15 Несоответствие после актуализации или стирания
Воздействие определенных методов на исходный сервер может вызвать то, что одна или более записей, имеющихся в кэше, становятся неявно непригодными. То есть, хотя они могут оставаться "свежими", они не вполне точно отражают то, что исходный сервер пришлет в ответ на новый запрос.
В протоколе HTTP не существует способа гарантировать, что все такие записи в кэше будут помечены как непригодные. Например, запрос, который вызывает изменение в исходном сервере не обязательно проходит через прокси, где в кэше хранится такая запись. Однако несколько правил помогает уменьшить вероятность некорректного поведения системы.
В этом разделе, выражение "пометить объект как непригодный" означает, что кэш должен либо удалить все записи, относящиеся к этому объекту из памяти или должен пометить их, как непригодные ("invalid"), что будет вызывать обязательную перепроверку пригодности перед отправкой в виде отклика на последующий запрос.
Некоторые методы HTTP могут сделать объект непригодным. Это либо объекты, на которые осуществляется ссылка через Request-URI, или через заголовки отклика Location или Content-Location (если они имеются). Это методы:
PUT
DELETE
POST
12.16. Обязательная пропись (Write-Through Mandatory)
Все методы, которые предположительно могут вызвать модификацию ресурсов исходного сервера должны быть прописаны в исходный сервер. В настоящее время сюда входят все методы кроме GET и HEAD. Кэш не должен отвечать на такой запрос от клиента, прежде чем передаст запрос встроенному (inbound) серверу, и получит соответствующего отклик от него. Это не препятствует кэшу послать отклик 100 (Continue), прежде чем встроенный сервер ответит.
Альтернатива, известная как "write-back" или "copy-back" кэширование, в HTTP/1.1 не допускается, из-за трудности обеспечения согласованных актуализаций и проблем, связанных с отказами сервера, кэша или сети до осуществления обратной записи (write-back).
12.17. Замещения в кэше
Если от ресурса получен новый кэшируемый отклик (см. разделы 13.9.2, 12.5, 12.6 и 12.8), в то время как какой-либо отклик для того же ресурса уже записан в кэш, кэшу следует использовать новый отклик для ответа на текущий запрос. Он может ввести его в память кэша и может, если он отвечает всем требованиям, использовать в качестве отклика для будущих запросов. Если он вводит новый отклик в память кэша, он должен следовать правилам из раздела 12.5.3.
Замечание. Новый отклик, который имеет значение заголовка Date старше, чем кэшированные уже отклики, не должен заноситься в кэш.
12.18. Списки предыстории
Агенты пользователя часто имеют механизмы "исторического" управления, такие как кнопки "Back" и списки предыстории, которые могут использоваться для повторного отображения объекта, извлеченного ранее в процессе сессии. Механизмы предыстории и кэширования различны. В частности механизмы предыстории не должны пытаться показать семантически прозрачный вид текущего состояния ресурса.Скорее, механизм предыстории предназначен для того, чтобы в точности показать, что видел пользователь, когда ресурс был извлечен. По умолчанию время годности не приложимо к механизмам предыстории. Если объект все еще в памяти, механизм предыстории должен его отобразить, даже если время жизни объекта истекло и он объявлен непригодным, если только пользователь не сконфигурировал агента так, чтобы обновлять объекты, срок годности которых истек. Это не запрещает механизму предыстории сообщать пользователю, что рассматриваемый им объект устарел.
Замечание. Если механизмы предыстории излишне мешают пользователю просматривать устаревшие ресурсы, то это заставит разработчиков избегать пользоваться контролем времени жизни объектов. Разработчикам следует считать важным, чтобы пользователи не получали сообщений об ошибке или предупреждения, когда они пользуются навигационным управлением (например, таким как клавиша BACK).
Опционные метки групп рядов
Когда таблица содержит только одно тело и не имеет заголовка и нижней подписи, начальная и конечная метки tbody могут быть опущены. Когда блок таблицы содержит заголовок, начальная и конечная метки элемента thead являются необходимыми. Конечная метка может быть опущена, когда далее следует стартовая метка tfoot или tbody. когда блок таблицы содержит нижняя подпись, необходима начальная метка элемента tfoot. Конечная метка может быть опущена, когда далее следуют начальная метка thead или tbody.
Опорный уровень в сетях с коммутацией каналов
На сегодняшний день крупнейшие телекоммуникационные сети являются сетями с коммутацией каналов, которые образуют всемирные телефонные сети общего назначения. В таких сетях пара пользователей занимает канал на время разговора. Отказ в работе некоторых сетевых компонентов снижает полную пропускную способность сети, и сокращается максимально возможное количество соединений. Это неблагоприятно сказывается на пользователях, возрастает вероятность того, что, когда человек захочет позвонить, линия будет занята. Это явление называется - «блокировкой вызова». В случае повреждения узлов в сети с коммутацией пакетов может увеличиться задержка передачи данных, но блокировки вызова не произойдет. Конечно для обоих типов сетей, если отсутствует связанность сети между двумя пользователями, они не смогут друг с другом общаться. В ранних работах по сетевой надежности предлагались модели сети с коммутацией каналов, где сетевые каналы считались неисправными, если они оказались блокированными.
Рис. 1. Arpanet 1979 год
Определение типа документа DTD (Document Type Definition)
<!-- Это строгие DTD HTML 4.0, которые исключают новейшие презентационные атрибуты и элементы. Разработчикам следует пользоваться строгими требованиями DTD всюду, где возможно, но могут быть применены и переходные DTD там, где это требуется для презентационных атрибутов и элементов. HTML 4.0 включает в себя механизм стилевых листов, скриптов, встроенных объектов, улучшенную поддержку размещения текста слева на право и наоборот, усовершенствования в работе с формами, обеспечение доступа для людей с ограниченными возможностями.
Проект: $date: 1998/04/02 00:17:00 $
Авторы:
dave raggett <dsr@w3.org>
arnaud le hors <lehors@w3.org>
ian jacobs <ij@w3.org>
Дальнейшая информация об HTML 4.0 доступна по адресу:
-->
<!-- Типовое применение:
|
<!doctype html public "-//w3c//dtd html 4.0//en" |
| "http://www.w3.org/tr/rec-html40/strict.dtd"> |
| <html> |
| <head> |
| ... |
| </head> |
| <body> |
| ... |
| </body> |
| </html> |
FPI для переходного HTML 4.0 dtd соответствует:
"-//w3c//DTD HTML 4.0 transitional//en"
а его uri:
http://www.w3.org/tr/rec-html40/loose.dtd
Если вы пишете документ, который включает в себя рамки, используйте fpi:
"-//w3c//dtd html 4.0 frameset//en"
с uri:
http://www.w3.org/tr/rec-html40/frameset.dtd
Следующие uri поддерживаются в рамках html 4.0
"http://www.w3.org/tr/rec-html40/strict.dtd" (strict dtd)
"http://www.w3.org/tr/rec-html40/loose.dtd" (loose dtd)
"http://www.w3.org/tr/rec-html40/frameset.dtd" (frameset dtd)
"http://www.w3.org/tr/rec-html40/htmllat1.ent" (latin-1 entities)
"http://www.w3.org/tr/rec-html40/htmlsymbol.ent" (symbol entities)
"http://www.w3.org/tr/rec-html40/htmlspecial.ent" (special entities)
Эти uri указывают на последние версии каждого из файлов. Для ссылок используйте URI:
"http://www.w3.org/tr/1998/rec-html40-19980424/strict.dtd"
"http://www.w3.org/tr/1998/rec-html40-19980424/loose.dtd"
"http://www.w3.org/tr/1998/rec-html40-19980424/frameset.dtd"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmllat1.ent"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmlsymbol.ent"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmlspecial.ent"
-->
<!--================== Импортированные имена ===================== -- >
<!entity % contenttype "cdata" |
-- тип среды, как в rfc2045 --> |
<!entity % contenttypes "cdata"
-- список кодов типов среды, разделенных запятыми, в соответствие с [rfc-2045] -->
<!entity % charset "cdata" |
-- символьное кодирования как в [rfc-2045] --> |
<!entity % charsets "cdata" | -- список символьных кодов, разделенных пробелами, как в rfc-2045 --> |
<!entity % languagecode "name" | -- код языка, как в [RFC-1766] --> |
<!entity % character "cdata" | -- одиночный символ из [ISO10646] --> |
<!entity % linktypes "cdata" | -- список типов связей (через пробел) --> |
<!entity % mediadesc "cdata" | -- список дескрипторов среды (через запятую)--> |
<!entity % uri "cdata" | -- uri --> |
<!entity % datetime "cdata" | -- информация о дате и времени. Формат ISO --> |
<!entity % script "cdata" | -- скрипты --> |
<!entity % stylesheet "cdata" | -- информация стилевого листа --> |
<!entity % text "cdata"> | |
<!-- parameter entities -->
<!entity % head.misc "script|style|meta|link|object" -- повторяющиеся элементы заголовков -->
<!entity % heading "h1|h2|h3|h4|h5|h6">
<!entity % list "ul | ol">
<!entity % preformatted "pre">
<!entity % color "cdata" -- цвет в представлении rgb: #rrggbb (hex формат) -->
<! -- Здесь представлены имена 16 широко известных цветов с их rgb значениями:
black = | #000000 | green = | #008000 |
silver = | #C0C0C0 | lime = | #00FF00 |
gray = | #808080 | olive = | #808000 |
white = | #FFFFFF | yellow = | #FFFF00 |
maroon = | #800000 | navy = | #000080 |
red = | #FF0000 | blue = | #0000FF |
purple = | #800080 | teal = | #008080 |
fuchsia = | #FF00FF | aqua = | #00FFFF |
--> <!entity % bodycolors "
bgcolor %color; #implied | -- фоновый цвет документа -- |
text %color; #implied | -- цвет текста документа -- |
link %color; #implied | -- цвета связей -- |
vlink %color; #implied | -- цвета посещенных URL -- |
alink %color; #implied | -- цвет выбранного URL -- "> |
<!--============== Символьные мнемонические объекты ==============-->
<!entity % htmllat1 public
"-//w3c//entities latin1//en//html"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmllat1.ent">
%htmllat1;
<!entity % htmlsymbol public
"-//w3c//entities symbols//en//html"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmlsymbol.ent">
%htmlsymbol;
<!entity % htmlspecial public
"-//w3c//entities special//en//html"
"http://www.w3.org/tr/1998/rec-html40-19980424/htmlspecial.ent">
%htmlspecial;
<!--===================== Общие атрибуты =======================-->
<!entity % coreattrs
"id id #implied
-- уникальный идентификатор, действительный для всего документа --
| class cdata #implied | -- список классов, разделенных пробелами -- |
| style %stylesheet; #implied | -- ассоциированная стилевая информация -- |
| title %text; #implied | -- рекомендуемые заголовки /приложения --" > |
<!entity % i18n
| "lang %languagecode; #implied | -- код языка -- |
| dir (ltr|rtl) #implied |
-- направление для слабого/нейтрального текста --" > |
<!entity % events | |
| "onclick %script; #implied | -- клавиша мышки была нажата -- |
| ondblclick %script; #implied | -- клавиша мышки была нажата дважды -- |
| onmousedown %script; #implied | -- клавиша мышки была нажата и удержана -- |
| onmouseup %script; #implied | -- клавиша мышки была отпущена -- |
| onmouseover %script; #implied | -- маркер был помещен на объект -- |
| onmousemove %script; #implied | -- маркер перемещался в пределах объекта -- |
| onmouseout %script; #implied | -- маркер удален с объекта -- |
| onkeypress %script; #implied | -- клавиша была нажата и отпущена -- |
| onkeydown %script; #implied | -- клавиша была зажата -- |
| onkeyup %script; #implied | -- клавиша была отпущена --" > |
<!-- Зарезервированный переключатель функций -->
<!entity % html.reserved "ignore">
<!-- Следующие атрибуты зарезервированы для будущего использования -->
<![ %html.reserved; [
<!entity % reserved
| "datasrc %uri; #implied | -- a single or tabular data source -- |
| datafld cdata #implied | -- свойство или имя колонки -- |
| dataformatas (plaintext|html) plaintext | -- текст или html --" > |
]]>
<!entity % reserved "">
<!entity % attrs "%coreattrs; %i18n; %events;">
<!--================== Разметка текста (markup) ===================-->
<!entity % fontstyle "tt | i | b | big | small">
<!entity % phrase "em | strong | dfn | code |
samp | kbd | var | cite | abbr | acronym" >
<!entity % special
"a | img | object | br | script | map | q | sub | sup | span | bdo">
<!entity % formctrl "input | select | textarea | label | button">
<!-- %inline; охватывает строчные и "text-level" элементы -->
<!entity % inline "#pcdata | %fontstyle; | %phrase; | %special; | %formctrl;">
<!element (%fontstyle;|%phrase;) - - (%inline;)*>
<!attlist (%fontstyle;|%phrase;)
| %attrs; | -- %coreattrs, %i18n, %events -- > |
<!element (sub|sup) - - (%inline;)* | -- нижний или верхний индексы --> |
<!attlist (sub|sup) %attrs; | -- %coreattrs, %i18n, %events --> |
<!element span - - (%inline;)* | -- общий языковый/стилевой контейнер --> |
<!attlist span %attrs | -- %coreattrs, %i18n, %events -- |
| %reserved | -- зарезервировано на будущее --> |
<!element bdo - - (%inline;)* | -- i18n bidi over-ride --> |
<!attlist bdo %coreattrs; | -- id, class, style, title -- |
| lang %languagecode; #implied | -- код языка -- |
| dir (ltr|rtl) #required | -- направление --> |
<!element br - o empty | -- принудительный разрыв строки --> |
<!attlist br %coreattrs; | -- id, class, style, title -- > |
<!element basefont - o empty | -- базовый размер шрифта --> |
<!attlist basefont | |
ID id #implied | -- идентификатор документа -- |
size cdata #required | -- базовый размер шрифта для элементов font -- |
color %color; #implied | -- цвет текста -- |
face cdata #implied | -- список имен шрифтов, разделенных запятыми -- > |
<!element font - - (%inline;)* | -- локальная смена шрифта --> |
<!attlist font %coreattrs; | -- id, class, style, title -- |
| %i18n; | -- lang, dir -- |
| size cdata #implied |
-- [+|-]nn e.g. size="+1", size="4" -- |
| color %color; #implied | -- цвет текста -- |
| face cdata #implied | -- список имен шрифтов, разделенных запятыми -- > |
<
/p>
<!--================ Модели содержимого html ==================-->
<!-- HTML имеет две базовые модели содержимого:
%inline; элементы символьного уровня и текстовые строки
%block; блочные элементы, напр., параграфы и списки -->
<!entity % block
"p | %heading; | %list; | %preformatted; | dl | div | noscript |
blockquote | form | hr | table | fieldset | address">
<!entity % flow "%block; | %inline;">
<!--=================== Тело документа ========================-->
<!element body o o (%block;|script)+ +(ins|del) -- тело документа -->
<!attlist body %attrs; | -- %coreattrs, %i18n, %events -- |
| onload %script; #implied | -- документ был загружен -- |
| onunload %script; #implied | -- документ был удален --> |
<!element address - - (%inline;)* | -- информация об авторе --> |
<!attlist address %attrs; | -- %coreattrs, %i18n, %events -- > |
<!element div - - (%flow;)* | -- общий языковый/стилевой контейнер --> |
<!attlist div %attrs; | -- %coreattrs, %i18n, %events -- |
| %reserved; | -- зарезервировано на будущее --> |
<!--================== Элемент anchor ========================-->
<!entity % shape "(rect|circle|poly|default)">
<!entity % coords "cdata" | -- список длин с запятыми между элементами --> |
<!element a - - (%inline;)* -(a) | -- якорь --> |
<!attlist a %attrs; | -- %coreattrs, %i18n, %events -- |
| charset %charset; #implied | -- кодировка подключенного ресурса -- |
| type %contenttype; #implied | -- рекомендуемый тип содержимого -- |
| name cdata #implied | -- именованный конец связи -- |
| href %uri; #implied | -- uri для связанного ресурса -- |
| hreflang %languagecode; #implied | -- код языка -- |
| rel %linktypes; #implied | -- прямые типы связи -- |
| rev %linktypes; #implied | -- обратные типы связи -- |
| target %frametarget; #implied | -- отображать в этой рамке -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| shape %shape; rect | -- для использования с картой изображения клиента -- |
| coords %coords; #implied | -- для использования с картой изображения клиента -- |
| tabindex number #implied | -- индекс позиции в меню -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- > |
<!--================ Карты изображения стороны клиента ==============-->
<!-- Они могут помещаться в один и тот же документ или группироваться в отдельном документе, хотя это и не поддерживается широко -->
<!element map - - ((%block;)+ | area+) | -- карта изображения со стороны клиента --> |
<!attlist map
| %attrs; | -- %coreattrs, %i18n, %events -- |
| name cdata #required | -- для ссылок через карту использования -- > |
<!element area - o empty | -- карта изображения стороны клиента --> |
<!attlist area | |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| shape %shape; rect | -- управление интерпретацией координат -- |
| coords %coords; #implied | -- список длин, разделенных запятыми -- |
| href %uri; #implied | -- uri для подключенного ресурса -- |
| target %frametarget; #implied | -- отображать в этой рамке -- |
| nohref (nohref) #implied | -- эта область не производит действия -- |
| alt %text; #required | -- краткое описание -- |
| tabindex number #implied | -- положение при обходе меню -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- > |
<!--===================== Элемент link ======================-->
<!-- Значения отношений могут использоваться:
для специальных меню (toolbars), когда значения отношений используются с элементом link в заголовке документа, напр., start, contents, previous, next, index, end, help
для связи с отдельным стилевым листом (rel=stylesheet)
для организации связи со скриптом (rel=script)
с стилевыми листами для управления процессом представления документов из нескольких узлов при их печати
для создания связи с печатаемой версией документа, напр., postscript или pdf (rel=alternate media=print) -->
<!element link - o empty | -- связь, независящая от среды--> |
<!attlist link | |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| charset %charset; #implied |
-- кодировка символов подключенного ресурса -- |
| href %uri; #implied | -- uri для подключенного ресурса -- |
|
hreflang %languagecode; #implied | -- код языка -- |
| type %contenttype; #implied | -- рекомендуемый тип содержимого -- |
| rel %linktypes; #implied | -- прямые типы связей -- |
| rev %linktypes; #implied | -- обратные типы связей -- |
| media %mediadesc; #implied | -- для отображения в этих средах -- > |
| target %frametarget; #implied | -- отображать в этой рамке -- > |
<
/p>
<!--===================== Изображения =====================-->
<!-- Длина, определенная в DTD, для cellpadding/cellspacing -->
<!entity % length "cdata" | -- nn для пикселей или nn% для %-длины --> |
<!entity % multilength "cdata" | -- пиксель, процент или относительно --> |
<!entity % multilengths "cdata" | -- список multilength, разделенных запятыми --> |
<!entity % pixels "cdata" | -- целочисленная длина в пикселях --> |
<!entity % ialign "(top|middle|bottom|left|right)" | -- центрировать? --> |
<!-- Чтобы избежать проблем с агентами пользователя, ориентированными исключительно на работу с текстом, сделать изображение понятным и удобным для сетевого поиска для неграфических агентов пользователя, следует предусмотреть альтернативу описания с помощью alt, и избежать применения карт изображения на стороне сервера -->
<!element img - o empty | -- Встроенное изображение --> |
<!attlist img
| %attrs; | -- %coreattrs, %i18n, %events -- |
| src %uri; #required | -- uri встроенного изображения -- |
| alt %text; #required | -- краткое описание -- |
| longdesc %uri; #implied | -- связь с длинным описанием (complements alt) -- |
| height %length; #implied | -- присвоение нового значения высоты -- |
| width %length; #implied | -- присвоение нового значения ширины-- |
| usemap %uri; #implied | -- для использования с картой изображения клиента -- |
| ismap (ismap) #implied | -- для использования с картой изображения сервера --> |
| align %ialign; #implied | -- вертикальное или горизонтальное выравнивание-- |
| border %length; #implied | -- ширина границы для связи -- |
| hspace %pixels; #implied | -- горизонтальный пробельный массив-- |
| vspace %pixels; #implied | -- вертикальный пробельный массив-- > |
<!-- usemap указывает на элемент map, который может быть в этом документе или во внешнем документе, хотя последнее и не поддерживается широко -->
<!--==================== object ===================-->
<!-- object используется для вставления объектов в качестве части html страниц.
Элементы param должны предшествовать остальному содержимому. -->
<!element object - - (param | %flow;)* | -- общий встроенный объект --> |
<!attlist object
| %attrs | -- %coreattrs, %i18n, %events -- |
| declare (declare) #implied | -- декларирует, но не инициирует флаг -- |
| classid %uri; #implied | -- идентифицирует реализацию -- |
| codebase %uri; #implied | -- базовый uri для classid, data, archive -- |
| data %uri; #implied | -- ссылка на данные объекта -- |
| type %contenttype; #implied | -- тип содержимого для данных -- |
| codetype %contenttype; #implied | -- тип содержимого для кода -- |
| archive %uri; #implied | -- архивный список с sp в качестве разделителей -- |
| standby %text; #implied | -- сообщение, отображаемое при загрузке -- |
| height %length; #implied | -- присваивает новое значение высоты -- |
| width %length; #implied | -- присваивает новое значение ширины -- |
| usemap %uri; #implied | -- для использования с картой изображения клиента -- |
| name cdata #implied | -- представляет как часть формы -- |
| tabindex number #implied | -- положение при обходе меню -- |
| align %ialign; #implied | -- вертикальное или горизонтальное выравнивание-- |
| border %length; #implied | -- ширина границы связи -- |
| hspace %pixels; #implied | -- горизонтальный пробельный массив-- |
| vspace %pixels; #implied | -- вертикальный пробельный массив-- |
| %reserved; | -- зарезервировано на будущее --> |
<!element param - o empty | -- именованное значение свойства --> |
<!attlist param
| id id #implied | -- идентификатор документа -- |
| name cdata #required | -- имя свойства -- |
| value cdata #implied | -- значение свойства -- |
| valuetype (data|ref|object) data | -- Как интерпретировать значение -- |
| type %contenttype; #implied | -- тип содержимого для значения, когда valuetype=ref --> |
<!--======================= java applet ========================-->
<!-- Один из кодов или атрибутов объекта должен присутствовать. Помещайте элементы param до остального содержимого. -->
<!element applet - - (param | %flow;)* -- аплет java -->
<!attlist applet %coreattrs; | -- id, class, style, title -- |
codebase %uri; #implied | -- опционный базовый uri для аплета -- |
archive cdata #implied | -- список архива с запятой в качестве разделителя-- |
code cdata #implied | -- файл класса аплета -- |
object cdata #implied | -- файл специального аплета -- |
alt %text; #implied | -- краткое описание-- |
name cdata #implied | -- позволяет аплетам найти друг друга -- |
width %length; #required | -- начальная ширина -- |
height %length; #required | -- начальная высота -- |
align %ialign; #implied | -- вертикальное или горизонтальное выравнивание -- |
hspace %pixels; #implied | -- горизонтальный пробельный массив-- |
vspace %pixels; #implied | -- вертикальный пробельный массив-- > |
<!--================ Горизонтальная линейка ==================-->
<!element hr - o empty | -- горизонтальная линейка --> |
<!attlist hr %coreattrs; | -- id, class, style, title -- |
| %events; > | |
<!--====================== Параграфы =======================-->
<!element p - o (%inline;)* | -- параграф --> |
<!attlist p %attrs; | -- %coreattrs, %i18n, %events -- > |
%align; | -- выравнивание текста -- > |
<!--======================= Заголовки =======================-->
<!--Существует 6 уровней заголовков от H1 (наиболее важный) до H6 (наименее важный). -->
<!element (%heading;) - - (%inline;)* | -- Заголовок --> |
<!attlist (%heading;) %attrs; | -- %coreattrs, %i18n, %events -- > |
%align; | -- выравнивание текста -- > |
<!--================ Преформатированный текст ================-->
<!-- не включает разметку для изображений и изменений в размере шрифтов -->
<!entity % pre.exclusion "img|object|big|small|sub|sup">
<!element pre - - (%inline;)* -(%pre.exclusion;) -- преформатированный текст -->
<!attlist pre %attrs; -- %coreattrs, %i18n, %events -- >
<!--===================== inline quotes ====================-->
<!element q - - (%inline;)* | -- Кавычки для текста в пределах строки --> |
<!attlist q %attrs; | -- %coreattrs, %i18n, %events -- |
| cite %uri; #implied | -- uri для исходного документа или сообщения -- > |
<!--===================== block-like quotes ====================-->
<!element blockquote - - (%block;|script)+ -- Кавычки для многострочных блоков текста -->
<!attlist blockquote
| %attrs; | -- %coreattrs, %i18n, %events -- |
| cite %uri; #implied | -- uri для исходного документа или сообщения --> |
<!--================== Введенный/Стертый текст ====================-->
<!-- ins/del are handled by inclusion on body -->
<!element (ins|del) - - (%flow;)* | -- введенный текст, стертый текст --> |
<!attlist (ins|del) %attrs; | -- %coreattrs, %i18n, %events -- |
| cite %uri; #implied | -- инфо о причине изменения -- |
| datetime %DAtetime; #implied | -- дата и время изменения -- > |
<!--====================== Списки ========================-->
<!-- список определений - dt - для термов, dd - для их определений -->
<!element dl - - (dt|dd)+ | -- список определений --> |
<!attlist dl %attrs; | -- %coreattrs, %i18n, %events --> |
<!element dt - o (%inline;)* | -- term определения --> |
<!element dd - o (%flow;)* | -- описание определения --> |
<!attlist (dt|dd) %attrs; | -- %coreattrs, %i18n, %events --> |
<!element ol - - (li)+ | -- упорядоченный список --> |
<!attlist ol %attrs; | -- %coreattrs, %i18n, %events --> |
<!-- Стиль нумерации упорядоченных списков (ol)
1 арабские числа 1, 2, 3, ...
a строчные буквы a, b, c, ...
a прописные буквы a, b, c, ...
i строчные римские i, ii, iii, ...
i прописные римские i, ii, iii, ...
Стиль применяется к номеру по порядку, который по умолчанию равен 1 для первого элемента упорядоченного списка. -->
<!entity % olstyle "cdata" -- ограничено перечнем: "(1|a|a|i|i)" -->
<!element ol - - (li)+ -- упорядоченный список -->
<!attlist ol
| %attrs; | -- %coreattrs, %i18n, %events -- |
| type %olstyle; #implied | -- стиль нумерации -- |
| compact (compact) #implied | -- уменьшенный зазор между позициями-- |
| start number #implied | -- начальный номер последовательности -- > |
<!-- Неупорядоченные списки (ul) bullet styles -->
<!element ul - - (li)+ | -- неупорядоченный список --> |
<!attlist ul %attrs; | -- %coreattrs, %i18n, %events -- > |
<!element li - o (%flow;)* | -- элемент списка --> |
<!attlist li %attrs; | -- %coreattrs, %i18n, %events -- > |
| type %ulstyle; #implied | -- стиль bullet -- |
| compact (compact) #implied | -- уменьшенный зазор между позициями-- > |
<!--==================== Формы =======================-->
<!element form - - (%block;|script)+ -(form) | -- интерактивная форма --> |
<!attlist form %attrs; | -- %coreattrs, %i18n, %events -- |
| action %uri; #required | -- хандлер форм для стороны сервера -- |
| method (get|post) get | -- http метод для представления форм -- |
enctype %contenttype; "application/x-www-form-urlencoded" |
| onsubmit %script; #implied | -- форма была представлена -- |
| onreset %script; #implied | -- форма возвращена в исходное состояние -- |
| target %frametarget; #implied | -- отображать в этой рамке -- |
| accept-charset %charsets; #implied | -- список поддерживаемых символьных наборов -- > |
<
/p>
<!-- Каждая метка не должна содержать более одного поля -->
<!element label - - (%inline;)* -(label) -- текст метки поля формы -->
<!attlist label %attrs; | -- %coreattrs, %i18n, %events -- |
| or idref #implied | -- проверяет корректность значения поля -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- > |
<!entity % inputtype
"(text | password | checkbox | radio | submit | reset | file | hidden | image | button)" >
<!-- имя атрибута необходимо всем кроме submit & reset -->
<!element input - o empty | -- Управление формой --> |
<!attlist input %attrs; | -- %coreattrs, %i18n, %events -- |
| type %inputtype; text | -- what kind of widget is needed -- |
| name cdata #implied | -- представить в качестве части формы -- |
| value cdata #implied | -- необходимо для радио кнопок и переключателей -- |
| checked (checked) #implied | -- для радио кнопок и переключателей -- |
| disabled (disabled) #implied | -- недоступно в данном контексте -- |
| readonly (readonly) #implied | -- для текста и пароля -- |
| size cdata #implied | -- разный для каждого из полей -- |
| maxlength number #implied |
-- максимальное число символов для текстовых полей -- |
| src %uri; #implied | -- для полей с изображением -- |
| alt cdata #implied | -- краткое описание -- |
| usemap %uri; #implied | -- использует карту изображения клиента -- |
| tabindex number #implied | -- номер позиции в меню -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- |
| onselect %script; #implied | -- некоторая часть текста выделена -- |
| onchange %script; #implied | -- значение элемента изменилось -- |
| accept %contenttypes; #implied | -- список типов mime для файловой загрузки -- |
| align %ialign; #implied | -- вертикальное или горизонтальное выравнивание-- |
| %reserved; | -- зарезервировано на будущее -- > |
<!element select - - (optgroup|option)+ | -- селектор опций --> |
<!attlist select %attrs; | -- %coreattrs, %i18n, %events -- |
| name cdata #implied | -- имя поля -- |
| size number #implied | -- видимые строки -- |
| multiple (multiple) #implied | -- по умолчанию один выбор -- |
| disabled (disabled) #implied | -- недоступно в данном контексте -- |
| tabindex number #implied | -- номер позиции в меню -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- |
| onchange %script; #implied | -- значение элемента изменилось -- |
| %reserved; | -- зарезервировано на будущее -- > |
<!element optgroup - - (option)+ | -- группа опций --> |
<!attlist optgroup %attrs; | -- %coreattrs, %i18n, %events -- |
| disabled (disabled) #implied | -- недоступно в данном контексте -- |
| label %text; #required | -- для использования в иерархических меню --> |
<!element option - o (#pcdata) | -- селективный выбор --> |
<!attlist option %attrs; | -- %coreattrs, %i18n, %events -- |
| selected (selected) #implied | |
| disabled (disabled) #implied | -- недоступно в данном контексте -- |
| label %text; #implied | -- для использования в иерархических меню -- |
| value cdata #implied | -- значения по умолчанию содержимого элемента --> |
<!element textarea - - (#pcdata) | -- многострочное текстовое поле --> |
<!attlist textarea %attrs; | -- %coreattrs, %i18n, %events -- |
| name cdata #implied | |
| rows number #required | |
| cols number #required | |
| disabled (disabled) #implied | -- недоступно в данном контексте -- |
| readonly (readonly) #implied | |
| tabindex number #implied | -- номер позиции в меню -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- |
| onselect %script; #implied | -- некоторая часть текста выделена -- |
| onchange %script; #implied | -- значение элемента изменилось -- |
| %reserved; | -- зарезервировано на будущее --> |
<!-- #pcdata служит для решения проблем смешанного содержимого, в спецификации допустим только пробел! -->
<!element fieldset - - (#pcdata,legend,(%flow;)*) | -- группа управлений формой --> |
<!attlist fieldset %attrs; | -- %coreattrs, %i18n, %events -- > |
<!element legend - - (%inline;)* | -- легенда поля --> |
<!entity % lalign "(top|bottom|left|right)"> | -- выравнивание --> |
<!attlist legend %attrs; | -- %coreattrs, %i18n, %events -- |
| accesskey %character; #implied | -- клавиша доступа -- > |
<!element button - - (%flow;)* -(a|%formctrl;|form|fieldset)
-- кнопка нажатия -->
<!attlist button %attrs; | -- %coreattrs, %i18n, %events -- |
| name cdata #implied | |
| value cdata #implied | -- посылается серверу при представлении -- |
| type (button|submit|reset) submit | -- для использования в качестве кнопки в форме -- |
| disabled (disabled) #implied | -- не доступно в данном контексте -- |
| tabindex number #implied | -- номер позиции в меню -- |
| accesskey %character; #implied | -- клавиша доступа -- |
| onfocus %script; #implied | -- элемент выделен -- |
| onblur %script; #implied | -- элемент не выделен -- |
| %reserved; | -- зарезервировано на будущее -- > |
<!--===================== Таблицы ======================-->
<!-- Стандарт таблиц ietf HTML, см. [rfc-1942] -->
<!-- Атрибут border устанавливает толщину рамки вокруг таблицы. Единицы измерения по умолчанию пиксели. Атрибут frame специфицирует то, какую часть рамки вокруг таблицы следует отображать. Значение "border" включено для обеспечения обратной совместимости с <table border>, который выдает frame=border и border=implied. Для <table border=1> вы получите border=1 и frame=implied. В этом случае, представляется разумным считать, что frame=border для обратной совместимости с уже существующими броузерами. -->
<!entity % tframe "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
<!-- Атрибут rules определяет, какие линии должны быть проведены между ячейками:
Если rules отсутствуют, то предполагается:
"none", если border отсутствует или =0, в противном случае "all" -->
<!entity % trules "(none | groups | rows | cols | all)">
<!-- горизонтальное размещение таблицы в документе -->
<!entity % talign "(left|center|right)">
<!-- Атрибуты горизонтального выравнивания для содержимого ячеек -->
<!entity % cellhalign "align (left|center|right|justify|char) #implied
| char %character; #implied | -- символ выравнивания, напр. символ=':' -- |
| charoff %length; #implied | -- смещение символа выравнивания --" > |
<!-- атрибуты вертикального выравнивания для содержимого -->
<!entity % cellvalign "valign (top|middle|bottom|baseline) #implied" >
<!element table - -
(caption?, (col*|colgroup*), thead?, tfoot?, tbody+)>
<!element caption - - (%inline;)* | -- Название таблицы --> |
<!element thead - o (tr)+ | -- Заголовок таблицы --> |
<!element tfoot - o (tr)+ | -- Подпись под таблицей --> |
<!element tbody o o (tr)+ | -- Тело таблицы --> |
<!element colgroup - o (col)* | -- Группа колонок таблицы --> |
<!element col - o empty | -- Колонка таблицы --> |
<!element tr - o (th|td)+ | -- Строка таблицы --> |
<!element (th|td) - o (%flow;)* | -- Заголовок ячейки, данные ячейки таблицы --> |
<!attlist table | -- Элемент таблицы -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| summary %text; #implied | -- цель/структура для речевого вывода -- |
| width %length; #implied | -- ширина таблицы -- |
| border %pixels; #implied | -- управляет шириной рамки вокруг таблицы -- |
| frame %tframe; #implied | -- какую часть таблицы отображать-- |
| rules %trules; #implied | -- линии между строками и колонками -- |
| cellspacing %length; #implied | -- зазор между ячейками -- |
| cellpadding %length; #implied | -- зазор внутри ячеек -- |
| align %talign; #implied | -- положение таблицы по отношению к окну -- |
| bgcolor %color; #implied | -- фоновый цвет ячеек таблицы -- |
| %reserved; | -- зарезервировано на будущее -- |
| datapagesize cdata #implied | -- зарезервировано на будущее -- > |
<!entity % calign "(top|bottom|left|right)">
<!attlist caption %attrs; | -- %coreattrs, %i18n, %events -- > |
<!-- Элемент colgroup группирует набор элементов col. Он позволяет сгруппировать несколько семантически зависимых колонок вместе. -->
<!attlist colgroup %attrs; | -- %coreattrs, %i18n, %events -- |
| span number 1 | -- число колонок в группе по умолчанию -- |
| width %multilength; #implied | -- значение ширины по умолчанию для вложенных col -- |
| %CEllhalign; | -- горизонтальное выравнивание в ячейках -- |
| %CEllvalign; | -- вертикальное выравнивание в ячейках -- > |
<!-- Элементы col определяют свойства выравнивания для ячеек в одной или нескольких колонках.
Атрибут width специфицирует ширину колонок, напр.
width=64 | ширина в пикселях |
width=0.5* | относительная ширина 0.5 |
Атрибут span заставляет атрибуты одного элемента col работать для нескольких колонок. -->
<!attlist col | -- группы колонок и свойства -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| span number 1 | -- атрибуты col воздействуют на n колонок -- |
| width %multilength; #implied | -- спецификация ширины колонки -- |
| %CEllhalign; | -- горизонтальное выравнивание в ячейках -- |
| %CEllvalign; | -- вертикальное выравнивание в ячейках -- > |
<!-- Используйте thead для дублирования заголовков при продолжении таблицы на нескольких страницах, или для статического заголовка для секций tbody со скролированием.
Используйте tfoot для дублирования подписи под таблицей при продолжении таблицы на нескольких страницах, или для статического заголовка для секций tbody со скролированием.
Используйте секции tbody, когда необходимы разделительные линии между группами строк в таблице. -->
<!attlist (thead|tbody|tfoot) | -- секция таблицы -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| %CEllhalign; | -- горизонтальное выравнивание в ячейках-- |
| %CEllvalign; | -- вертикальное выравнивание в ячейках -- > |
<!attlist tr | -- строка таблицы -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| %CEllhalign; | -- горизонтальное выравнивание в ячейках -- |
| %CEllvalign; | -- вертикальное выравнивание в ячейках -- > |
| bgcolor %color; #implied | -- цвет фона для строки -- > |
<!-- scope проще, чем осевые атрибуты для обычных таблиц -->
<!entity % scope "(row|col|rowgroup|colgroup)">
<!-- th для заголовков, td для данных a, но для ячеек используется td -->
<!attlist (th|td) | -- заголовок или данные ячейки -- |
| %attrs; | -- %coreattrs, %i18n, %events -- |
| abbr %text; #implied | -- сокращение для ячейки заголовка -- |
| axis cdata #implied | -- имена групп связанных заголовков -- |
| headers idrefs #implied | -- список id для ячеек заголовка |
| scope %scope; #implied | -- область, перекрываемая ячеками заголовка -- |
| rowspan number 1 | -- число строк в ячейке -- |
| colspan number 1 | -- число колонок в ячейке -- |
| %CEllhalign; | -- горизонтальное выравнивание в ячейках -- |
| %CEllvalign; | -- вертикальное выравнивание в ячейках -- > |
| nowrap (nowrap) #implied | -- подавление разрыва слов -- |
| bgcolor %color; #implied | -- цвет фона ячейки -- |
| width %pixels; #implied | -- ширина ячейки -- |
| height %pixels; #implied | -- высота ячейки -- > |
<!--=================== Рамки документа ====================-->
<!-- Модель содержимого для HTML-документа зависит от того, следует ли за head элемент frameset или body. Широко распространенное отсутствие начальной метки body делает непрактичным определение модели содержимого без использования помеченной секции. -->
<!-- Переключатель функций для набора рамок документов -->
<!entity % html.frameset "ignore">
<![ %html.frameset; [
<!element frameset - - ((frameset|frame)+ & noframes?) - разделение окна -->
<!attlist frameset %coreattrs; | -- id, class, style, title -- |
rows %multilengths; #implied | -- список длин, по умолчанию 100% (1 строка) -- |
cols %multilengths; #implied | -- список длин, по умолчанию 100% (1 колонка) -- |
onload %script; #implied | -- все рамки были загружены -- |
onunload %script; #implied | -- все рамки удалены -- > |
]]>
<![ %html.frameset; [
<!-- резервные имена рамок начинаются с "_" в противном случае с буквы -->
<!element frame - o empty -- субокно -->
<!attlist frame
%coreattrs; | -- id, class, style, title -- |
longdesc %uri; #implied | -- указатель на длинное описание (complements title) -- |
name cdata #implied | -- имя рамки для обращений -- |
src %uri; #implied | -- источник содержимого рамки -- |
frameborder (1|0) 1 | -- запрос границ рамки? -- |
marginwidth %pixels; #implied | -- ширины полей в пикселях -- |
marginheight %pixels; #implied | -- высота поля в пикселях -- |
noresize (noresize) #implied | -- разрешить пользователям изменить размер рамок? -- |
scrolling (yes|no|auto) auto | -- есть или нет полоса прокрутки -- > |
]]>
<!element iframe - - (%flow;)* -- inline subwindow -->
<!attlist iframe %coreattrs; -- id, class, style, title --
longdesc %uri; #implied | -- указатель на длинное описание -- |
name cdata #implied | -- имя рамки для обращений -- |
src %uri; #implied | -- источник содержимого рамки -- |
frameborder (1|0) 1 | -- запрос границ рамки? -- |
marginwidth %pixels; #implied | -- ширины полей в пикселях -- |
marginheight %pixels; #implied | -- высота поля в пикселях -- |
scrolling (yes|no|auto) auto | -- есть или нет полоса прокрутки -- |
align %ialign; #implied | -- вертикальное или горизонтальное выравнивание-- |
height %length; #implied | -- высота рамки -- |
width %length; #implied | -- ширина рамки -- > |
<![ %html.frameset; [
<!entity % noframes.content "(body) -(noframes)">
]]>
<!entity % noframes.content "(%flow;)*">
<!element noframes - - %noframes.content;
< -- контейнер альтернативного сообщения для отображения без поддержки рамок -->
<!attlist noframes %attrs; -- %coreattrs, %i18n, %events -- >
<!--================== Заголовок документа ==================-->
<!-- %head.misc; определены ранее как "script|style|meta|link|object" -->
<!entity % head.content "title & base?">
<!element head o o (%head.content;) +(%head.misc;) -- Заголовок документа -->
<!attlist head %i18n; | lang, dir |
| profile %uri; #implied | -- именованный словарь мета инфо -- > |
<!-- Элемент title не рассматривается как часть текста. Он должен быть отображен, например, как заголовок страницы или окна. У документа должен быть только один заголовок. -->
<!element title - - (#pcdata) -(%head.misc;) -- заголовок документа -->
<!attlist title %i18n>
<!element isindex - o empty -- однострочное сообщение - подсказка -->
<!attlist isindex
%coreattrs; | -- id, class, style, title -- |
%i18n; | -- lang, dir -- |
prompt %text; #implied | -- сообщение-подсказка --> |
<!element base - o empty -- базовый uri документа -->
<!attlist base href %uri; #required -- uri, выполняющий функцию базового идентификатора -- >
target %frametarget; #implied | -- отображать в этой рамке -- > |
<!element meta - o empty | -- общая метаинформация --> |
<!attlist meta %i18n; | -- lang, dir, для использования с содержимым -- |
http-equiv name #implied | -- имя заголовка http отклика -- |
name name #implied | -- имя метаинформации -- |
content cdata #required | -- ассоциированная информация -- |
scheme cdata #implied | -- выбранная форма содержимого -- > |
<!element style - - %stylesheet | -- стилевое инфо --> |
<!attlist style %i18n; | -- lang, dir, для использования в заголовке -- |
| type %contenttype; #required | -- тип содержимого стилевого языка -- |
| media %mediadesc; #implied | -- предназначено для работы с этими средами -- |
| title %text; #implied | -- рекомендуемый title -- > |
<!element script - - %script; -- декларации скрипта -->
<!attlist script charset %charset; #implied -- символьное кодирование подключенного ресурса --
type %contenttype; #required | -- тип содержимого языка скрипта -- |
language cdata #implied | -- предопределенное имя языка скрипта -- |
src %uri; #implied | -- uri внешнего скрипта -- |
defer (defer) #implied | -- ua может отложить исполнение скрипта -- |
event cdata #implied | -- зарезервировано на будущее -- |
for %uri; #implied | -- зарезервировано на будущее -- > |
<!element noscript - - (%block;)+ -- альтернативный текст для случая отображения без поддержки скриптов -->
<!attlist noscript %attrs; -- %coreattrs, %i18n, %events -- >
<!--================== Структура документа ===================-->
<!entity % version "version cdata #fixed '%html.version;`">
<!entity % html.content "head, body">
<!element html o o (%html.content;) -- корневой элемент документа -->
<!attlist html %i18n; -- lang, dir -- >
Определение типа документа frameset
<!-- Это HTML 4.0 frameset DTD, который должен использоваться для документов с рамками. Этот DTD идентичен переходному DTD HTML 4.0 за исключением модели содержимого "html" элемента: в документах с рамками, элемент "frameset" замещает элемент "body".
Дополнительная информация о HTML 4.0 доступна по адресу:
. -->
<!entity % html.version "-//w3c//dtd HTML 4.0 frameset//en" -- Типовое использование:
<!doctype html public "-//w3c//dtd html 4.0 frameset//en"
"http://www.w3.org/tr/rec-html40/frameset.dtd">
<html>
<head>
...
</head>
<frameset>
...
</frameset>
</html>
-->
<!entity % html.frameset "include">
<!entity % html4.dtd public "-//w3c//dtd html 4.0 transitional//en">
%html4.dtd;
Определения полей заголовка
Этот раздел определяет синтаксис и семантику всех стандартных полей заголовков HTTP/1.1. Для полей заголовков объекта, как отправитель, так и получатель могут рассматриваться клиентом или сервером в зависимости от того, кто получает объект.
13.1. Поле Accept
Поле заголовка запроса Accept может использоваться для спецификации определенных типов среды, которые приемлемы для данного ресурса. Заголовки Accept могут использоваться для индикации того, что запрос ограничен в рамках определенного набора типов, как в случае запросов отображения в текущей строке.
Accept | = "Accept" ":" |
| #( media-range [ accept-params ] ) |
media-range | = ( "*/*" |
| | ( type "/" "*") |
| | ( type "/" subtype ) |
| ) *( ";" parameter ) |
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
Символ звездочка "*" используется для того, чтобы группировать типы среды в группы с "*/*", указывающим на все типы, и "type/*", указывающим на все субтипы данного типа. Группа сред может включать в себя параметры типа среды, которые применимы. За каждой группой сред может следовать один или более параметров приема (accept-params), начинающихся с "q" параметра для указания фактора относительного качества. Первый "q" параметр (если таковой имеется) отделяет параметры группы сред от параметров приема. Факторы качества позволяют пользователю или агенту пользователя указать относительную степень предпочтения для данной группы сред, используя шкалу значений q от 0 до 1 (раздел 2.9). Значение по умолчанию соответствует q=1.
Замечание. Использование имени параметра "q" для разделения параметров типа среды от параметров расширения Accept связано с исторической практикой. Это мешает присвоения параметру типа среды имени "q". Пример Accept: audio/*; q=0.2, audio/basic.
Должно интерпретироваться, как "Я предпочитаю audio/basic, но шлите мне любые типы аудио, если это лучшее, что имеется после 80% понижения качества".
Если поле заголовка Accept отсутствует, тогда предполагается, что клиент воспринимает все типы среды. Если поле заголовка Accept присутствует и, если сервер не может послать отклик, который является приемлемым, согласно комбинированному значению поля Accept, тогда сервер должен послать отклик 406 (not acceptable). Более сложный пример.
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
Это будет интерпретироваться следующим образом: "text/html и text/x-c являются предпочтительными типами сред, но, если их нет, тогда следует слать объект text/x-dvi, если он отсутствует, следует присылать объект типа text/plain".
Группы сред могут быть заменены другими группами или некоторыми специальными типами среды. Если используется более одного типа среды для данного типа, предпочтение отдается наиболее специфичному типу. Например,
Accept: text/*, text/html, text/html;level=1, */*
имеет следующие предпочтения:
1) text/html;level=1
2) text/html
3) text/*
4) */*
Фактор качества типа среды, ассоциированный с данным типом определен путем нахождения группы сред с наивысшим предпочтением, который подходит для данного типа. Например,
Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5
в результате будут установлены следующие величины:
text/html;level=1 | = 1 |
text/html | = 0.7 |
text/plain | = 0.3 |
image/jpeg | = 0.5 |
text/html;level=2 | = 0.4 |
text/html;level=3 ; | = 0.7 |
Замечание. Агент пользователя может быть создан с набором значений качества по умолчанию для определенных групп среды. Однако, если только агент пользователя не является закрытой системой, которая не может взаимодействовать с другими агентами, этот набор по умолчанию должен быть конфигурируем пользователем.
13.2. Поле Accept-Charset
Поле заголовка запроса Accept-Charset может быть использовано для указания того, какой символьный набор приемлем для отклика. Это поле позволяет клиентам, способным распознавать более обширные или специальные наборы символов, сигнализировать об этой возможности серверу, который способен представлять документы в рамках этих символьных наборов.
Набор символов ISO-8859- 1 может считаться приемлемым для всех агентов пользователя.
Accept-Charset = "Accept-Charset" ":"
1#( charset [ ";" "q" "=" qvalue ] )
Значения символьных наборов описаны в разделе 2.4. Каждому символьному набору может быть поставлено в соответствие значение качества, которое характеризует степень предпочтения пользователя для данного набора. Значение по умолчанию q=1. Например Accept-Charset: ISO-8859-5, unicode-1-1;q=0.8. Если заголовок Accept-Charset отсутствует, по умолчанию это означает, что приемлем любой символьный набор. Если заголовок Accept-Charset присутствует, и, если сервер не может послать отклик, который приемлем с точки зрения заголовка Accept-Charset, тогда он должен послать сообщение об ошибке со статусным кодом 406 (not acceptable), хотя допускается посылка и отклика "unacceptable".
13.3. Поле Accept-Encoding
Поле заголовка запроса Accept-Encoding сходно с полем Accept, но регламентирует кодировку содержимого (раздел 13.12), которая приемлема в отклике.
Accept-Encoding = "Accept-Encoding" ":"
#( content-coding )
Ниже приведен пример его использования Accept-Encoding: compress, gzip
Если заголовок Accept-Encoding в запросе отсутствует, сервер может предполагать, что клиент воспримет любую кодировку информации. Если заголовок Accept-Encoding присутствует и, если сервер не может послать отклик, приемлемый согласно этому заголовку, тогда серверу следует послать сообщение об ошибке со статусным кодом 406 (Not Acceptable). Пустое поле Accept-Encoding указывает на то, что не приемлемо никакое кодирование.
13.4. Поле Accept-Language
Поле заголовка запроса Accept-Language сходно с полем Accept, но регламентирует набор естественных языков, которые предпочтительны в отклике на запрос.
Accept-Language | = "Accept-Language" ":" |
| 1#( language-range [ ";" "q" "=" qvalue ] ) |
language-range | = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) |
Каждому набору языков может быть поставлено в соответствие значение качества, которое представляет собой оценку предпочтений пользователя для языков, специфицированных в диапазоне. По умолчанию значение качества "q=1". Например,
Accept-Language: da, en-gb;q=0.8, en;q=0.7
будет означать: "Я предпочитаю датский, но восприму британский английский и другие типы английского". Список языков согласуется с языковой меткой, если он в точности равен метке или, если он в точности равен префиксу метки, такому как первый символ метки, за которым следует символ "-". Специальный список "*", если он присутствует в поле Accept-Language, согласуется с любой меткой.
Замечание. Это использование префикса не предполагает, что языковые метки присвоены языкам таким образом, что, если пользователь понимает язык с определенной меткой, то он поймет все языки, имеющие метки с одним и тем же префиксом. Правило префикса просто позволяет использовать префиксные метки для случаев, когда это справедливо.
Фактор качества, присваиваемый языковой метке с помощью поля Accept-Language, равен значению качества самого длинного списка языков в поле. Если в поле отсутствует список языков, фактору качества присваивается значение нуль. Если в запросе отсутствует заголовок Accept-Language, серверу следует предполагать, что все языки приемлемы в равной мере. Если заголовок Accept-Language имеется, тогда все языки, которым присвоен фактор качества больше нуля, приемлемы.
Посылка заголовка Accept-Language с полным списком языковых предпочтений пользователя в каждом запросе может восприниматься как нарушение принципов конфиденциальности. Обсуждение этой проблемы смотри в разделе 14.7.
Замечание. Так как степень интеллигентности в высшей степени индивидуальна, рекомендуется, чтобы приложения клиента делали выбор языковых предпочтений доступным для пользователя. Если выбор не сделан доступным, тогда поле заголовка Accept-Language не должно присутствовать в запросе.
13.5.
Поле Accept-Ranges
Поле заголовка отклика Accept- Ranges позволяет серверу указать доступность широкодиапазонных запросов к ресурсу:
Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges
acceptable-ranges = 1#range-unit | "none"
Исходные серверы, которые воспринимают байт-диапазонные запросы, могут послать
Accept-Ranges: bytes
но делать это необязательно. Клиенты могут выдавать байт-диапазонные запросы, не получив этот заголовок отклика для запрашиваемого ресурса. Серверы, которые не могут работать с какими-либо диапазонными запросами, могут послать
Accept-Ranges: none,
чтобы посоветовать клиенту, не пытаться посылать такие запросы.
13.6. Поле Age
Поле заголовка отклика Age передает оценку отправителем времени с момента формирования отклика исходным сервером (или перепроверки его пригодности). Кэшированный отклик является свежим, если его возраст не превышает его времени жизни. Значения Age вычисляются согласно рекомендациям представленным разделе 12.2.3.
Age | = "Age" ":" age-value |
age-value | = delta-seconds |
Значения Age являются неотрицательным десятичным целым числом, характеризующим возраст записи в секундах.
Если кэш получает величину больше, чем наибольшее положительное число, которое он может себе представить или, если вычисление возраста вызвало переполнение, он должен передать заголовок Age со значением 2147483648 (231). Кэши HTTP/1.1 должны посылать заголовки Age в каждом отклике. Кэшам следует использовать арифметический тип чисел не менее 31 бита.
13.7. Поле Allow
Поле заголовка объекта Allow перечисляет набор методов, поддерживаемых ресурсом, идентифицированным Request-URI. Целью этого поля является точное информирование получателя о рабочих методах данного ресурса. Поле заголовка Allow должно быть представлено в отклике 405 (Method Not Allowed).
Allow = "Allow" ":" 1#method
Пример использования:
Allow: GET, HEAD, PUT
Это поле не препятствует клиенту испытать другие методы.
Однако указания, данные в значение поля заголовка Allow, следует выполнять. Действительный набор методов определяется исходным сервером во время каждого запроса.
Поле заголовка Allow может быть прислано запросом PUT, чтобы рекомендовать методы, которые будут поддерживаться новым или модифицированным ресурсом. Серверу не обязательно поддерживает эти методы, но ему следует включить заголовок Allow в отклик, чтобы сообщить действительно поддерживаемые методы.
Прокси не должен модифицировать поле заголовка Allow, даже если он не понимает все специфицированные методы, так как агент пользователя может иметь другие средства связи с исходным сервером.
Поле заголовка Allow не указывают на то, что методы реализованы на уровне сервера. Серверы могут использовать поле заголовка отклика Public (раздел 13.35), чтобы описать, какие методы реализованы на сервере.
13.8. Авторизация
Агент пользователя, который хочет авторизовать себя на сервере может сделать это после получения отклика 401, включив в запрос поле заголовка Authorization. Значение поля Authorization состоит из идентификационной информации агента пользователя для области (realm) запрошенных ресурсов.
Authorization = "Authorization" ":" credentials
Авторизация доступа HTTP описана в разделе 10. Если запрос идентифицирован и область специфицирована, та же самая идентификационная информация может быть использована для других запросов в пределах данной области.
Когда кэш коллективного пользования (см. раздел 12.7) получает запрос, содержащий поле Authorization, он не должен присылать соответствующий отклик в качестве ответа на какой-либо другой запрос, если только не выполняется одно из следующих условий:
Если отклик включает в себя директиву Cache-Control "proxy-revalidate", кэш может использовать этот отклик при последующих запросах, но прокси-кэш должен сначала перепроверить его пригодность с помощью исходного сервера, используя заголовки нового запроса для того, чтобы исходный сервер мог идентифицировать новый запрос.
Если отклик содержит в себе директиву Cache-Control "must-revalidate", кэш может использовать этот отклик при ответах на последующие запросы, но все кэши должны сначала перепроверить пригодность откликов с помощью исходного сервера, используя заголовки нового запроса для того, чтобы сервер мог идентифицировать новый запрос.
Если отклик содержит директиву Cache-Control "public", то этот отклик может быть отослан в ответ на любой последующий запрос.
13.9. Поле Cache-Control
Поле общего заголовка Cache-Control используется для спецификации директив, которые должны исполняться всеми механизмами кэширования вдоль цепочки запрос/отклик. Директивы определяют поведение, которое, как предполагается, должно предотвратить нежелательную интерференцию откликов или запросов в кэше. Эти директивы обычно переписывают алгоритм кэширования, используемый по умолчанию. Директивы кэша являются однонаправленными, присутствие директивы в запросе не предполагает, что та же директива будет присутствовать и в отклике.
Заметьте, что кэши HTTP/1.0 могут не реализовывать управление (Cache-Control), а могут использовать только директиву Pragma: no-cache (см. раздел 13.32).
Директивы кэша должны пропускаться через приложения прокси или внешнего шлюза (gateway), вне зависимости от их значения для этого приложения, так как директивы могут быть применимы для всех получателей в цепочке запрос/отклик. Невозможно специфицировать директивы для отдельных кэшей.
Cache-Control | = "Cache-Control" ":" 1#cache-directive |
cache-directive | = cache-request-directive |
| | cache-response-directive |
cache-request-directive | = "no-cash" ["=" <">1#field-name<">] |
| | "no-store" |
| | "max-age" "=" delta-seconds |
| | "max-stale" [ "=" delta-seconds ] |
| | "min-fresh" "=" delta-seconds |
| | "only-if-cached" |
| | cache-extension |
cache-response-directive | = "public" |
| | "private" [ "=" <"> 1#field-name <"> ] |
| | "no-cache" [ "=" <"> 1#field-name <"> ] |
| | "no-store" |
| | "no-transform" |
| | "must-revalidate" |
| | "max-age" "=" delta-seconds |
| | cache-extension; |
cache-extension | = token [ "=" ( token | quoted-string ) ] |
Если директива появляется без какого-либо параметра 1#field-name, она воздействует на весь запрос или отклик. Когда такая директива приходит с параметром 1#field-name, она воздействует только на именованное поле или поля и не имеет никакого действия на остальную часть запроса или отклика. Этот механизм поддерживает расширяемость. Реализации будущих версий протокола HTTP могут использовать эти директивы для полей заголовка, неопределенных в HTTP/1.1.
Директивы управления кэшем могут быть разделены на следующие категории:
Ограничения на то, что можно кэшировать. Они налагаются только исходным сервером.
Ограничения на то, что можно записывать в память кэша. Они определяются исходным сервером или агентом пользователя.
Модификации базового механизма контроля годности записей. Они вносятся либо исходным сервером, либо агентом пользователя.
Управление процессом перепроверки годности записей и перезагрузкой осуществляется только агентом пользователя.
Управление преобразованием объектов.
Расширения системы кэширования.
13.9.1. Что допускает кэширование?
По умолчанию отклик допускает кэширование, если требования метода запроса, поля заголовка запроса и код статуса отклика указывают на то, что кэширование не запрещено. Раздел 12.4 обобщает эти рекомендации для кэширования. Следующие Cache-Control директивы отклика позволяют исходному серверу переписать стандартные требования по кэшируемости:
public
Указывает, что отклик может кэшироваться любым кэшем, даже если он в норме не кэшируем или кэшируем только в кэшах индивидуального пользования. (См. также об авторизации в разделе 13.8.)
private
Указывает, что весь или часть сообщения отклика предназначена для одного пользователя и не должна быть записана кэшем коллективного пользования. Это позволяет исходному серверу заявить о том, что специфицированные части отклика предназначены только для одного пользователя, и он не может отсылаться в ответ на запросы других пользователей. Частный кэш может кэшировать такие отклики.
Замечание. Это использование слова частный (private) определяет только возможность кэширования и не гарантирует конфиденциальности для содержимого сообщения.
no-cache
Указывает, весь или фрагмент сообщения-отклика не должны кэшироваться, где бы то ни было. Это позволяет исходному серверу предотвратить кэширование даже для кэшей, сконфигурированных для рассылки устаревших откликов.
Замечание. Большинство кэшей HTTP/1.0 не распознают и не исполняют эту директиву.
13.9.2. Что может быть записано в память кэша?
Целью директивы no-store (не запоминать) является предотвращение ненамеренного распространения или записи конфиденциальной информации (например, на backup ленты). Директива no-store применяется для всего сообщения и может быть послана как в отклике, так и в запросе. При посылке в запросе кэш не должен запоминать какую-либо часть этого запроса или присланного в ответ отклика. При посылке в отклике, кэш не должен запоминать какую-либо часть отклика или запроса, его вызвавшего. Эта директива действует как для индивидуальных кэшей, так и кэшей коллективного пользования. "Не должно запоминаться" в данном контексте означает, что кэш не должен заносить отклик в долговременную память и должен сделать все от него зависящее для того, чтобы удалить эту информацию из временной памяти после переадресации этих данных.
Даже когда эта директива ассоциирована с откликом, пользователи могут непосредственно запомнить такой отклик вне системы кэширования (например, с помощью диалога "Save As"). Буферы предыстории могут запоминать такие отклики как часть своей нормальной работы.
Цель этой директивы обеспечение выполнения определенных требований пользователей и разработчиков, кто связан с проблемами случайного раскрытия информации за счет непредвиденного доступа к структуре данных кэша. При использовании этой директивы можно в некоторых случаях улучшить конфиденциальность, но следует учитывать, что не существует какого-либо надежного механизма для обеспечения конфиденциальности.
В частности, некоторые кэши могут не распознавать или не выполнять эту директиву, а коммуникационные сети могут прослушиваться.
13.9.3. Модификации базового механизма контроля времени жизни
Время пригодности объекта (entity expiration time) может быть специфицировано исходным сервером с помощью заголовка Expires (см. раздел 13.21). Другой возможностью является применение директивы max-age в отклике.
Если отклик включает в себя как заголовок Expires, так и директиву max-age, более высокий приоритет имеет директива max-age, даже если заголовок Expires накладывает более жесткие ограничения. Это правило позволяет исходному серверу обеспечить для заданного отклика большее время жизни в случае объектов кэша HTTP/1.1 (или более поздней версии), чем в HTTP/1.0. Это может быть полезным, если кэш HTTP/1.0 некорректно вычисляет возраст объекта или его время пригодности, например, из-за не синхронности часов.
Замечание. Большинство старых кэшей, несовместимых с данной спецификацией, не поддерживают применение директив управления кэшем. Исходный сервер, желающий применить директиву управления кэшем, которая ограничивает, но не запрещает кэширование в системах, следующих регламентациям HTTP/1.1, может использовать то, что директива max-age переписывает значение, определенное Expires.
Другие директивы позволяют агенту пользователя модифицировать механизм контроля времени жизни объектов. Эти директивы могут быть специфицированы в запросе max-age.
Этот запрос указывает, что клиент желает воспринять отклик, чей возраст не больше времени, заданного в секундах. Если только не включена также директива max-stale, клиент не воспримет устаревший отклик.
Запрос min-fresh указывает, что клиент желает воспринять отклик, чье время жизни не меньше, чем его текущий возраст плюс заданное время в секундах. То есть, клиент хочет получит отклик, который будет еще свежим, по крайней мере, заданное число секунд.
Запрос max-stale указывает, что клиент желает воспринять отклик, время жизни которого истекло.
Если max- stale присвоено конкретное значение, тогда клиент хочет получить отклик, время жизни которого не ранее, чем заданное число секунд тому назад. Если значения max-stale в директиве не указано, тогда клиент готов воспринять отклики любого возраста.
Если кэш присылает устаревший отклик, из-за наличия в запросе директивы max-stale, либо потому, что кэш сконфигурирован таким образом, что переписывает время жизни откликов, кэш должен присоединить заголовок предупреждения к отклику, используя Warning 10 (Response is stale - отклик устарел).
13.9.4. Управление перепроверкой пригодности и перезагрузкой
Иногда агент пользователя может потребовать, чтобы кэш перепроверил пригодность своих записей с помощью исходного сервера (а не соседнего кэша по пути к исходному серверу), или перезагрузил свой кэш из исходного сервера. Может потребоваться перепроверка End-to-end, если и кэш и исходный сервер имеют завышенные оценки времени жизни кэшированных откликов. Перезагрузка End-to-end может потребоваться, если запись в кэше оказалась по какой-то причине поврежденной.
Перепроверка типа End-to-end может быть запрошена в случае, когда клиент не имеет своей локальной копии, этот вариант мы называем "не специфицированная перепроверка end-to-end", или когда клиент имеет локальную копию, такой вариант называется "специфической перепроверкой end-to-end."
Клиент может потребовать три вида действий, используя в запросе директивы управления кэшем:
End-to-end reload
Запрос включает в себя директиву управления кэшем "no-cache" или, для совместимости с клиентами HTTP/1.0, "Pragma: no-cache". В запросе с директивой no-cache может не быть никаких имен полей. Сервер не должен использовать кэшированную копию при ответе на этот запрос.
Specific end-to-end revalidation
Запрос включает в себя директиву управления кэшем "max-age=0", которая вынуждает каждый кэш вдоль пути к исходному серверу сверить свою собственную запись, если она имеются, с записью следующего кэша или сервера.
Исходный запрос включает в себя требования перепроверки для текущего значениея валидатора клиента.
Unspecified end-to-end revalidation
Запрос включает в себя директиву управления кэшем "max-age=0", которая вынуждает каждый кэш вдоль пути к исходному серверу сверить свою собственную запись, с записью следующего кэша или сервера. Исходный запрос не включает в себя требований перепроверки. Первый кэш по пути (если таковой имеется), который содержит запись данного ресурса, подключает условия перепроверки со своим текущим валидатором.
Когда промежуточный кэш вынуждается с помощью директивы max-age=0 перепроверить свои записи, присланный клиентом валидатор может отличаться от того, что записан в данный момент в кэше. В этом случае кэш может воспользоваться в своем запросе любой из валидаторов, не нарушая семантической прозрачности.
Однако выбор валидатора может влиять на результат. Наилучшим подходом для промежуточного кэша является использование в запросе своего собственного валидатора. Если сервер присылает отклик 304 (Not Modified), тогда кэш должен отправить свою уже проверенную копию клиенту со статусным кодом 200 (OK). Если сервер присылает отклик с новым объектом и валидатором кэша, промежуточный кэш должен сверить, тем не менее, полученный валидатор с тем, что прислал клиент, используя функцию сильного сравнения. Если валидатор клиента равен присланному сервером, тогда промежуточный кэш просто возвращает код 304 (Not Modified). В противном случае он присылает новый объект со статусным кодом 200 (OK).
Если запрос включает в себя директиву no-cache, в нем не должно быть min-fresh, max-stale или max-age.
В некоторых случаях, таких как периоды исключительно плохой работы сети, клиент может захотеть возвращать только те отклики, которые в данный момент находятся в памяти, и не перезагружать или перепроверять записи из исходного сервера. Для того чтобы сделать это, клиент может включить в запрос директиву only-if-cached. При получении такой директивы кэшу следует либо реагировать, используя кэшированную запись, которая соответствует остальным требованиям запроса, либо откликаться статусным кодом 504 (Gateway Timeout).
Однако если группа кэшей работает как унифицированная система с хорошей внутренней коннективностью, тогда такой запрос может быть переадресован в пределах группы кэшей
Так как кэш может быть сконфигурирован так, чтобы игнорировать времена жизни, заданные сервером, а запрос клиента может содержать директиву max-stale, протокол включает в себя механизм, который позволяет серверу требовать перепроверки записей в кэше для любого последующего применения. Когда в отклике, полученном кэшем, содержится директива must-revalidate, этот кэш не должен использовать эту запись для откликов на последующие запросы без сверки ее на исходном сервере. Таким образом, кэш должен выполнить перепроверку end-to-end каждый раз, если согласно значениям Expires или max-age, кэшированный отклик является устаревшим.
Директива must-revalidate необходима для поддержания надежной работы для определенных функций протокола. При любых обстоятельствах HTTP/1.1 кэш должен выполнять директиву must-revalidate. В частности, если кэш по какой-либо причине не имеет доступа к исходному серверу, он должен генерировать отклик 504 (Gateway Timeout).
Серверы должны посылать директиву must-revalidate, тогда и только тогда, когда неудача запроса перепроверки объекта может вызвать нарушение работы системы, например, не выполнение финансовой операции без оповещения об этом. Получатели не должны осуществлять любые автоматические действия, которые нарушают эту директиву, и не должны посылать непригодную копию объекта, если перепроверка не удалась.
Хотя это и не рекомендуется, агенты пользователя, работающие в условиях очень плохой коннективности, могут нарушать эту директиву, но, если это происходит, пользователь должен быть предупрежден в обязательном порядке, что присланный отклик возможно является устаревшим. Предупреждение должно посылаться в случае каждого непроверенного доступа, при этом следует требовать подтверждения от пользователя.
Директива proxy-revalidate имеет то же значение, что и must-revalidate, за исключением того, что она не применима для индивидуальных кэшей агентов пользователя.
Она может использоваться в отклике на подтвержденный запрос, чтобы разрешить кэшу пользователя запомнить и позднее прислать отклик без перепроверки (так как он был уже подтвержден однажды этим пользователем), в то же время прокси должен требовать перепроверки всякий раз при обслуживании разных пользователей (для того чтобы быть уверенным, что каждый пользователь был авторизован). Заметьте, что такие авторизованные отклики нуждаются также в директиве управления кэшем public для того, чтобы разрешить их кэширование.
13.9.5. Директива No-Transform
Разработчики промежуточных кэшей (прокси) выяснили, что полезно преобразовать тип среды для тел определенных объектов. Прокси может, например, преобразовать форматы изображения для того, чтобы сэкономить место в памяти кэша или чтобы уменьшить информационный поток в тихоходном канале. HTTP должен датировать такие преобразования, выполняемые без оповещения.
Серьезные операционные проблемы происходят, однако, когда такие преобразования производятся над телами объектов, предназначенных для определенного сорта приложений. Например, использующих медицинские изображения, предназначенные для анализа научных данных, а также тех, которые применяют авторизацию end-to-end, или требуют побитной совместимости с оригиналом.
Следовательно, если отклик содержит директиву no-transform, промежуточный кэш или прокси не должны изменять те заголовки, которые перечислены в разделе 12.5.2, так как они могут содержать директиву no-transform. Это предполагает, что кэш или прокси не должны изменять любую часть тела объекта, который имеет такие заголовки.
13.9.6. Расширения управления кэшем
Поле заголовка Cache-Control может быть расширено за счет использования одной или более лексем расширения, каждой из которых может быть присвоено определенное значение. Информационные расширения (те которые не требуют изменений в работе кэша) могут быть добавлены без изменения семантики других директив. Поведенческие расширения спроектированы для того, чтобы выполнять функции модификаторов существующих директив управления кэшем.
Новые директивы и стандартные директивы устроены так, что приложения, которые не воспринимают новую директиву, по умолчанию исполнят стандартную процедуру. Те же приложения, которые распознают новую директиву, воспринимают ее как модификацию стандартной процедуры. Таким путем расширения директив управления кэшем могут быть сделаны без изменения базового протокола.
Этот механизм расширений зависит от того, выполняет ли кэш все директивы управления, определенные для базовой версии HTTP. Предполагается, что кэш реализует определенные расширения и игнорирует все директивы, которые не может распознать.
Например, рассмотрим гипотетическую, новую директиву, названную "community", которая действует как модификатор директивы "private". Мы определяем эту новую директиву так, что в дополнение к стандартным возможностям индивидуальных кэшей, кэши, которые обслуживают группу (community), могут кэшировать их отклики. Исходный сервер, желающий позволить группе "UCI" использовать частные отклики на их общем кэше, может решить эту проблему, включив директиву управления кэшем: private, community="UCI".
Кэш, получив это поле заголовка, будет действовать корректно, если даже не понимает расширение "community", так как он видит и понимает директиву "private" и, таким образом, по умолчанию обеспечит безопасное функционирование.
Не распознанная директива управления должна игнорироваться. Предполагается, что любая директива, в том числе и не узнанная кэшем HTTP/1.1, имеет по умолчанию стандартную директиву-подмену, которая обеспечивает определенный уровень функциональности, когда директива-расширение не распознается.
13.10. Соединение
Поле общего заголовка Connection позволяет отправителю специфицировать опции, которые желательны для конкретного соединения. Заголовок Connection имеет следующую грамматику:
Connection-header = "Connection" ":" 1#(connection-token)
connection-token = token
Прокси-серверы HTTP/1.1 должны выполнить разбор поля заголовка Connection, прежде чем выполнить переадресацию, и для каждой лексемы соединения в этом поле убрать любые поля заголовка в сообщении с именами, совпадающими с этими лексемами.
Опции Connection отмечаются присутствием лексем соединения в поле заголовка Connection, а не какими-либо дополнительными полями заголовка, так как дополнительное поле заголовка может быть не послано, если нет параметров, ассоциированных с данной опцией соединения. HTTP/1.1 определяет опцию "close" (закрыть) для отправителя, чтобы сигнализировать о том, что соединение будет закрыто после завершения передачи отклика. Например, наличие
Connection: close
как в полях запроса, так и в полях отклика указывает на то, что соединение не следует рассматривать как "постоянное" (раздел 7.1) после завершения передачи данного запроса/отклика.
Приложения HTTP/1.1, которые не поддерживают постоянные соединения, должны содержать опцию соединения "close" в каждом сообщении.
13.11. Content-Base
Поле заголовка объекта Content-Base может быть использовано для спецификации базового URI, которое позволяет работать с относительными URL в пределах объекта. Это поле заголовка описано как Base в документе RFC 1808, который, как ожидается, будет пересмотрен.
Content-Base = "Content-Base" ":" absoluteURI
Если поле Content-Base отсутствует, базовый URI объекта определяется его Content-Location (если это Content-Location URI является абсолютным) или URI используется для инициации запроса. Заметьте, однако, что базовый URI содержимого в пределах тела объекта может быть переопределен.
13.12. Кодирование содержимого
Поле заголовка объекта Content-Encoding используется в качестве модификатора типа среды. Если это поле присутствует, его значение указывает, что тело объекта закодировано, и какой механизм декодирования следует применить, чтобы получить массив данных, ориентированный на тип среды, указанный в поле Content-Type. Поле Content-Encoding первоначально предназначалось для того чтобы архивировать документ без потери его идентичности с учетом типа среды, на которую он ориентирован.
Content-Encoding = "Content-Encoding" ":" 1#content-coding
Кодировки содержимого определены в разделе 2.5. Пример его использования приведен ниже
Content-Encoding: gzip
Content-Encoding ( кодирование содержимого) является характеристикой объекта, задаваемой Request-URI. Обычно тело объекта заносится в память в закодированном виде и декодируется перед отображением или другим аналогичным использованием.
Если было применено множественное кодирование объекта, кодирование содержимого должно быть перечислено в том порядке, в котором оно было выполнено.
13.13. Язык содержимого
Поле заголовка объекта Content-Language описывает естественный язык(и) потенциальных читателей вложенного объекта. Заметьте, что это может быть совсем не эквивалентно всем языкам, использованным в теле объекта.
Content-Language = "Content-Language" ":" 1#language-tag
Языковые метки определены в разделе 2.10. Первоначальной целью поля Content-Language является предоставление пользователю возможности дифференцировать объекты согласно языковым предпочтениям. Таким образом, если содержимое тела предназначено только для аудитории, говорящей на датском языке, подходящим содержимым поля Content-Language может быть
Content-Language: da
Если поле Content-Language не задано, по умолчанию считается, что содержимое ориентировано на любую аудиторию. Это может значить, что отправитель не выделяет какой-либо естественный язык конкретно, или что отправитель не знает, какой язык предпочесть.
Список языков может быть предложен для текста, который предназначен для многоязыковой аудитории. Например, перевод "Treaty of Waitangi," представленный одновременно в оригинальной версии на маори и на английском, может быть вызван с помощью
Content-Language: mi, en
Однако только то, что в поле объекта перечислено несколько языков не означает, что объект предназначен для многоязыковой аудитории. Примером может быть языковый курс для начинающих, такой как "A First Lesson in Latin," который предназначен для англо-говорящей аудитории. В этом случае поле Content-Language должно включать только "en".
Поле Content-Language может быть применено к любому типу среды - оно не ограничено только текстовыми документами.
13.14. Длина содержимого
Содержимое поля заголовка объекта Content-Length указывает длину тела сообщения в октетах (десятичное число), посылаемое получателю, или в случае метода HEAD, размер тела объекта, который мог бы быть послан при запросе GET.
Content-Length = "Content-Length" ":" 1*DIGIT
Например
Content-Length: 3495
Приложениям следует использовать это поле для указания размера сообщения, которое должно быть послано вне зависимости от типа среды. Получатель должен иметь возможность надежно определить положение конца запроса HTTP/1.1, содержащего тело объекта, например, запрос использует Transfer-Encoding chunked или multipart body.
Любое значение Content-Length больше или равное нулю допустимо. Раздел 3.4 описывает то, как определить длину тела сообщения, если параметр Content-Length не задан.
Замечание. Значение этого поля заметно отличается от соответствующего определения в MIME, где оно является опционным, используемым в типе содержимого "message/external-body". В HTTP его следует посылать всякий раз, когда длина сообщения должна быть известна до начала пересылки.
13.15. Поле Content-Location
Поле заголовка объекта Content-Location может быть использовано для определения положения ресурса для объекта, вложенного в сообщение. В случае, когда ресурс содержит много объектов, и эти объекты в действительности имеют разные положения, по которым может быть осуществлен доступ, сервер должен предоставить поле Content-Location для конкретного варианта, который должен быть прислан. Кроме того сервер должен предоставить Content-Location для ресурса, соответствующего объекту отклика.
Content-Location = "Content-Location" ":"
( absoluteURI | relativeURI )
Если поле заголовка Content-Base отсутствует, значение Content-Location определяет также базовый URL для объекта (см. раздел 13.11).
Значение Content-Location не является заменой для исходного запрашиваемого URI, это лишь объявление положения ресурса, соответствующего данному конкретному объекту в момент запроса.
Будущие запросы могут использовать Content- Location URI, если нужно идентифицировать источник конкретного объекта.
Кэш не может предполагать, что объект с полем Content-Location, отличающимся от URI, который использовался для его получения, может использоваться для откликов на последующие запросы к этому Content-Location URI. Однако Content-Location может использоваться для того, чтобы отличить объекты, полученные из одного общего, как это описано в разделе 12.6.
Если Content-Location является относительным URI, URI интерпретируется с учетом значения Content-Base URI, присланного в отклике. Если значения Content-Base не предоставлено, относительный URI интерпретируется по отношению к Request-URI.
13.16. Content-MD5
Поле заголовка объекта Content-MD5, как это определено в RFC 1864 [23], является MD5-дайджестом тела объекта для целей обеспечения проверки end-to-end целостности сообщения MIC (message integrity check). Замечание. MIC привлекательна для регистрации случайных модификаций тела объекта при транспортировке, но не является гарантией против преднамеренных действий.)
Content | MD5 = "Content-MD5" ":" md5-digest |
md5digest | = |
Поле заголовка Content-MD5 может генерироваться исходным сервером с целью проверки целостности тел объектов. Только исходные серверы могут генерировать поле заголовка Content-MD5. Прокси и внешние шлюзы его генерировать не должны, так как это сделает невозможными проверку целостности end-to-end. Любой получатель тела объекта, включая внешние шлюзы и прокси, могут проверять то, что значение дайджеста в этом поле заголовка согласуется с полученным телом объекта.
Дайджест MD5 вычисляется на основе содержимого тела сообщения, с учетом любых кодировок содержимого, но исключая любые транспортные кодировки (Transfer-Encoding), которые могли быть использованы. Если сообщение получено в закодированном виде с использованием Transfer-Encoding, это кодирование должно быть удалено перед проверкой значения Content-MD5 для полученного объекта.
Это означает, что дайджест вычисляется для октетов тела объекта в том порядке, в каком они будут пересланы, если не используется транспортное кодирование.
HTTP расширяет RFC 1864 с тем, чтобы разрешить вычисление дайджеста для MIME-комбинации типов среды (например, multipart/* и message/rfc822), но это никак не влияет на способ вычисления дайджеста, описанного выше.
Замечание. Существует несколько следствий этого. Тело объекта для комбинированных типов может содержать много составных частей, каждая со своими собственными MIME и HTTP заголовками (включая заголовки Content-MD5, Content-Transfer-Encoding и Content-Encoding). Если часть тела имеет заголовок Content-Transfer-Encoding или Content-Encoding, предполагается, что содержимое этой части закодировано и она включается в дайджест Content-MD5 как есть. Поле заголовка Transfer-Encoding не применимо для частей тела объекта.
Замечание. Так как определение Content-MD5 является в точности тем же для HTTP и MIME (RFC 1864), существует несколько вариантов, в которых применение Content-MD5 к телам объектов HTTP отличается от случая MIME. Один вариант связан с тем, что HTTP, в отличие от MIME, не использует Content-Transfer-Encoding, а использует Transfer-Encoding и Content-Encoding. Другой - вызван тем, что HTTP чаще, чем MIME, использует двоичный тип содержимого. И, наконец, HTTP позволяет передачу текстовой информации с любым типом разрыва строк, а не только с каноническим CRLF. Преобразование всех разрывов строк к виду CRLF не должно делаться до вычисления или проверки дайджеста: тип оформления разрыва строк при расчете дайджеста должен быть сохранен.
13.17. Отрывок содержимого
Заголовок объекта Content-Range посылается с частью тела объекта и служит для определения того, где в теле объекта должен размещаться данный фрагмент. Он также указывает полный размер тела объекта. Когда сервер присылает клиенту частичный отклик, он должен описать как длину фрагмента, так и полный размер тела объекта.
Content-Range | = "Content-Range" ":" content-range-spec |
Content-range-spec | = byte-content-range-spec |
byte-content-range-spec | = bytes-unit SP first-byte-pos "-" |
last-byte-pos "/" entity-length
В отличие от значений спецификаторов байтовых диапазонов (byte-ranges-specifier), byte-content-range-spec может специфицировать только один интервал и должен содержать абсолютные положения, как первого, так и последнего байтов.
Некорректной считается спецификация byte-content-range-spec, чье значение last-byte-pos меньше, чем его значение first-byte-pos, или значение длины объекта меньше или равно last-byte-pos. Получатель некорректной спецификации byte-content-range-spec должен игнорировать ее и любой текст, переданный вместе с ней. Примеры спецификации byte-content-range-spec, предполагающей, что объект содержит 1234 байт, приведены ниже:
The first 500 bytes: bytes 0-499/1234
The second 500 bytes: bytes 500-999/1234
All except for the first 500 bytes: bytes 500-1233/1234
The last 500 bytes: bytes 734-1233/1234
Когда сообщение HTTP включает в себя содержимое одного фрагмента (например, отклик на запрос одного фрагмента, или на запрос набора фрагментов, которые перекрываются без зазоров), это содержимое передается с заголовком Content-Range, а заголовок Content-Length несет в себе число действительно переданных байт. Например,
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
Когда сообщение HTTP несет в себе содержимое нескольких фрагментов (например, отклик на запрос получения нескольких, не перекрывающихся фрагментов), они передаются как многофрагментное MIME-сообщение. Многофрагментный тип данных MIME используемый для этой цели, определен в этой спецификации как "multipart/byteranges". (Смотри приложение 16.2).
Клиент, который не может декодировать сообщение MIME multipart/byteranges, не должен запрашивать несколько байт-фрагментов в одном запросе.
Когда клиент запрашивает несколько фрагментов байт в одном запросе, серверу следует присылать их в порядке перечисления.
Если сервер игнорирует спецификацию byte-range-spec, из- за того, что она некорректна, сервер должен воспринимать запрос так, как если бы некорректного заголовка Range не существовало вовсе. (В норме это означает посылку отклика с кодом 200, содержащего весь объект). Причиной этого является то, что клиент может прислать такой некорректный запрос, только когда объект меньше чем объект, полученный по предыдущему запросу.
13.18. Тип содержимого
Поле заголовка объекта Content-Type указывает тип среды тела объекта, посланного получателю, или, в случае метода HEAD, тип среды, который был бы применен при методе GET.
Content-Type = "Content-Type" ":" media-type
Типы среды определены в разделе 2.7. Примером поля может служить
Content-Type: text/html; charset=ISO-8859-4
Дальнейшее обсуждение методов идентификации типа среды объекта приведено в разделе 6.2.1.
13.19. Дата
Поле общего заголовка Date представляет дату и время формирования сообщения, имеет ту же семантику, что и orig-date в RFC 822. Значение поля равно HTTP-date, как это описано в разделе 2.3.1.
Date = "Date" ":" HTTP-date
Пример
Date: Tue, 15 Nov 1994 08:12:31 GMT
Если сообщение получено через непосредственное соединение с агентом пользователя (в случае запросов) или исходным сервером (в случае откликов), дата может считаться текущей датой конца приема. Однако так как дата по определению является важной при оценке характеристик кэшированных откликов, исходный сервер должен включать поле заголовка Date в каждый отклик. Клиентам следует включать поле заголовка Date в сообщения, которые несут тело объекта запросов PUT и POST, но даже здесь это является опционным. Полученному сообщению, которое не имеет поля заголовка Date, следует присвоить дату. Это может сделать один из получателей, если сообщение будет кэшировано им, или внешним шлюзом.
Теоретически дата должна представлять момент времени сразу после генерации объекта. На практике поле даты может быть сформировано в любое время в процессе генерации сообщения.
Формат поля Date представляет собой абсолютную дату и время так, как это определено для даты HTTP в разделе 2.3. Оно должно быть послано в формате, описанном в документе RFC-1123 [8].
13.20. Поле ETag
Поле заголовка объекта ETag определяет метку объекта. Заголовки с метками объектов описаны в разделах 13.20, 13.25, 13.26 и 13.43. Метка объекта может использоваться для сравнения с другими объектами того же самого ресурса (см. раздел 12.8.2).
ETag = "ETag" ":" entity-tag
Примеры:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
13.21. Поле Expires
Поле заголовка объекта Expires содержит дату/время с момента, когда отклик может считаться устаревшим. Устаревшая запись в кэше в норме не должна посылаться кэшем (а также прокси кэшем и кэшем агента пользователя), если только она не будет сначала перепроверена с помощью исходного сервера (или с помощью промежуточного кэша, который содержит свежую копию объекта). Дальнейшее обсуждение модели контроля пригодности записей содержится в разделе 12.2. Присутствие поля Expires не предполагает, что исходный ресурс изменит или удалит объект по истечении указанного времени.
Формат абсолютной даты и времени описан в разделе 2.3. Он должен следовать рекомендациям документа RFC1123:
Expires = "Expires" ":" HTTP-date
Примером реализации формата даты может служить
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Замечание. Если отклик содержит поле Cache-Control с директивой max-age, то эта директива переписывает значение поля Expires.
Клиенты HTTP/1.1 и кэши должны рассматривать некорректные форматы даты, в особенности те, что содержат нули, как относящиеся к прошлому (то есть, как "уже истекшие").
Для того, чтобы пометить отклик, как "уже с истекшим сроком", исходный сервер должен использовать дату Expires, которая равна значению заголовка Date. (Правила вычисления времени истечения пригодности записи смотри в разделе 12.2.4.)
Для того, чтобы пометить отклик как "всегда пригодный", исходный сервер должен использовать дату Expires приблизительно на один год позже момента посылки отклика.
Серверы HTTP/1. 1 не должны посылать отклики с датами в поле Expires, которые устанавливают время жизни более одного года.
Присутствие поля заголовка Expires со значением даты, относящейся к будущему, означает, что они могут быть занесены в кэш, если только не указано обратного в поле заголовка Cache-Control (раздел 13.9).
13.22. Поле From
Поле заголовка запроса From (если присутствует) должно содержать интернетовский e-mail адрес пользователя. Адрес должен иметь формат, описанный в документе RFC-822 (и дополненный в RFC-1123):
From = "From" ":" mailbox
Пример:
From: webmaster@w3.org
Это поле заголовка может быть использовано для целей регистрации процедур и как средство идентификации источников некорректных и нежелательных запросов. Не следует использовать его как ненадежную систему защиты доступа. Это поле предоставляет информацию о том, кто является ответственным за метод, использованный в данном запросе. В частности, агенты-роботы должны содержать этот заголовок, так чтобы с лицом, ответственным за работу робота, можно было связаться, в случае возникновения проблем на принимающем конце.
Интернетовский e-mail адрес в этом поле может не совпадать с Интернет-адресом ЭВМ, пославшей запрос. Например, когда запрос прошел через прокси, следует использовать адрес первичного отправителя.
Замечание. Клиенту не следует посылать поле заголовка From без одобрения пользователя, так как это может вызвать конфликт с интересами конфиденциальности пользователя или нарушить политику безопасности сети отправителя. Настоятельно рекомендуется, чтобы пользователь мог дезактивировать, активировать и модифицировать значение этого поля в любое время до запроса.
13.23. Поле Host
Поле заголовка запроса Host специфицирует ЭВМ в Интернет и номер порта запрашиваемого ресурса в виде, полученном из исходного URL, который выдал пользователь или который получен из указанного ресурса (в общем случае из HTTP URL, как это описано в разделе 2.2.2). Значение поля Host должно определять положение в сети исходного сервера или шлюза, заданное исходным URL.
Это позволяет исходному серверу или шлюзу различать внутренние URL, такие как корневые "/" URL сервера для ЭВМ, которым поставлен в соответствие один IP адрес.
Host = "Host" ":" host [ ":" port ] ; Раздел 2.2.2
Имя "ЭВМ" без последующего номера порта предполагает значение порта по умолчанию для заданного вида сервиса (напр., "80" для HTTP URL). Например, запрос исходного сервера должен включать в себя:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org
Клиент должен включать поле заголовка Host во все сообщения-запросы HTTP/1.1 в Интернет (т.е., в любое сообщение, соответствующее запросу URL, который включает в себя Интернет-адрес ЭВМ, услуги которой запрашиваются). Если поле Host отсутствует, прокси HTTP/1.1 должен добавить его в сообщение-запрос до того, как переадресует запрос дальше в Интернет. Все серверы HTTP/1.1, которые базируются в Интернет, должны откликаться статусным кодом 400 на любое сообщение-запрос HTTP/1.1, в котором отсутствует поле Host.
О других требованиях относительно поля Host смотри раздел 4.2 и 16.5.1.
13.24. Поле If-Modified-Sinc
Поле заголовка запроса If-Modified-Since используется с методом GET, для того чтобы сделать его условным. Если запрошенный объект не был модифицирован со времени, указанного в этом поле, объект не будет прислан сервером, вместо этого будет послан отклик 304 (not modified) без какого-либо тела сообщения.
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
Пример поля:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Метод GET с заголовком If-Modified-Since и без заголовка Range требует, чтобы идентифицированный объект был передан, только в случае его модификации после даты, указанной в заголовке If-Modified-Since. Алгоритм определения этого включает в себя следующие шаги.
Если запрос приводит к чему-то отличному от статусного отклика 200 (OK), или если переданная дата If-Modified-Since некорректна, отклик будет в точности тот же, что и для обычного GET.
Дата раньше текущего времени сервера является некорректной.
Если объект был модифицирован после даты If-Modified-Since, отклик будет в точности тем же, что и для обычного GET.
Если объект не был модифицирован после корректно указанной даты If-Modified-Since, сервер должен прислать отклик 304 (Not Modified).
Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками.
Заметьте, что поле заголовка запроса Range модифицирует значение If-Modified-Since. Более детально эта проблема рассмотрена в разделе 13.36.
Заметьте, что время If-Modified-Since интерпретируются сервером, чьи часы могут быть не синхронизованы с часами клиента.
Если клиент использует произвольную дату в заголовке If-Modified-Since вместо даты взятой из заголовка Last-Modified для текущего запроса, тогда клиенту следует остерегаться того, что эта дата интерпретируется согласно представлениям сервера о временной шкале. Клиенту следует учитывать не синхронность часов и проблемы округления, связанные с различным кодированием времени клиентом и сервером. Это предполагает возможность быстрого изменения условий, когда документ изменяется между моментом первого запроса и датой If-Modified-Since последующего запроса, а также возможность трудностей, связанных с относительным сбоем часов, если дата If-Modified-Since получена по часам клиента (без поправки на показания часов сервера). Поправки для различных временных базисов клиента и сервера желательно делать с учетом времени задержки в сети.
13.25. Поле If-Match
Поле заголовка запроса If-Match используется с методом, для того чтобы сделать его условным. Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, является ли один из этих объектов текущим, включив список связанных с ним меток в поле заголовка If-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками. Она используется также в запросах актуализации с целью предотвращения непреднамеренной модификации не той версии ресурса что нужно.
Значение "*" соответствует любому текущему объекту ресурса.
If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
Если какая-то метка объекта совпадает с меткой объекта, который прислан в отклике на аналогичный запрос GET (без заголовка If-Match), или если задана "*" и какой-то текущий объект существует для данного ресурса, тогда сервер может реализовать запрошенный метод, как если бы поля заголовка If-Match не существовало.
Сервер должен использовать функцию сильного сравнения (см. раздел 2.11) для сопоставления меток объекта в If-Match.
Если ни одна из меток не подходит, или если задана "*" и не существует никакого текущего объекта, сервер не должен реализовывать запрошенный метод, а должен прислать отклик 412 (Precondition Failed). Это поведение наиболее полезно, когда клиент хочет помешать актуализующему методу, такому как PUT, модифицировать ресурс, который изменился после последнего доступа к нему клиента.
Если запрос без поля заголовка If-Match выдает в результате нечто отличное от статуса 2xx, тогда заголовок If-Match должен игнорироваться.
"If-Match: *" означает, что метод должен быть реализован, если представление, выбранное исходным сервером (или кэшем, возможно с привлечением механизма Vary, см. раздел 13.43), существует, и не должен быть реализован, если выбранного представления не существует.
Запрос, предназначенный для актуализации ресурса (напр., PUT) может включать в себя поле заголовка If-Match, чтобы сигнализировать о том, что метод запроса не должен быть применен, если объект, соответствующий значению If-Match (одиночная метка объекта), не является более представлением этого ресурса. Это позволяет пользователям указывать, что они не хотят, чтобы запрос прошел успешно, если ресурс был изменен без их уведомления. Примеры:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
13.26. Поле If-None-Match
Поле заголовка запроса If-None-Match используется для формирования условных методов.
Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, что ни один из этих объектов не является текущим, путем включения списка их ассоциированных меток в поле заголовка If-None-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальной избыточностью. Она также используется при актуализации запросов с тем, чтобы предотвратить непреднамеренную модификацию ресурса, о существовании которого не было известно.
Значение "*" соответствует любому текущему объекту ресурса.
If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
Если какая-либо метка объекта соответствует метке объекта, который был прислан в отклике на аналогичный запрос GET (без заголовка If-None-Match) или если задана "*" и существует какой-то текущий объект данного ресурса, тогда сервер не должен реализовывать запрошенный метод. Вместо этого, если методом запроса был GET или HEAD, серверу следует реагировать откликом 304 (Not Modified), включая поля заголовков объекта, ориентированные на кэш (в частности ETag). Для всех других методах запроса сервер должен откликаться статусным кодом 412 (Precondition Failed).
По поводу правил того, как определять соответствие двух меток объектов смотри раздел 12.8.3. С запросами GET и HEAD должна использоваться только функция слабого сравнения.
Если не подходит ни одна из меток объекта или если задана "*" и не существует ни одного текущего объекта, сервер может выполнить запрошенный метод так, как если бы поля заголовка If-None-Match не существовало.
Если запрос без поля заголовка If-None-Match, даст результат отличный от статусного кода 2xx, тогда заголовок If-None-Match должен игнорироваться.
"If-None-Match: *" означает, что метод не должен реализовываться, если представление, выбранное исходным сервером (или кэшем, возможно использующим механизм Vary, см. раздел 13.43), существует, и должен быть реализован, если представления не существует.
Эта функция может быть полезной для предотвращения конкуренции между операциями PUT.
Примеры:
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
13.27. Заголовок If-Range
Если клиент имеет частичную копию объекта в своем кэше и хочет иметь полную свежую копию объекта, он может использовать заголовок запроса Range с условным GET (используя If-Unmodified-Since и/или If-Match.) Однако если условие не выполняется, из-за того, что объект был модифицирован, клиенту следует послать второй запрос, чтобы получить все текущее содержимое тела объекта.
Заголовок If-Range позволяет клиенту заблокировать второй запрос. По существу это означает, что "если объект не изменился, следует посылать мне часть, которой у меня нет, в противном случае пришлите мене всю новую версию объекта".
If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
Если клиент не имеет метки объекта, но имеет дату Last-Modified, он может использовать эту дату в заголовке If-Range. Сервер может отличить корректную дату HTTP от любой формы метки объекта, рассмотрев не более двух символов. Заголовок If-Range следует использовать только совместно с заголовком Range, и его следует игнорировать, если запрос не содержит в себе этот заголовок, или если сервер не поддерживает операции с фрагментами.
Если метка объекта, представленная в заголовке If-Range, соответствует текущей метке, тогда сервер должен обеспечить специфицированный фрагмент объекта, используя отклик 206 (Partial content). Если метка объекта не подходит, сервер должен прислать полный объект со статусным кодом 200 (OK).
13.28. Поле If-Unmodified-Since
Поле заголовка запроса If-Unmodified-Since используется для того, чтобы формировать условные методы. Если запрошенный ресурс не был модифицирован с момента, указанного в поле, сервер должен произвести запрошенную операцию, так как если бы заголовок If-Unmodified-Since отсутствовал.
Если запрошенный объект был модифицирован после указанного времени, сервер не должен выполнять запрошенную операцию и должен прислать отклик 412 (Precondition Failed).
If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
Примером поля может служить:
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Если запрос завершается чем-то отличным от статусного кода 2xx (т.е., без заголовка If-Unmodified-Since), заголовок If-Unmodified-Since следует игнорировать. Если специфицированная дата некорректна, заголовок также игнорируется.
13.29. Поле Last-Modified
Поле заголовка объекта Last-Modified указывает на дату и время, при которых, по мнению исходного сервера, данный объект был модифицирован.
Last-Modified = "Last-Modified" ":" HTTP-date
Пример его использования
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Точное значение этого заголовка зависит от реализации исходного сервера и природы ресурса. Для файлов, это может быть дата последней модификации файловой системы. Для объектов с динамическими встроенными частями это может время последней модификации одной из встроенных компонент. Для шлюзов баз данных это может быть метка последней модификации рекорда. Для виртуальных объектов это может быть время последнего изменения внутреннего состояния.
Исходный сервер не должен посылать дату Last-Modified, которая позже, чем время формирования сообщения сервера. В таких случаях, когда последняя модификация объекта указывает некоторое на время в будущем, сервер должен заменить дату на время формирования сообщения.
Исходный сервер должен получить значение Last-Modified объекта как можно ближе по времени к моменту генерации значения Date отклика. Это позволяет получателю выполнить точную оценку времени модификации объекта, в особенности, если объект был изменен буквально накануне формирования отклика.
Серверы HTTP/1.1 должны посылать поле Last-Modified всякий раз, когда это возможно.
13.30. Поле Location
Поле заголовка отклика Location используется для переадресации запроса на сервер, отличный от указанного в Request-URI, или для идентификации нового ресурса.
В случае отклика 201 (Created), поле Location указывает на новый ресурс, созданный в результате запроса. Для откликов 3xx поле Location должно указывать предпочтительные URL сервера для автоматической переадресации на ресурс. Значение поля включает одинарный абсолютный URL.
Location = "Location" ":" absoluteURI
Например
Location: http://www.w3.org/pub/WWW/People.html
Замечание. Поле заголовка Content-Location (раздел 13.15) отличается от поля Location в том, что Content-Location идентифицирует исходное положение объекта, заключенное в запросе. Следовательно, отклик может содержать поля заголовка как Location, так и Content-Location. Требования некоторых методов изложены также в разделе 12.10.
13.31. Поле Max-Forwards
Поле заголовка запроса Max-Forwards может использоваться с методом TRACE (раздел 13.31) ,чтобы ограничить число прокси или шлюзов, которые могут переадресовывать запрос. Это может быть полезным, когда клиент пытается отследить путь запроса в случае возникновения различных проблем.
Max-Forwards = "Max-Forwards" ":" 1*DIGIT
Значение Max-Forwards представляет собой целое десятичное число, которое указывает сколько еще раз запрос можно переадресовать.
Каждый прокси или шлюз получатель запроса TRACE, содержащего поле заголовка Max-Forwards, должен проверить и актуализовать его величину прежде, чем переадресовывать запрос. Если полученная величина равна нулю, получателю не следует переадресовывать запрос. Вместо этого, ему следует откликнуться как конечному получателю статусным кодом 200 (OK), содержащим полученное сообщение-запрос в качестве тела отклика (как это описано в разделе 8.8). Если полученное значение больше нуля, тогда переадресованное сообщение должно содержать актуализованное значение поля Max-Forwards (уменьшенное на единицу).
Поле заголовка Max-Forwards следует игнорировать для всех других методов определенных в данной спецификации и для всех расширений методов, для которых это не является частью определения метода.
13.32. Поле Pragma
Поле общего заголовка Pragma используется для включения специальных директив (зависящих от конкретной реализации), которые могут быть применены ко всем получателям вдоль цепочки запрос/отклик. Все директивы pragma специфицируют с точки зрения протокола опционное поведение. Однако некоторые системы могут требовать, чтобы поведение соответствовало директивам:
Pragma | = "Pragma" ":" 1#pragma-directive |
pragma-directive | = "no-cache" | extension-pragma |
extension-pragma | = token [ "=" ( token | quoted-string ) ] |
Когда в запросе присутствует директива no-cashe, приложение должно переадресовать запрос исходному серверу, даже если имеется кэшированная копия того, что запрошено. Директива pragma имеет ту же семантику, что и директива кэша no-cache (см. раздел 13.9) и определена здесь для обратной совместимости с HTTP/1.0. Клиентам следует включать в запрос оба заголовка, когда посылается запрос no-cache серверу, о котором неизвестно, совместим ли он с HTTP/1.1.
Нельзя специфицировать директиву pragma для какого-то отдельного получателя. Однако любая директива pragma неприемлемая для получателя должна им игнорироваться.
Клиенты HTTP/1.1 не должны посылать заголовок запроса Pragma. Кэши HTTP/1.1 должны воспринимать "Pragma: no-cache", как если бы клиент послал "Cache-Control: no-cache". Никаких новых директив Pragma в HTTP определено не будет.
13.33. Поле Proxy-Authenticate
Поле заголовка отклика Proxy-Authenticate должно быть включено в качестве части отклика 407 (Proxy Authentication Required). Значение поля состоит из вызова, который указывает схему идентификации, и параметров, применимых в прокси для данного Request-URI.
Proxy-Authenticate = "Proxy-Authenticate" ":" challenge
Процесс авторизованного доступа HTTP описан в разделе 10. В отличие от WWW-Authenticate, поле заголовка Proxy-Authenticate применимо только к текущему соединению и не может быть передано другим клиентам.
Однако, промежуточному прокси может быть нужно получить свои собственные авторизационные параметры с помощью запроса у ниже расположенного клиента, который при определенных обстоятельствах может проявить себя как прокси, переадресующий поле заголовка Proxy-Authenticate.
13.34. Поле Proxy-Authorization
Поле заголовка запроса Proxy-Authorization позволяет клиенту идентифицировать себя (или его пользователя) прокси, который требует авторизации. Значение поля Proxy-Authorization состоит из автризационных параметров, содержащих идентификационную информацию агента пользователя для прокси и/или области (realm) запрошенного ресурса.
Proxy-Authorization = "Proxy-Authorization" ":" credentials
Процесс авторизации доступа HTTP описан в разделе 10. В отличие от Authorization, поле заголовка Proxy-Authorization применимо только к следующему внешнему прокси, который требует авторизации с помощью поля Proxy-Authenticate. Когда работает несколько прокси, объединенных в цепочку, поле заголовка Proxy-Authorization используется первым внешним прокси, который предполагает получение авторизационных параметров. Прокси может передать эти параметры из запроса клиента следующему прокси, если существует механизм совместной авторизации при обслуживании данного запроса.
13.35. Поле Public
Поле заголовка отклика Public содержит список методов, поддерживаемых сервером. Задачей этого поля является информирование получателя о возможностях сервера в отношении необычных методов. Перечисленные методы могут быть, а могут и не быть применимыми к Request-URI. Поле заголовка Allow (раздел 13.7) служит для указания методов, разрешенных для данного URI.
Public | = "Public" ":" 1#method |
Пример использования:
Public: OPTIONS, MGET, MHEAD, GET, HEAD
Это поле заголовка применяется для серверов, непосредственно соединенных с клиентом, (т.е., ближайших соседей в цепи соединения). Если отклик проходит через прокси, последний должен либо удалить поле заголовка Public или заменить его полем, характеризующим его собственные возможности.
13.36. Фрагмент
13.36.1. Фрагменты байт
Так как все объекты HTTP в процессе передачи представляют собой последовательности байт, концепция фрагментов является существенной для любого объекта HTTP. Однако не все клиенты и серверы нуждаются в поддержке операций с фрагментами.
Спецификации байтовых фрагментов в HTTP относятся к последовательностям байт в теле объекта не обязательно то же самое что и тело сообщения.
Операция с байтовыми фрагментами может относиться к одному набору байт или к нескольким таким наборам в пределах одного объекта.
ranges-specifier | = byte-ranges-specifier |
byte-ranges-specifier | = byte-sunit "=" byte-range-set |
byte-range-set |
= 1#( byte-range-spec | suffix-byte-range-spec ) |
byte-range-spec |
= first-byte-pos "-" [last-byte-pos] |
first-byte-pos | = 1*DIGIT |
last-byte-pos | = 1*DIGIT |
Значение first-byte-pos в спецификации byte-range-spec указывает на относительное положение первого байта фрагмента. Значение last-byte-pos определяет относительное положение последнего байта фрагмента. Относительное положение начального байта равно нулю.
Если присутствует значение last-byte-pos, оно должно быть больше или равно значению first-byte-pos в спецификации byte-range-spec, в противном случае спецификация byte-range-spec не корректна. Получатель некорректной спецификации byte-range-spec должен ее игнорировать.
Если значение last-byte-pos отсутствует, или если значение больше или равно текущей длине тела объекта, значение last-byte-pos берется на единицу меньше текущего значения длины тела объекта в байтах.
При выборе last-byte-pos, клиент может ограничить число копируемых байт, если не известна длина объекта.
suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT
Спецификация suffix-byte-range-spec используется для задания суффикса тела объекта с длиной, заданной значением suffix-length. (То есть, эта форма специфицирует последние N байтов тела объекта.) Если объект короче заданной длины суффикса, то в качестве суффикса используется все тело объекта.
Примеры значений byte-ranges-specifier (предполагается, что длина тела объекта равна 10000):
Первые 500 байтов (относительные позиции 0-499, включительно): bytes=0-499
Вторые 500 байтов (относительные позиции 500-999, включительно): bytes=500-999
Последние 500 байтов (относительные позиции 9500-9999, включительно): bytes=-500
или
bytes=9500-
Первые и последние байты (байты 0 и 9999): bytes=0-0,-1
Несколько легальных, но неканонических спецификаций вторых 500 байт (относительные позиции 500-999, включительно): bytes=500-600,601-999; bytes=500-700,601-999
13.36.2. Запросы получения фрагментов
Информационные запросы HTTP, использующие условные или безусловные методы GET могут заказывать один или более субфрагментов объекта, а не целый объект, используя заголовок запроса Range:
Range | = "Range" ":" ranges-specifier |
Сервер может игнорировать заголовок Range. Однако исходные серверы HTTP/1.1 и промежуточные кэши должны поддерживать по возможности работу с фрагментами, так как Range поддерживает эффективное восстановление в случае частично неудачных пересылок больших объектов.
Если сервер поддерживает заголовки Range и специфицированный фрагмент или фрагменты подходят для данного объекта, то:
Присутствие заголовка Range в безусловном GET допускает модификацию того, что прислано. Другими словами отклик может содержать статусный код 206 (Partial Content) вместо 200 (OK).
Присутствие заголовка Range в условном GET (запрос использует If-Modified-Since, If-None-Match, If-Unmodified-Since и/или If-Match) модифицирует то, что прислано GET в случае успешного завершения при выполнении условия (TRUE). Это не влияет на отклик 304 (Not Modified), если условие не выполнено (FALSE).
В некоторых случаях более удобно использовать заголовок If-Range (см. раздел 13.27).
Если прокси, который поддерживает фрагменты, получает запрос Range, переадресует запрос внешнему серверу и получает в ответ весь объект, ему следует прислать запрашиваемый фрагмент клиенту.
Он должен запомнить весь полученный отклик в своем кэше, если отклик совместим с политикой записи в его кэш.
13.37. Поле Referer
Поле заголовка запроса Referer позволяет клиенту специфицировать (для пользы сервера) адрес (URI) ресурса, из которого был получен Request-URI. Заголовок запроса Referer позволяет серверу генерировать список обратных связей с ресурсами для интереса, ведения дневника, оптимизации кэширования и т.д.. Он позволяет также заставить работать устаревшие или дефектные связи. Поле Referer не должно посылаться, если Request-URI был получен от источника, который не имеет своего собственного URI, такого, например, как ввод с пользовательского терминала.
Referer | = "Referer" ":" ( absoluteURI | relativeURI ) |
Пример:
Referer: http://www.w3.org/hypertext/DataSources/Overview.html
Если значением поля является частичный URI, его следует интерпретировать относительно Request-URI. URI не должен включать фрагментов.
Замечание. Так как первоисточник связи может быть конфиденциальной информацией или может раскрывать другой источник частной информации, настоятельно рекомендуется, чтобы пользователь имел возможность решать, посылать поле Referer или нет. Например, клиент-броузер может иметь кнопку-переключатель для открытого или анонимного просмотра, которая управляет активацией/дезактивацией посылки информации Referer и From.
13.38. Поле Retry-After
Поле заголовка отклика Retry-After может использоваться с кодом статуса 503 (Service Unavailable) с тем, чтобы указать, как еще долго данная услуга предполагается быть недоступной для запрашивающего клиента. Значением этого поля может быть либо дата HTTP либо целое число секунд (в десятичном исчислении) после отправки отклика.
Retry-After | = "Retry-After" ":" ( HTTP-date | delta-seconds ) |
Два примера использования поля
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120
В последнем примере задержка равна двум минутам.
13.39. Поле Server
Поле заголовка отклика Server содержит информацию о программном обеспечении, используемым исходным сервером для обработки запросов.
Поле может содержать коды многих продуктов (раздел 2.8), комментарии, идентифицирующие сервер, и некоторые важные субпродукты. Коды программных продуктов перечисляются в порядке важности приложений.
Server | = "Server" ":" 1*( product | comment ) |
Например:
Server: CERN/3.0 libwww/2.17
Если отклик переадресуется через прокси, приложение прокси не должно модифицировать заголовок отклика сервера. Вместо этого ему следует включить в отклик поле Via (как это описано в разделе 13.44).
Замечание. Раскрытие конкретной версии программного обеспечения сервера может облегчить атаки против программных продуктов, для которых известны уязвимые места. Разработчикам серверов рекомендуется сделать это поле конфигурируемой опцией.
13.40. Поле Transfer-Encoding (Транспортное кодирование)
Поле общего заголовка Transfer-Encoding указывает, какой тип преобразования (если таковое использовано) применен к телу сообщения, для того чтобы безопасно осуществить передачу между отправителем и получателем. Это поле отличается от Content-Encoding тем, что транспортное кодирование является параметром сообщения, а не объекта.
Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding
Транспортное кодирование определено в разделе 2.6. Например:
Transfer-Encoding: chunked
Многие старые приложения HTTP/1.0 не воспринимают заголовок Transfer-Encoding.
13.41. Заголовок Upgrade (Актуализация)
Общий заголовок Upgrade позволяет клиенту специфицировать то, какие дополнительные коммуникационные протоколы он поддерживает и хотел бы использовать, если сервер найдет их подходящими. Сервер должен использовать поле заголовка Upgrade в отклике 101 (Switching Protocols) для указания того, какие протоколы активны.
Upgrade | = "Upgrade" ":" 1#product |
Например:,
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
Поле заголовка Upgrade предназначено для обеспечения простого механизма перехода от протокола HTTP/1.1 к некоторым другим. Это достигается путем разрешения клиенту объявлять о намерении использовать другой протокол, например, более позднюю версию HTTP с большим старшим кодом версии, даже если текущий запрос выполнен с использованием HTTP/1.1.
Это облегчает переходы между несовместимыми протоколами за счет разрешения клиенту инициировать запрос в более широко поддерживаемом протоколе, в то же время, указывая серверу, что он предпочел бы использовать протокол "получше", если таковой доступен (где слово "получше" определяется сервером, возможно согласно природы метода и/или запрашиваемого ресурса).
Поле заголовка Upgrade воздействует только на переключающий протокол прикладного уровня транспортного слоя существующег соединения. Upgrade не может быть использовано для требования изменения протокола, его восприятие и использование сервером является опционным. Совместимость и природа прикладного уровня коммуникаций после смены протокола зависит исключительно от нового выбранного протокола, хотя первым действием после такой замены должен быть отклик на исходный запрос HTTP, содержащий поле заголовка Upgrade.
Поле Upgrade применимо только к текущему соединению. Следовательно, ключевое слово upgrade должно содержаться в поле заголовка Connection (раздел 13.10) всякий раз, когда поле Upgrade присутствует в сообщении HTTP/1.1.
Поле заголовка Upgrade не может использоваться для указания смены протокола в другом соединении. Для этой цели более приемлемы отклики переадресации с кодами 301, 302, 303 или 305.
Эта спецификация определяет протокол с именем "HTTP" при работе с семейством протоколов для передачи гипертекста (Hypertext Transfer Protocols), как это определено в правилах работы с версиями HTTP раздела 2.1 и для будущих усовершенствований этой спецификации. В качестве имени протокола может использоваться любая лексема, однако она будет работать, только если клиент и сервер ассоциируют это имя с одним и тем же протоколом.
13.42. Поле User-Agent (Агент пользователя)
Поле заголовка отклика User-Agent содержит информацию об агенте пользователя, инициировавшем запрос. Это нужно для целей сбора статистических данных, отслеживания нарушений протокола и автоматического распознавания агентов пользователя.
Агентам пользователя рекомендуется включать это поле в запросы. Поле может содержать несколько кодов продуктов (раздел 2.8), комментарии, идентифицирующие агента и любые субпродукты, которые образуют существенную часть агента пользователя. Согласно договоренности коды программных продуктов перечисляются в порядке их важности для идентифицируемого приложения.
User-Agent |
= "User-Agent" ":" 1*( product | comment ) |
Например:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
13.43. Поле Vary
Поле заголовка отклика Vary используется сервером для того, чтобы сигнализировать о том, что отклик выбран из числа имеющихся представлений с помощью механизма согласования под управлением сервера (раздел 11). Имена полей, перечисленные в заголовках Vary, являются такими заголовками запроса. Значение поля Vary указывает на то, что данный набор полей заголовка ограничивает пределы, в которых могут варьироваться представления, или что пределы вариации не специфицированы ("*") и, таким образом, могут модифицироваться в широких пределах для будущих запросов.
Vary | = "Vary" ":" ( "*" | 1#field-name ) |
Сервер HTTP/1.1 должен включать соответствующее поле заголовка Vary в любой кэшируемый отклик, который является субъектом, управляющим процессом согласования. Такая схема позволяет кэшу правильно интерпретировать будущие запросы к заданному ресурсу и информирует пользователя о согласовании доступа к ресурсу. Серверу следует включить соответствующее поле заголовка Vary в некэшируемый отклик, который является субъектом, управляющим согласованием, так как это может предоставить агенту пользователя полезную информацию о пределах вариации отклика.
Набор полей заголовка, перечисленных в поле Vary известен как "выбирающие" заголовки запроса.
Когда кэш получает последующий запрос, чей Request-URI специфицирует одну или более записей кэша, включая заголовок Vary, кэш не должен использовать такую запись для формирования отклика на новый запрос.
Он это должен делать, если только все заголовки, перечисленные в кэшированном заголовке Vary, присутствуют в новом запросе и все заголовки отбора предшествующих запросов совпадают с соответствующими заголовками нового запроса.
Сортирующие заголовки от двух запросов считаются соответствующими, тогда и только тогда, когда сортирующие заголовки первого запроса могут быть преобразованы в сортирующие заголовки второго запроса с помощью добавления или удаления строчных пробелов LWS (Linear White Space) в местах, где это допускается соответствующими правилами BNF (Backus-Naur Form) и/или, комбинируя несколько полей заголовка согласно требованиям на построение сообщения из раздела 3.2.
Vary "*" означает, что не специфицированные параметры, возможно отличающиеся от содержащихся в полях заголовка (напр., сетевой адрес клиента), играют роль при выборе представления отклика. Последующие запросы данного ресурса могут быть правильно интерпретированы только исходным сервером, а кэш должен переадресовать запрос (возможно условно), даже когда он имеет свежий кэшированный отклик для данного ресурса. Об использовании заголовка кэшами см. раздел 12.6.
Значение поля Vary, состоящее из списка имен полей сигнализирует о том, что представление, выбранное для отклика, базируется на алгоритме выбора, который рассматривает только значения перечисленные в поле заголовка запроса. Кэш может предполагать, что тот же выбор будет сделан для будущих запросов с теми же значениями имен полей, для периода времени, в течение которого отклик остается свежим.
Имена полей не ограничены набором стандартных полей заголовков запросов, определенных в данной спецификации. Имена полей могут быть записаны строчными или прописными буквами.
13.44. Поле Via
Поле общего заголовка Via должно быть использовано шлюзами или прокси для указания промежуточных протоколов и получателей на пути от агента пользователя к серверу, которому адресован запрос, и между исходным сервером и клиентом в случае отклика.
Это аналогично полю "Received" документа RFC 822 и предназначено для использования при трассировке переадресаций сообщений, исключения петель запроса и идентификации протокольных возможностей всех отправителей вдоль цепочки запрос/отклик.
Via | = "Via" ":" 1#( received-protocol received-by [ comment ] ) |
received-protocol |
= [ protocol-name "/" ] protocol-version |
protocol-name | = token |
protocol-version | = token |
received-by | = ( host [ ":" port ] ) | pseudonym |
pseudonym | = token |
Запись "received-protocol" указывает версию протокола в сообщении, полученном сервером или клиентом вдоль цепочки запрос/отклик. Версия received-protocol добавляется к значению поля Via, когда сообщение переадресуется, так что информация о возможностях протоколов предыдущих приложений остается прозрачной для всех получателей.
Запись "protocol-name" является опционной, тогда и только тогда, когда это "HTTP". Поле "received-by" обычно соответствует ЭВМ и номеру порта сервера получателя или клиента, который переадресует сообщение. Однако, если настоящее имя ЭВМ считается конфиденциальной информацией, оно может быть заменено псевдонимом. Если номер порта не задан, можно предполагать, что используется значение по умолчанию для данного протокола (received-protocol).
Значения поля Via представляет каждый прокси или шлюз, который переадресовывал сообщение. Каждый получатель должен присоединить свою информацию так, что конечный результат оказывается упорядоченным согласно последовательности переадресующих приложений.
Комментарии могут быть использованы в поле заголовка Via для идентификации программ получателя прокси или шлюза аналогично полям User-Agent и Server header. Однако, все комментарии в поле Via являются опционными и могут быть удалены любым получателем перед тем, как переадресовать сообщение.
Например, сообщение-запрос может быть послано от агента пользователя HTTP/1.0 программе внутреннего прокси с именем "fred", которая использует HTTP/1.1 для того, чтобы переадресовать запрос общедоступному прокси с именем nowhere.com, который завершает процесс переадресации запроса исходному серверу www.ics.uci.edu.
Запрос, полученный www.ics.uci. edu будет тогда иметь следующее поле заголовка Via:
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Прокси и шлюзы, используемые как средства сетевой защиты (firewall) не должны по умолчанию переадресовывать имена ЭВМ и портов в пределах области firewall. Эта информация может передаваться, если это непосредственно позволено. Если это не разрешено, запись "received-by" для ЭВМ в зоне действия firewall должна быть заменена соответствующим псевдонимом.
Для организаций, которые имеют жесткие требования к защите конфиденциальности и сокрытию внутренней структуры, прокси может комбинировать субпоследовательность поля заголовка Via с идентичными значениями "received-protocol" в единую запись. Например,
Via: 1.0 vanya, 1.1 manya, 1.1 dunya, 1.0 sonya
Приложениям не следует комбинировать несколько записей, если они только не находятся под единым административным контролем и имена ЭВМ уже заменены на псевдонимы. Приложения не должны комбинировать записи, которые имеют различные значения "received-protocol".
13.45. Поле Warning (Предупреждение)
Поле заголовка отклика Warning используется для переноса дополнительной информации о состоянии отклика, которая может отражать статусный код. Эта информация обычно служит для предупреждения о возможной потере семантической прозрачности из-за операций кэширования. Заголовки Warning посылаются с откликами, используя:
Warning |
= "Warning" ":" 1#warning-value |
warning-value | = warn-code SP warn-agent SP warn-text |
warn-code | = 2DIGIT |
warn-agent | = ( host [ ":" port ] ) | pseudonym |
; имя или псевдоним сервера, добавившего заголовок Warning, предназначенный для целей отладки
warn-text | = quoted-string |
Отклик может нести в себе более одного заголовка Warning.
Запись warn-text производится на естественном языке и с применением символьного набора, приемлемого для принимающего отклик лица. Это решение может базироваться на какой-то имеющейся информации, такой как положение кэша или пользователя, поле запроса Accept-Language, поле отклика Content-Language и т.д.
Языком по умолчанию является английский, а символьным набором - ISO-8859-1.
Если используется символьный набор отличный от ISO-8859-1, он должен быть закодирован в warn-text с использованием метода, описанного в RFC-1522 [14].
Любой сервер или кэш может добавить заголовки Warning к отклику. Новые заголовки Warning должны добавляться после любых существующих заголовков Warning. Кэш не должен уничтожать какие-либо заголовки, которые он получил в отклике. Однако, если кэш успешно перепроверил запись, ему следует удалить все заголовки Warning, присоединенные ранее, за исключением специальных кодов Warning. Он должен добавить к записи новые заголовки Warning, полученные с откликом перепроверки. Другими словами заголовками Warning являются те, которые были бы получены в отклике на запрос в данный момент.
Когда к отклику подключено несколько заголовков Warning, агенту пользователя следует отображать их столько, сколько возможно, для того чтобы они появились в отклике. Если невозможно отобразить все предупреждения, агент пользователя должен следовать следующим эвристическим правилам:
Предупреждения, которые появляются в отклике раньше, имеют приоритет перед теми, что появляются позже.
Предупреждения, с предпочитаемым пользователем символьным набором имеют приоритет перед предупреждениями с другими наборами, но с идентичными warn-codes и warn-agents.
Системы, которые генерируют несколько заголовков Warning, должны упорядочить их с учетом ожидаемого поведения агента пользователя.
Далее представлен список определенных в настоящее время кодов предупреждений, каждый из которых сопровождается рекомендуемым текстом на английском языке и описанием его значения.
10 Response is stale (отклик устарел)
Должно включаться всякий раз, когда присылаемый отклик является устаревшим. Кэш может добавить это предупреждение к любому отклику, но не может удалить его до тех пор, пока не будет установлено, что отклик является свежим.
11 Revalidation failed (перепроверка пригодности неудачна)
Должно включаться, если кэш присылает устаревший отклик, потому что попытка перепроверить его пригодность не удалась, из-за невозможности достичь сервера. Кэш может добавить это предупреждение к любому отклику, но никогда не может удалить его до тех пор, пока не будет успешно проведена перепроверка пригодности отклика.
12 Disconnected operation (работа в отключенном от сети состоянии)
Следует включать, если кэш намерено отключен от остальной сети на определенный период времени.
13 Heuristic expiration (эвристическое завершение периода пригодности)
Должно включаться, если кэш эвристически выбрал время жизни больше 24 часов, а возраст отклика превышает эту величину.
14 Transformation applied (применено преобразование)
Должно добавляться промежуточным кэшем или прокси, если он использует какое-либо преобразование, изменяющее кодировку содержимого (как это специфицировано в заголовке Content-Encoding) или тип среды (как это описано в заголовке Content-Type) отклика, если только этот код предупреждения не присутствует уже в отклике.
99 Разные предупреждения
Текст предупреждения включает в себя любую информацию, которая может быть представлена человеку-оператору или может быть занесена в дневник операций. Система, получающая это предупреждение, не должна предпринимать каких-либо действий автоматически.
13.46. Поле WWW-Authenticate
Поле заголовка отклика WWW-Authenticate должно включаться в сообщения откликов со статусным кодом 401 (Unauthorized). Значение поля содержит, по крайней мере, одно требование, которое указывает на схему идентификации и параметры, применимые для Request-URI.
WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge
Процесс авторизации доступа HTTP описан в разделе 10. Агенты пользователя должны проявлять особую тщательность при разборе значения поля WWW-Authenticate, если оно содержит более одного требования, или если прислан более чем одно поле заголовка WWW-Authenticate, так как содержимое требования может само содержать список параметров идентификации, элементы которого разделены запятыми.
14. Соображения безопасности
Этот раздел предназначен для того, чтобы проинформировать разработчиков приложений, поставщиков информации и пользователей об ограничениях безопасности в HTTP/1.1, как это описано в данном документе. Обсуждение не включает определенные решения данных проблем, но рассматриваются некоторые предложения, которые могут уменьшить риск.
14.1. Аутентификация клиентов
Базовая схема идентификации не предоставляет безопасного метода идентификации пользователя, не обеспечивает она и какох-либо средств защиты объектов, которые передаются открытым текстом по используемым физическим сетям. HTTP не мешает внедрению дополнительных схем идентификации и механизмов шифрования или других мер, улучшающих безопасность системы (например, SSL или одноразовых паролей).
Наиболее серьезным дефектом базового механизма идентификации является то, что пароль пользователя передается по сети в незашифрованном виде.
Так как базовая идентификация предусматривает пересылку паролей открытым текстом, она никогда не должна использоваться (без улучшения) для работы с конфиденциальной информацией.
Обычным назначением базовой идентификации является создание информационной (справочной) среды, которая требует от пользователя его имени и пароля, например, для сбора точной статистики использования ресурсов сервера. При таком использовании предполагается, что не существует никакой опасности даже в случае неавторизованного доступа к защищенному документу. Это правильно, если сервер генерирует сам имя и пароль пользователя и не позволяет ему выбрать себе пароль самостоятельно. Опасность возникает, когда наивные пользователи часто используют один и тот же пароль, чтобы избежать необходимости внедрения многопарольной системы защиты.
Если сервер позволяет пользователям выбрать их собственный пароль, тогда возникает опасность несанкционированного доступа к документам на сервере и доступа ко всем аккаунтам пользователей, которые выбрали собственные пароли. Если пользователям разрешен выбор собственных паролей, то это означает, что сервер должен держать файлы, содержащие пароли (предположительно в зашифрованном виде).
Многие из этих паролей могут принадлежать удаленным пользователям. Собственник или администратор такой системы может помимо своей воли оказаться ответственным за нарушения безопасности сохранения информации.
Базовая идентификация уязвима также для атак поддельных серверов. Когда пользователь связывается с ЭВМ, содержащей информацию, защищенную с использованием базовой системой идентификации, может так получиться, что в действительности он соединяется с сервером-злоумышленником, целью которого является получение идентификационных параметров пользователя (например, имени и пароля). Этот тип атак не возможен при использовании идентификации с помощью дайджестов [32]. Разработчики серверов должны учитывать возможности такого рода атак со стороны ложных серверов или CGI-скриптов. В частности, очень опасно для сервера просто прерывать связь со шлюзом, так как этот шлюз может тогда использовать механизм постоянного соединения для выполнения нескольких процедур с клиентом, исполняя роль исходного сервера, так что это незаметно клиенту.
14.2. Предложение выбора схемы идентификации
Сервер HTTP/1.1 может прислать несколько требований с откликом 401 (Authenticate) и каждое требование может использовать разную схему. Порядок присылки требований соответствует шкале предпочтений сервера. Сервер должен упорядочит требования так, чтобы наиболее безопасная схема предлагалась первой. Агент пользователя должен выбрать первую понятную ему схему.
Когда сервер предлагает выбор схемы идентификации, используя заголовок WWW-Authenticate, безопасность может быть нарушена только за счет того, что злонамеренный пользователь может перехватить набор требований и попытаться идентифицировать себя, используя саму слабую схему идентификации. Таким образом, упорядочение служит более для защиты идентификационных параметров пользователя, чем для защиты информации на сервере.
Возможна атака MITM (man-in-the-middle - "человек в середине"), которая заключается в добавлении слабой схемы идентификации к списку выбора в надежде на то, что клиент выберет именно ее и раскроет свой пароль.
По этой причине клиент должен всегда использовать наиболее строгую схему идентификации из предлагаемого списка.
Еще эффективнее может быть MITM-атака, при которой удаляется весь список предлагаемых схем идентификации, и вставляется вызов, требующий базовой схемы идентификации. По этой причине агенты пользователя, обеспокоенные таким видом атак, могут запомнить самую строгую схему идентификации, которая когда-либо запрашивалась данным сервером, и выдавать предупреждение, которое потребует подтверждения пользователя при использовании более слабой схемы идентификации. Особенно хитроумный способ реализации MITM-атаки является предложение услуг "свободного" кэширования для доверчивых пользователей.
14.3. Злоупотребление служебными (Log) записями сервера
Сервер должен оберегать информацию о запросах пользователя, о характере его интересов (такая информация доступна в дневнике операций сервера). Эта информация является, очевидно, конфиденциальной по своей природе и работа с ней во многих странах ограничена законом. Люди, использующие протокол HTTP для получения данных, являются ответственными за то, чтобы эта информация не распространялась без разрешения лиц, кого эта информация касается.
14.4. Передача конфиденциальной информации
Подобно любому общему протоколу передачи данных, HTTP не может регулировать содержимое передаваемых данных, не существует методов определения степени конфиденциальности конкретного фрагмента данных в пределах контекста запроса. Следовательно, приложения должны предоставлять как можно больше контроля провайдеру информации. Четыре поля заголовка представляют интерес с этой точки зрения: Server, Via, Referer и From. Раскрытие версии программного обеспечения сервера может привести к большей уязвимости машины сервера к атакам на программы с известными слабостями. Разработчики должны сделать поле заголовка Server конфигурируемой опцией. Прокси, которые служат в качестве сетевого firewall, должны предпринимать специальные предосторожности в отношении передачи информации заголовков, идентифицирующей ЭВМ, за пределы firewall.
В частности они должны удалять или замещать любые поля Via, созданные в пределах firewall. Хотя поле Referer может быть очень полезным, его мощь может быть использована во вред, если данные о пользователе не отделены от другой информации, содержащейся в этом поле. Даже когда персональная информация удалена, поле Referer может указывать на URI частных документов, чья публикация нежелательна. Информация, посланная в поле From, может вступать в конфликт с интересами конфиденциальности пользователя или с политикой безопасности его домена, и, следовательно, она не должна пересылаться и модифицироваться без прямого разрешения пользователя. Пользователь должен быть способен установить содержимое этого поля, в противном случае оно будет установлено равным значению по умолчанию. Мы предлагаем, хотя и не требуем, чтобы предоставлялся удобный интерфейс для пользователя, который позволяет активировать и дезактивировать посылку информации полей From и Referer.
14.5. Атаки, основанные на именах файлов и проходов
Реализации исходных серверов HTTP должна быть тщательной, чтобы ограничить список присылаемых HTTP документов теми, которые определены для этого администратором сервера. Если сервер HTTP транслирует HTTP URI непосредственно в запросы к файловой системе, сервер должен следить за тем, чтобы не пересылать файлы клиентам HTTP, для этого не предназначенные. Например, UNIX, Microsoft Windows и другие операционные системы используют ".." как компоненту прохода, чтобы указать уровень каталога выше текущего. В такой системе сервер HTTP должен запретить любую подобную в Request-URI, если она позволяет доступ к ресурсу за пределами того, что предполагалось. Аналогично, файлы, предназначенные только для внутреннего использования сервером (такие как файлы управления доступом, конфигурационные файлы и коды скриптов) должны быть защищены от несанкционированного доступа, так как они могут содержать конфиденциальную информацию. Практика показала, что даже незначительные ошибки в реализации сервера HTTP могут привести к рискам безопасности.
14.6. Персональная информация
Клиентам HTTP небезразличнен доступ к некоторым данным (например, к имени пользователя, IP-адресу, почтовому адресу, паролю, ключу шифрования и т.д.). Система должна быть тщательно сконструирована, чтобы предотвратить непреднамеренную утечку информации через протокол HTTP. Мы настоятельно рекомендуем, чтобы был создан удобный интерфейс для обеспечения пользователя возможностями управления распространением такой информации.
14.7. Аспекты конфиденциальности, связанные с заголовками Accept
Заголовок запроса Accept может раскрыть информацию о пользователе всем серверам, к которым имеется доступ. В частности, заголовок Accept-Language может раскрыть информацию, которую пользователь, возможно, рассматривает как конфиденциальную. Так, например, понимание определенного языка часто строго коррелируется с принадлежностью к определенной этнической группе. Агентам пользователя, которые предлагают возможность конфигурирования содержимого заголовка Accept-Language, настоятельно рекомендуется посылать сообщение пользователю о том, что в результате может быть потеряна конфиденциальность определенных данных. Подходом, который ограничивает потерю конфиденциальности для агента пользователя, может быть отказ от посылки заголовков Accept-Language по умолчанию. Предполагается при этом каждый раз консультироваться с пользователем относительно возможности посылки этих данных серверу. Пользователь будет принимать решение о посылке Accept-Language, лишь убедившись на основании содержимого заголовка отклика Vary в том, что такая посылка существенно улучшит качество обслуживания.
Для многих пользователей, которые размещены не за прокси, сетевой адрес работающего агента пользователя может также использоваться как его идентификатор. В среде, где прокси используются для повышения уровня конфиденциальности, агенты пользователя должны быть достаточно консервативны в предоставлении опционного конфигурирования заголовков доступа конечным пользователям. В качестве крайней меры обеспечения защиты прокси могут фильтровать заголовки доступа для передаваемых запросов.
Главной целью агентов пользователя, которые предоставляют высокий уровень конфигурационных возможностей, должно быть предупреждение пользователя о возможной потере конфиденциальности.
14.8. Фальсификация DNS
Клиенты, интенсивно использующие HTTP обмен со службой имен домена (Domain Name Service), обычно предрасположены к атакам, базирующимся на преднамеренном некорректном соответствии IP адресов и DNS имен. Клиенты должны быть осторожны относительно предположений, связанных с ассоциаций IP адресов и DNS имен.
В частности, клиенту HTTP следует полагаться на его сервер имен для подтверждения соответствия IP адресов и DNS имен, а не слепо кэшировать результаты предшествующих запросов. Многие платформы могут кэшировать такие запросы локально и это надо использовать, конфигурируя их соответствующим образом. Такие запросы должны кэшироваться, однако только на период, пока не истекло время жизни этой информации.
Если клиенты HTTP кэшируют результат DNS-запроса для улучшения рабочих характеристик, они должны отслеживать пригодность этих данных с учетом времени жизни, объявляемого DNS-сервером.
Если клиенты HTTP не следуют этому правилу, они могут быть мистифицированы, когда изменится IP-адрес доступного ранее сервера. Так как смена адресов в сетях будет в ближайшее время активно развиваться (Ipv6 !), такого рода атаки становятся все более вероятными.
Данное требование улучшает работу клиентов, в том числе с серверами, имеющими идентичные имена.
14.9. Заголовки Location и мистификация
Если один сервер поддерживает несколько организаций, которые не доверяют друг другу, тогда он должен проверять значения заголовков Location и Content-Location в откликах, которые формируются под управлением этих организаций. Это следует делать, чтобы быть уверенным, что они не пытаются провести какие-либо операции над ресурсами, доступ к которым для них ограничен.
15. Библиография
[1] |
Alvestrand, H., "Tags for the identification of languages", RFC 1766, UNINETT, March 1995. |
[2] |
Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey, D., and B. Alberti. "The Internet Gopher Protocol: (a distributed document search and retrieval protocol)", RFC 1436, University of Minnesota, March 1993 |
[3] |
Berners-Lee, T., "Universal Resource Identifiers in WWW", A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the World-Wide Web", RFC 1630, CERN, June 1994 |
[4] |
Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, CERN, Xerox PARC, University of Minnesota, December 1994 |
[5] |
Berners-Lee, T., and D. Connolly, "HyperText Markup Language Specification - 2.0", RFC 1866, MIT/LCS, November 1995 |
[6] |
Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0.", RFC 1945 MIT/LCS, UC Irvine, May 1996 |
[7] |
Freed, N., and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, Innosoft, First Virtual, November 1996. |
[8] |
Braden, R., "Requirements for Internet hosts - application and support", STD3, RFC 1123, IETF, October 1989 |
[9] |
Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, UDEL, August 1982 |
[10] |
Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R., Sui, J., and M. Grinbaum. "WAIS Interface Protocol Prototype Functional Specification", (v1.5), Thinking Machines Corporation, April 1990 |
[11] |
Fielding, R., "Relative Uniform Resource Locators", RFC 1808, UC Irvine, June 1995 |
[12] |
Horton, M., and R. Adams. "Standard for interchange of USENET messages", RFC 1036, AT&T Bell Laboratories, Center for Seismic Studies, December 1987 |
[13] |
Kantor, B., and P. Lapsley. "Network News Transfer Protocol." A Proposed Standard for the Stream-Based Transmission of News", RFC 977, UC San Diego, UC Berkeley, February 1986 |
[14] |
Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, University of Tennessee, November 1996 |
[15] |
Nebel, E., and L. Masinter. "Form-based File Upload in HTML", RFC 1867, Xerox Corporation, November 1995. |
[16] |
Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, USC/ISI, August 1982 |
[17] |
Postel, J., "Media Type Registration Procedure", RFC 2048, USC/ISI, November 1996 |
[18] |
Postel, J., and J. Reynolds, "File Transfer Protocol (FTP)", STD 9, RFC 959, USC/ISI, October 1985 |
[19] |
Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC1700, USC/ISI, October 1994 |
[20] |
Sollins, K., and L. Masinter, "Functional Requirements for Uniform Resource Names", RFC 1737, MIT/LCS, Xerox Corporation, December 1994 |
[21] |
US-ASCII. Coded Character Set - 7-Bit American Standard Code for Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986 |
[22] |
ISO-8859. International Standard -- Information Processing -- 8-bit Single-Byte Coded Graphic Character Sets |
|
Part 1: Latin alphabet No. 1, ISO 8859-1:1987 |
|
Part 2: Latin alphabet No. 2, ISO 8859-2, 1987 |
|
Part 3: Latin alphabet No. 3, ISO 8859-3, 1988 |
|
Part 4: Latin alphabet No. 4, ISO 8859-4, 1988 |
|
Part 5: Latin/Cyrillic alphabet, ISO 8859-5, 1988 |
|
Part 6: Latin/Arabic alphabet, ISO 8859-6, 1987 |
|
Part 7: Latin/Greek alphabet, ISO 8859-7, 1987 |
|
Part 8: Latin/Hebrew alphabet, ISO 8859-8, 1988 |
|
Part 9: Latin alphabet No. 5, ISO 8859-9, 1990 |
[23] |
Meyers, J., and M. Rose "The Content-MD5 Header Field", RFC1864, Carnegie Mellon, Dover Beach Consulting, October, 1995 |
[24] |
Carpenter, B., and Y. Rekhter, "Renumbering Needs Work", RFC 1900, IAB, February 1996. |
[25] |
Deutsch, P., "GZIP file format specification version 4.3." RFC1952, Aladdin Enterprises, May 1996 |
[26] |
Venkata N. Padmanabhan and Jeffrey C. Mogul. Improving HTTP Latency. Computer Networks and ISDN Systems, v. 28, pp. 25-35, Dec. 1995. Slightly revised version of paper in Proc. 2nd International WWW Conf. '94: Mosaic and the Web, Oct. 1994, which is available at http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/ mogul/HTTPLatency.html. |
[27] |
Joe Touch, John Heidemann, and Katia Obraczka, "Analysis of HTTP Performance", , USC/Information Sciences Institute, June 1996 |
[28] |
Mills, D., "Network Time Protocol, Version 3, Specification, Implementation and Analysis", RFC 1305, University of Delaware, March 1992 |
[29] |
Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3." RFC 1951, Aladdin Enterprises, May 1996 |
[30] |
Spero, S., "Analysis of HTTP Performance Problems" . |
[31] |
Deutsch, P., and J-L. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, Aladdin Enterprises, Info-ZIP, May 1996 |
[32] |
Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., Luotonen, A., Sink, E., and L. Stewart, "An Extension to HTTP : Digest Access Authentication", RFC 2069, January 1997 |
Ориентация таблиц
Ориентация таблиц определяется атрибутом dir элемента table. Для таблиц, ориентированных слева направо (ориентация по умолчанию), первая колонка расположена слева, а первый ряд сверху. Возможна ориентация таблицы справа налево. Для того чтобы специфицировать таблицу с нумерацией колонок справа налево нужно установить значение атрибута dir.
<table dir="rtl">
… содержимое таблицы …
</table>
Ориентированные и неориентированные сети
Общий метод преобразования неориентированного ребра в пару противоположно ориентированных ребер проиллюстрирован на рис. 2. Этот подход широко применяется в задачах сетевой надежности.
Теорема 2.1. Пусть дан неориентированный граф G=(V,E), заданы вероятности разрыва ребер, их функция распределение по длинам {lе,i, pе,i } или по пропускной способности {се,i, pе,i}. Применяя схему на рисунке 2 к каждому ребру исходного графа, получен ориентированный граф Gў=(V,A), надежность ориентированных дуг равна pa, а распределение по длинам {la,i, pa,i} или по пропускной способности {сa,i, pa,i}. Если эти параметры окажутся равными соответствующим параметрам неориентированного графа, тогда справедливо:
Rel(G,s,K,p) = Rel(Gў,s,K,{pa})
FT(G,s,t,{се,i},{ pе,i},fthresh) = FT(Gў,s,t,{сa,i}, {pa,i},fthresh)
ST(G,s,t,{dе,i }, { pе,i},lthresh) = FT(Gў,s,t,{da,i}, {pa,i},lthresh)
FE(G,s,t,{се,i}, {pе,i }) = FT(Gў,s,t,{сa,i}, {pa,i})
SE(G,s,t,{dе,i}, {pе,i}) = FT(Gў,s,t,{da,i}, {pa,i})
Рис. 2. Преобразование неориентированных графов в диграфы.
Рассмотренное преобразование идентично тем преобразованиям, что применяются для сетевых потоков. Теорема 2.1 дает нам право трактовать состояния антипараллельной пары дуг, как пару независящих друг от друга случайных величин, в то время как их состояния не являются независимыми. Полученные соотношения могут не выполняться, если рассматривать более сложные меры работоспособности.
Основные определения
Из-за отсутствия приемлемой модели механизма потерь в сети и присущей сложности расчета сетевой надежности используются времязависимые модели с дискретной вероятностью. В статье мы рассмотрим наиболее популярную модель, в ней предполагается, что сетевые компоненты (узлы и ребра на языке графов) могут принимать лишь два состояния: работает или не работает. Состояние сетевого компонента - случайная величина, не зависящая от состояния других компонентов (в общем случае это может быть и не так). Постановка задачи вычисления надежности: для каждого компонента сети задана вероятность того, что он находится в рабочем состоянии, требуется вычислить меру надежности сети. Рассмотрим некое обобщение этой модели. В частности, будем рассматривать модели, в которых каждый компонент может находиться в одном из нескольких состояний, или модели, в которых рабочее состояние характеризуется численным значением. Численные значения этих характеристик обычно приравниваются метрике расстояния или величине пропускной способности. Простая модель с двумя состояниями хорошо подходит для вычисления меры связанности. Когда возникает необходимость посчитать более сложную меру, например производительность системы, применяют более сложные характеристики состояний компонентов.
Для модели с двумя состояниями вероятность работоспособности компонента или, проще надежность, можно понимать по-разному. Наиболее распространенными являются формулировки:
1. доступность компонента
2. надежность компонента
Вообще в этой главе договоримся применять термин надежность для обозначения вероятности того, что компонент или система работает. Здесь мы обсуждаем более частное определение. Доступность используется в контексте ремонтоспособных систем. Из сказанного следует, что компонент может находиться в одном из трех состояний: работает, не работает, в процессе восстановления. Доступность компонента определяется как вероятность его работы в случайный момент времени. Оценка величины доступности производится с учетом среднего времени восстановления в рабочее состояние и среднего времени в не рабочем состоянии.
Надежность можно записать:
среднее время до отказа
среднее время до отказа + среднее время восстановления.
Определение надежности компонента не учитывает время восстановления. Специфицируется промежуток времени t, а надежность компонента определяется как вероятность того, что за это время t компонент останется в рабочем состоянии. Допускаются также иные трактовки для вероятности того, что компонент работает. Конечно, интерпретация уровня надежности компонента определяет в свою очередь интерпретацию мер сетевой надежности. В оставшейся части статьи мы будем использовать вероятность работоспособности или надежности и не будем пытаться это как-либо интерпретировать.
За отправную точку примем сеть G=(V,E), в которой V - набор узлов или вершин, а Е - набор неориентированных ребер или набор ориентированных дуг. При изучении моделей связанности для каждого еОЕ мы определяем надежность е (ре) как Pr[e работает]. При изучении простых моделей потоков (кратчайших путей), мы ассоциируем пропускную способность се(расстояние dе) с каждым еОЕ. Мы интерпретируем ре, как вероятность того, что е работает и имеет пропускную способность се (расстояние dе), а 1-ре, как вероятность того, что е не работает и имеет пропускную способность 0 (расстояние равно бесконечности). При изучении моделей потоков (кратчайших путей) с множеством состояний мы ассоциируем распределение пропускной способности {cе,i, pе,i} (распределение расстояний {dе,i, pе,i}) для еОЕ. Здесь pе,i - вероятность того, что е будет иметь пропускную способность cе,i (расстояние dе,i).
Иногда, при изучении сетевой надежности, бывает удобно переходить к обобщенным случаям и рассматривать когерентные двоичные системы. Стохастическая бинарная система SBS (stochastic binary system) - представляет собой систему, которая отказывает случайным образом в результате случайного выхода из строя ее компонента. Каждый компонент из набора сетевых компонентов T может принимать одно из двух значений: работает, не работает. Структура системы описывается функцией ? (S), определенной для SНT.
? (S)=
Функция SBS является когерентной, если ?(Т)=1, ?(0)=0 и выполняется условие ?(S?)??(S) для S?ЙS. Последнее свойство означает, что выход из строя любого из компонентов может только повредить работе системы. Представляет интерес задача вычисления выражения:
Rel(SBS,p)=Pr[?(S)=1, где S - набор работающих компонентов],
если известен вид распределения ?(). Иногда мы рассматриваем задачи надежности, где ре=p для всех е, в этих случаях мы заменяем p на p в представленной выше нотации. Для произвольной стохастической когерентной двоичной системы (SCBS - stochastic coherent binary system) определим набор путей как набор компонентов, работоспособность которых означает работу системы в целом. Назовем минипроходом - минимальный набор путей, обеспечивающих работоспособность системы. Аналогично определим набор разрезов, как набор компонентов, чей отказ вызовет отказ системы, а миниразрезом назовем минимальный набор таких разрезов.
Особенности sgml с ограниченной поддержкой
Системы SGML, соответствующие ISO-8879, должны поддерживать определенное число возможностей, которые не слишком широко поддерживаются агентами пользователя HTML. Разработчикам рекомендуется не использовать все эти возможности.
Отказы узлов
Во многих приложениях могут отказывать как дуги, так и узлы. Следовательно, приходится изучать модели, способные реагировать и на отказы узлов и на обрывы дуг. К счастью, для случая ориентированных сетей с помощью преобразования, показанного на рисунке 3, задачу с ненадежными ребрами и узлами можно свести к задаче с абсолютно надежными узлами и ненадежными ребрами. Преобразование используется для мер Rel(), FT(), ST(), FE() и SE(), где в каждом случае дуга, которая замещает узлы, наследует характеристики соответствующих узлов. При осуществлении преобразования для терминального узла i узел-заменитель i1 не должен быть терминальным, а узел-заменитель i2 должен быть терминальным. При выполнении этого преобразования для исходящего узла i нужно, чтобы i1 был исходящим, а i2 - таковым не был.
Рис. 3. Замена ненадежного узла.
Теорема 2.1 и выше представленное обсуждение указывают, что с практической точки зрения предпочтительнее коды для анализа надежности ориентированной сети по отношению к кодам для неориентированного случая. При условии тщательного подбора входных данных, ориентированные сетевые коды можно применять для анализа ориентированных и неориентированных моделей сети и задач с отказом узлов и без.
Пакеты Access-Accept
Пакеты Access-Accept посылаются сервером RADIUS, и предоставляют специфическую конфигурационную информацию, необходимую для предоставления пользователю соответствующего сервиса. Если все значения атрибутов, полученных с запросом Access-Request, приемлемы, тогда реализация RADIUS должна послать пакет с полем код=2 (Access-Accept). При получении сообщения Access-Accept, поле идентификатор соответствует обрабатываему запросу (Access-Request). Кроме того, поле аутентификатор отклика должно содержать корректный отклик на полученный запрос Access-Request. Пакеты неверного формата молча отбрасываются. Формат пакета Access-Accept идентичен показанному на рис. .1. Но здесь вместо поля аутентификатор используется поле аутентификатор отклика, имеющее тот же размер. В поле код при этом записывается число 2.
Поле идентификатор является копией одноименного поля в запросе Access-Request, который инициировал сообщение Access-Accept.
Значение поля аутентификатор отклика (Response Authenticator) вычисляется на основе значения Access-Request, как это описано выше. Поле атрибуты имеет переменную длину и содержит список из нуля или более атрибутов.
Параграфы и элемент p
<! element p - o (%inline) *>
<!attlist p %attrs; | -- %coreattrs, %i18n, %events |
| %align; | -- выравнивание текста -- > |
P-элемент отмечает границы параграфа и не может содержать элементов блочного уровня, включая другие Р-элементы. Конечная метка может быть опущена, при этом любой элемент блочного уровня будет являться начальной меткой и конечной меткой Р-элемента. Например:
<p>Это первый параграф.</p>
<p>Это второй </p>
… блочный элемент …
Этот же текст можно переписать эквивалентным образом:
<p>Это первый параграф.
<p>Это второй.
…блочный элемент …
Аналогично параграф может быть сформирован с помощью блочных элементов:
<div>
<p> Это параграф
</div>
Пустой параграф является дурным стилем и должен игнорироваться агентом пользователя. Агент пользователя определяет способ отображения параграфа. Параграфы могут иметь абзацы, а могут отделяться друг от друга пустой строкой. Обычно в процессе отображения строки разрываются по пробелам между словами, но можно ввести принудительные разрывы строк с помощью элемента BR.
9.5. Элемент br
<!element br - o empty | -- вызывает разрыв строки -- > |
<!attlist br %coreattrs; | -- id, class, style, title -- |
| clear (left|all|right|none) none | -- управление отображением текста -- > |
Для визуального агента пользователя атрибут clear может использоваться для позиционирования плавающих объектов (напр. обтекание текстом изображений). Этот атрибут используется в случае отсутствия стилей.
Помимо принудительного разрыва строки существует элемент, запрещающий разрыв строки между двумя словами. Например entity ( ,  ) действует как пробел, где агент пользователя не должен разрывать строку.
В HTML существует два вида дефисов: мягкий и твердый. Твердый рассматривается как обычный символ, а мягкий воспринимается агентом пользователя как место, где можно разорвать строку. Твердый дефис обозначается символом "-" (-,-), а мягкий - именованным символом ­ (,­).
9.6. Предварительно сформатированный текст. Элемент pre.
<!entity % pre.exclusion "img|big|small|sub|sup|font">
<!element pre - - (%inline) * - (%pre.exclusion)>
<!attlist pre %attrs; | -- %coreattrs, %i18n, %events -- |
| width number #implied > |
Определения атрибутов
width = integer
Этот атрибут дает информацию агенту пользователя о желательной ширине форматируемого блока. Агент пользователя может использовать эту информацию для выбора шрифта или отступа. Желательная ширина выражается в числе символов.
Элемент pre сообщает визуальному агенту пользователя, что данный фрагмент текста уже сформатирован. Агент пользователя при этом должен сохранить все пробелы, использовать шрифт с фиксированной шириной букв, блокировать автоматический перенос и разрыв строк. Перед и после такого фрагмента обычно вводятся пустые строки (требование SGML). В DTD-фрагменте, приведенном выше, в первой строке содержится список элементов, которые не должны присутствовать в PRE-декларации. Рассмотрим фрагмент из поэмы Шелли "to a skylark".
<pre>
| higher still and higher | |
| | from the earth thou springest |
| like a cloud of fire; | |
| | the blue deep thou wingest, |
and singing still dost soar, and soaring ever singest.
</pre>
Этот стих будет представлен агентом пользователя без изменений формата.
Не рекомендуется использовать горизонтальную табуляцию в предварительно отформатированных текстах, агент пользователя не сможет воспроизвести формат фрагмента без искажений.
10. Пометка изменений документа. Элементы ins и del.
<!element (ins|del) - - (%inline) * | -- (введенный/удаленный текст) -- > |
<!attlist (ins|del) %attrs; | -- %coreattrs, %i18n, %events -- |
| cite %url #implied | -- информация о причине изменения -- |
| datetime cdata #implied | -- дата изменения в формате ISO -- > |
Определение атрибутов
cite = URL
Значение этого атрибута равно URL, которое указывает на документ-первоисточник. Атрибут служит для пояснения причины изменения документа.
datetime = cdata
Значение этого атрибута определяет дату и время внесения изменения в документ. Формат этого значения должен соответствовать требованиям документа ISO-8601.
Элементы ins и del используются для выделения фрагментов документа, которые были добавлены или удалены из предшествующей версии документа.
Пароль пользователя
Этот атрибут указывает на пароль аутентифицируемого пользователя или на вводимые пользователем данные в ответ на Access-Challenge. Этот атрибут используется только в пакетах Access-Request.
При передаче пароль шифруется. Пароль сначала дополняется нулями до границы кратной 16 октетам. Затем согласно алгоритму MD5 вычисляется хэш-функция. Это вычисление производится для потока октетов, состоящего из о бщего секретного пароля, за которым следует аутентификатор запроса (Request Authenticator). Для полученного кода и первых 16 октетов пароля производится операция XOR. Результат кладется в первых 16 октетов поля строка атрибута пароля пользователя.
Если пароль длиннее 16 символов, вычисляется вторая хэш-функция для потока данных, включающего в себя общий секретный пароль и результат предыдущей операции XOR. Полученный результат и вторые 16 октетов пароля объединяются с помощью операции XOR, а полученный код кладется во вторые 16 октетов поля строка атрибута User-Password. Если необходимо, эта операция повторяется. Следует только иметь в виду, что поле строка не может превышать 128 символов.
Данный метод заимствован из книги "Network Security" Кауфмана, Пелмана и Спесинера [4; стр. 109-110]. Более формализовано алгоритм можно описать следующим образом:
Берется общий секретный ключ S и псевдослучайный 128-битный аутентификатор запроса RA. Пароль разбивается на 16-октетные блоки p1, p2, …, pi. последний из них дополняется нулями до размера кратного 16 октетам. Далее реализуется алгоритм MD5. Берутся блоки шифрованного текста c(1), c(2), …, c(i), получаются промежуточные значения b1, b2, … bi:
b1 = MD5(S + RA) | c(1) = p1 XOR b1 |
b2 = MD5(S + c(1)) | c(2) = p2 XOR b2 |
. | . |
. | . |
. | . |
bi = MD5(S + c(I-1)) | c(i) = pi XOR bi |
Поле строка будет содержать c(1)+c(2)+...+c(i), где знак + означает присоединение.
При получении осуществляется обратный процесс и получается исходная форма пароля. В результате формируется атрибут, где в поле тип записан код 2, в поле длина число в интервале 18-130, а в поле строка - 16-128 октетов зашифрованного пароля.
Ping и Traceroute
Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru
При работе в Интернет время от времени возникают ситуации, когда нужно определить, работоспособен ли тот или иной канал или узел, а в случае работы с динамическими протоколами маршрутизации выяснить, по какому из каналов вы в данный момент работаете. Используется эта процедура и для оценки вероятности потери пакетов в заданных сегментах сети или каналах. Для решения этих задач удобна программа Ping.
Ping - это процедура, которая базируется на IP- и ICMP-протоколах пересылки дейтограмм и служит для трассировки маршрутов и проверки работоспособности каналов и узлов (в некоторых программных пакетах эта команда имеет имена trace, hopcheck, tracert или traceroute). Для решения поставленной задачи PING использует отклики протокола ICMP (смотри также статьи о протоколах IP и ICMP). В протоколе IP имеется опция записи маршрута (RR - Record Route). В отличие от традиционной команды traceroute опция RR позволяет записать как путь от инициатора до адресата, так и обратный маршрут. К сожалению разработчики протокола предусмотрели для записи маршрута только 37 байт, сюда может поместиться максимум девять IP-адресов (определяется предельным размером поля опций). Применяется PING и при отладке сетевых продуктов. Трассировка может выполняться, например, посредством команды ping -q <Internet_адрес> (пакет PCTCP). При выполнении этой команды ЭВМ сообщит вам Internet адреса всех промежуточных узлов, их имена и время распространения отклика от указанного вами узла. Следует иметь в виду, что трассировка осуществляется непосредственно с помощью IP-протокола (опция записи адресов промежуточных узлов). Ниже приведен пример использования команды Ping. Если вы просто напечатаете команду ping (пакет PCTCP), то ЭВМ выдаст на экран справочную таблицу по использованию этой команды:
Usage:
ping [-options] host
options:
-d [bytes] |
dump input packet |
(пропечатка входных пакетов). |
-d# [bytes] |
dump output packet |
(пропечатка выходных пакетов). |
-e |
cancel extended security |
(отмена дополнительных мер безопасности) |
-i seconds |
IP time to live |
(установка времени жизни пакетов IP) |
-j dest 1...dest n |
loose source routing |
(свободная маршрутизация). |
-k dest 1...dest n |
strict source routing |
(принудительная маршрутизация). |
-l length |
set length of icmp data |
(установить длину данных для ICMP). |
-n times |
ping host times number of times |
(провести зондирование ЭВМ заданное число раз). |
-o |
no-op option |
(ни каких опций для операций). |
-p precedence |
set IP precedence |
(установка IP-предпочтения). |
-q |
trace route |
(трассировка маршрута). |
-r |
record route |
(запись маршрута). |
-s level [authority] |
basic security |
(базовый уровень безопасности). |
-t |
ping forever |
(режим бесконечного ping). |
-v type |
set type of service |
(установка типа операции). |
-w seconds |
time to wait for answer |
(установка времени ожидания ответа). |
-x [{1|3 dest1..destn}] |
timestamp option |
(опция временных меток). |
-z |
quiet mode |
(набор статистики отключен). |
<
br>
Команда трассировки маршрута ИТЭФ - сервер научно-исследовательской станции США Мак-Мурдо в Антарктиде (запись в файл route.txt):
ping -q mcmurdo-gw.mcmurdo.gov > route.txt
Содержимое файла route.txt будет иметь вид:
hop 1: |
193.124.224.190 |
??? |
имя для GW ИТЭФ пока не придумано |
hop 2: |
193.124.137.13 |
MSU-Tower.Moscow.RU.Radio-MSU.net |
Вперед, в космос |
hop 3: |
193.124.137.9 |
NPI-MSU.Moscow.RU.Radio-MSU.net |
Через спутник "Радуга" |
hop 4: |
193.124.137.6 |
DESY.Hamburg.DE.Radio-MSU.net |
пакеты совершили мягкую посадку в Гамбурге, ДЕЗИ |
hop 5: |
188.1.133.56 |
dante.WiN-IP.DFN.DE |
|
hop 6: |
193.172.4.12 |
duesseldorf2.empb.net |
|
hop 7: |
193.172.4.8 |
amsterdam6.empb.net |
|
hop 8: |
193.172.12.6 |
Amsterdam1.dante.net |
Пересекаем Атлантический океан |
hop 9: |
194.41.0.42 |
New-York1.dante.net |
вступили на землю США |
hop 10: |
192.103.63.5 |
en-0.cnss35.New-York.t3.ans.net |
|
hop 11: |
140.222.32.222 |
mf-0.cnss32.New-York.t3.ans.net |
|
hop 12: |
140.222.56.2 |
t3-1.cnss56.Washington-DC.t3.ans.net |
|
hop 13: |
140.222.145.1 |
t3-0.enss145.t3.ans.net |
|
hop 14: |
192.203.229.243 |
SURA2.NSN.NASA.GOV |
Снова в космос |
hop 15: |
128.161.166.1 |
GSFC8.NSN.NASA.GOV |
но теперь через американский |
hop 16: |
128.161.232.1 |
GSFC12.NSN.NASA.GOV |
спутник |
hop 17: |
128.161.1.1 |
ARC1NEW.NSN.NASA.GOV |
|
hop 18: |
192.203.230.2 |
ARC1.NSN.NASA.GOV |
|
hop 19: |
192.100.12.2 |
ARC2.NSN.NASA.GOV |
|
hop 20: |
128.161.115.2 |
MCMURDO.NSN.NASA.GOV |
Оденьте шапку, мы в Антарктиде! |
Target |
157.132.100.1 |
reached on hop 21 |
round-trip time 1370 ms |
Фантастика, мы пересекли туда и обратно Европу, два океана и США с востока на запад, побывали в Антарктиде и все это менее чем за полторы секунды.
Ping позволяет не только проверить работоспособность канала, но измерить ряд его характеристик, включая надежность (например, версия ping для SUN):
PING -s cernvm.cern.ch 100 64 (пакеты по 100 байт посылаются 64 раза)
108 bytes from crnvma.cern.ch (128.141.2.4): icmp_seq=0. time=606. Ms
.............. (результаты пересылки пакетов с номерами 1-61 опущены)
108 bytes from crnvma.cern.ch (128.141.2.4): icmp_seq=62. time=667. Ms
108 bytes from crnvma.cern.ch (128.141.2.4): icmp_seq=63. time=628. Ms
---- PING Statistics ----
64 packets transmitted, 63 packets received, 1% packet loss (процент потерянных пакетов)
round-trip (ms) min/avg/max = 600/626/702
Для получения большей точности следует послать большее число пакетов. В последней строке приведены результаты измерения RTT, где представлены минимальное/среднее/максимальное значения.
Наибольшее число модификаций имеет BSD-версия ping, если на вашей ЭВМ нет этой удобной программы, можно воспользоваться общедоступной версией по адресу:
(см. также приложения).
Сходную информацию позволяет получить и программа traceroute (использует непосредственно IP-пакеты):
traceroute -n cernvm.cern.ch
traceroute to crnvma.cern.ch (128.141.2.4) 30 hops max, 40 byte packets
1 193.124.224.50 3 ms 2 ms 2 ms
2 194.85.112.130 3 ms 3 ms 3 ms
3 194.67.80.5 4 ms 3 ms 3 ms
4 193.124.137.6 534 ms 534 ms 534 ms
5 188.1.56.5 545 ms 545 ms 546 ms
6 193.172.4.12 558 ms (ttl=59!) 549 ms (ttl=59!) 548 ms (ttl=59!)
7 193.172.4.30 580 ms (ttl=58!) 581 ms (ttl=58!) 581 ms (ttl=58!)
8 193.172.24.10 586 ms 585 ms 597 ms
9 192.65.185.1 593 ms 587 ms 598 ms
10 128.141.2.4 628 ms 602 ms 619 ms
При написании программ, использующих протокол ICMP, полезно воспользоваться отладочной опцией PING, которая позволяет получить на экране шестнадцатеричный образ посылаемого и получаемого пакетов:
ping -d# 300 ns.itep.ru |
(версия PCTCP, запрос отклика серверу имен, число байт, подлежащих выдаче, равно 300) |
Dump of outgoing packet
Version = 4 IP header length = 5 Precedence = Routine
Type of Service = Normal
Total length = 284 Protocol = 1 TTL = 64
45 00 01 1C 00 02 00 00 40 01 71 29 C0 94 A6 81 C1 7C E0 23 IP-заголовок
08 00 8D BD E9 03 00 01 ... ICMP-заголовок
host responding, time = 60 ms
Выдачи ради экономии места сильно сокращены. Тексты пакетов начинаются с кодов IP-версии (=4) и длины заголовка (=5), далее следует байт TOS=0, два байта длины пакета (01 1С) и т.д.
в соответствии с требованиями IP-протокола.
ping -d 300 ns.itep.ru (команда получения текста пакета-отклика на запрос)
host responding, time = 25 ms
Dump of incoming packet
Version = 4 IP header length = 5 Precedence = Routine
Type of service = Normal
Total length = 284 Protocol = 1 TTL = 254
45 00 01 1C EE 29 00 00 FE 01 C5 00 C1 7C E0 23 C0 94 A6 81
00 00 93 BD EB 03 00 01 ..............
В принципе, процедуру Ping и Traceroute можно реализовать и с привлечением протоколов UDP и TCP. Рассмотрим следующую модель реализации Traceroute <URL>:
Посылаем последовательно по адресу IP(URL) IP-пакеты со значением TTL=1, 2,... и т.д. Если до <URL> больше одного шага, соответствующий маршрутизатор, размещенный по пути следования к адресату, уничтожит посланный пакет и вернет ICMP-сообщение: Time Exceeded (тип ICMP-сообщения=11), указав при этом IP-адрес узла, где это произошло. Послав запрос типа get_name_by_address для присланного IP, можно получить имя узла, откуда пришло данное уведомление. Отсутствие сообщения Time Exceeded (например, после трех попыток) будет говорить о достижении <URL>-адресата. Еще лучше для контроля наличия отклика от узла-мишени использовать реализацию ping на основе протокола UDP или ТСР (например, из библиотеки PERL), так как в этом случае можно задать бессмысленный номер порта и адресат откликнется ICMP-сообщением - порт недоступен (с предъявлением своего IP-адреса). Это будет означать, что адресат достигнут и вы располагаете исчерпывающими данными о пути до него. В результате такой последовательности посылок будет получена исчерпывающая информация о пути до указанной цели.
Для данной методики реализации traceroute не существенно, какой протокол использовать, UDP, ICMP или TCP.
Плавающие объекты
Изображения и объекты могут быть привязаны к тексту, а могут обтекаться текстом, прижимаясь к одной из сторон документа и деформируя его поля. Плавающие объекты начинаются с новой строки. Для управления положением плавающего объекта используется атрибут align. Например:
<img align="left" src=http://foo.com/animage.gif>
Существует атрибут для элемента br, который управляет обтеканием объекта текстом. Это clear= none|left|right|all, который определяет то, где должна появиться следующая строка в процессе отображения.
none | следующая строка будет отображена как обычно (значение по умолчанию). |
left | следующая строка будет помещена ниже плавающего объекта на левом поле. |
right | следующая строка будет помещена ниже плавающего объекта на правом поле. |
all | следующая строка будет помещена ниже плавающего объекта на любом из доступных полей. |
Рассмотрим вариант, когда текст размещается справа от изображения, и посмотрим, что будет после прерывания строки с помощью BR.
Если атрибут clear="none", следующая строка начнется сразу под уже имеющимся текстом.
Если же clear = "left" или all, то мы получим:
Используя стилевые листы, мы можем потребовать, чтобы все разрывы строк обрабатывались аналогичным образом. Для реализации этого можно записать:
<style type="text/css">
br { clear: left }
</style>
Для того чтобы такая схема размещения текста сработала только раз, следует воспользоваться атрибутом ID.
<head>
…….
<style type="text/css">
br.mybr }clear: left}
</style>
</head>
<body>
…….
……..
</body>
23.7. Элементы управления шрифтами: tt, i, b, big, small, strike, s и u
<!entity % font
"tt | i | b | u | s | strike | big | small ">
<!element (%font|%phrase) - - (%inline)*>
<!attlist (%font|%phrase) %attrs; -- %coreattrs, %i18n, %events -- >
tt: |
соответствует шрифту телетайпа (символы равной ширины). |
i: | курсив |
b: | полужирный шрифт. |
big: | шрифт с крупными буквами. |
small: | мелкий шрифт. |
strike: |
перечеркнутый шрифт (к использованию не рекомендуется) |
u: |
подчеркнутый шрифт (к использованию не рекомендуется) |
<
/p>
Ниже приведены примеры управления шрифтами.
<b>bold</b>
<i>italic</i>, <b><i>bold italic</i></b>, <tt>teletype text</tt>
<big>big</big> <small> small </small> text.
Броузер отобразит при этом на экране:
bold, italic, bold italic, teletype text, big, small text.
Использование стилевых листов позволяет получить значительно большее многообразие шрифтов. Например, нижеприведенный текст даст распечатку голубым курсивом:
<head>
<style>
p.mypar {font-style: italic; color: blue}
</style>
</head>
<p id="mypar"> … далее следует текст, печатаемый голубыми буквами курсивом.
23.8. Элементы модификаторов шрифтов: font и basefont
<!element font - - (%inline)* -- локальное изменение шрифта -->
<!attlist font
| size cdata #implied |
-- [+]nn напр. size="+1", size=4 -- |
| color cdata #implied |
-- #rgbgbb in hex, напр. red: "#ff0000" -- |
| face cdata #implied |
-- список имен шрифтов, разделенных запятыми -- > |
<!element basefont - o empty>
<!attlist basefont
| size cdata #required |
-- базовый размер шрифта для элементов font -- |
| color cdata #implied |
-- #rgbgbb in hex, напр. red: "#ff0000" -- |
| face cdata #implied |
-- список имен шрифтов, разделенных запятыми -- > |
С этими элементами могут использоваться атрибуты (все они не рекомендуются к использованию):
size = cdata
Атрибут определяет размер шрифта (1-7).
color = color
Атрибут определяет цвет шрифта.
face = cdata-list
Атрибут определяет список шрифтов, которые агент пользователя должен рассматривать в порядке приоритета.
Элемент font изменяет размер и цвет шрифта для текста, в нем содержащегося. Элемент basefont устанавливает базовый размер шрифта (с помощью атрибута size). Размер шрифта, заданного font является относительным по отношению к размеру, определенному basefont. Если basefont не задан, значением по умолчанию считается 4. Ниже приведены примеры задания шрифтов с помощью font (данная форма определения размера шрифта не рекомендуется).
<p> <font size=1> size=1</font>
<font size=2> size=2</font>
<font size=3> size=3</font>
<font size=4> size=4</font>
<font size=5> size=5</font>
<font size=6> size=6</font>
<font size=7> size=7</font>
Агент пользователя при этом отобразит следующее
size=1 size=2 size=3 size=4 size=5 size=6 size=7
23.9. Элемент hr
<!element hr - o empty>
<!attlist hr %coreattrs; | -- id, class, style, title -- |
| %events; |
|
align (left|right|center) #implied |
| () #implied |
| size %pixels #implied |
| width %length #implied > |
Определение атрибутов
Этот булев атрибут требует, чтобы агент пользователя пользовался одноцветным способом отображения линии.
size = length
(Не рекомендуется) Этот атрибут определяет высоту линии.
width = length
(Не рекомендуется) Этот атрибут определяет ширину линии (по умолчанию 100%), то есть линия пресекает весь экран.
Пример использования элемента hr.
<hr width="50%" align="center">
<hr size="5" width="50%" align="center">
<hr size="5" width="50%" align="center">
24. Рамки (frames)
Обычный документ имеет одну секцию заголовка и одну секцию тела документа. Документ с рамками имеет заголовок (head), frameset (набор рамок) и, опционно, тело документа. Секция frameset специфицирует раскладку объектов в основном окне агента пользователя. Секция body предлагает альтернативу для случая агентов пользователя, которые не поддерживают frameset.
24.1. Элемент frameset
<!element frameset - - ((frameset|frame) + & noframes?)>
<!attlist frameset
|
-- абсолютные значения в пикселях, проценты или относительные значения -- |
| rows cdata #implied | -- если не задано, по умолчанию rows=1 -- |
| cols cdata #implied | -- если не задано, по умолчанию cols=1 -- |
| onload %script #implied | -- все рамки загружены -- |
| onunload %script #implied | -- все рамки удалены -- > |
Определения атрибутов
rows = length-list
Этот атрибут специфицирует выкладку горизонтальных рамок. Значение представляет собой список длин, разделенных запятыми. Если атрибут не задан, значение по умолчанию равно 100%.
cols = length-list
Этот атрибут специфицирует выкладку вертикальных рамок. Значение представляет собой список длин, разделенных запятыми. Если атрибут не задан, значение по умолчанию равно 100%.
Все рамки предполагаются прямоугольными. Установка атрибута rows определяет число рамок по горизонтали, а атрибут cols задает число рамок по вертикали. Таким образом, задается сетка рамок. Если атрибут rows не задан, каждая колонка занимает всю длину страницы. Если атрибут cols не задан, каждый ряд занимает всю ширину страницы. Если не заданы оба атрибута, на странице присутствует одна рамка, занимающая всю страницу.
Размер может задаваться в пикселях (абсолютно), в процентах от размеров экрана или в относительных длинах в форме i*, где i - целое число. Когда заданы оба атрибута, агент пользователя сначала выделяет размеры, заданные абсолютно, затем оставшуюся часть делит в соответствии с определенными долями. Значение * эквивалентно 1*. Отображение страницы осуществляется слева направо и сверху вниз. Пример (экран делится на две равные части, верхнюю и нижнюю):
<frameset rows="50%, 50%">
… остальная часть определения …
</frameset>
В следующем примере создается три колонки: вторая имеет фиксированную ширину в 250 пикселей (что удобно для картинки известного размера). Первая получает 25% оставшегося пространства, а третья - 75%.
<frameset cols="1*,250,3*">
… остальная часть определения …
</frameset>
В следующем примере создается решетка 2х3
<frameset rows="30%,70%" cols="33%,34%,33%">
… остальная часть определения …
</frameset>
В следующем примере предполагается, что высота окна равна 1000 пикселей. Для первой рамки выделяется 30% общей высоты (300 пикселей). Для второй рамки выделено точно 400 пикселей.
Это оставляет 300 пикселей на две оставшиеся рамки. Высота четвертой рамки определена как "2*", а третей - *, следовательно, третья получит 100, а четвертая - 200 пикселей.
<frameset rows="30%,400,*,2*" >
… остальная часть определения …
</frameset>
Если при задании абсолютных размеров остается свободное место, или возникает перерасход пространства, агент пользователя пропорционально увеличит или уменьшит размеры рамок. frameset могут вкладываться друг в друга на любом уровне. В приведенном примере внешний frameset делит имеющееся пространство на три равные колонки. Внутренний frameset делит вторую область на два ряда не равной высоты.
<frameset rows="33%,33%,34%" >
…содержимое первой рамки…
| <frameset rows="40%,50%" > |
| …содержимое второй рамки первого ряда… |
| …содержимое второй рамки второго ряда… |
| </frameset> |
| …содержимое третей рамки… |
</frameset>
Почему UDP?
Может возникнуть вопрос, почему RADIUS использует протокол UDP вместо TCP. UDP был выбран по чисто техническим причинам. Существует большое число моментов, которые нужно понять. RADIUS является протоколом, ориентированным на операции и имеющим ряд интересных особенностей:
1. |
Если запрос к первичному аутентификационному серверу не прошел, он должен быть переадресован вторичному серверу. Чтобы удовлетворить этому, копия запроса должна храниться на уровне выше транспортного, с тем, чтобы позволить альтернативную попытку. Отсюда следует, что необходим таймер ретрансмиссии. |
2. |
Временные требования данного конкретного протокола значительно отличаются от тех, которые обеспечивает TCP. |
3. |
Природа данного протокола не требует контроля состояния, что упрощает применение протокола UDP. |
Клиенты и серверы приходят и уходят. Системы перезагружаются, а сетевое питание выключается и включается... UDP полностью исключает влияние всех этих событий на работу системы. Любой клиент и сервер может открыть UDP обмен однажды и оставлять его в таком состоянии, игнорируя какие-либо сбои в сетевой среде.
Поисковые роботы Файл robotstxt
Когда робот посещает сайт, скажем http://www.foobar.com/, он сначала проверяет наличие http://www.foobar.com/robots.txt. Если он нашел этот документ, он анализирует его содержимое и выясняет, разрешен ли допуск к документу. Вы можете указать, что файл robots.txt доступен только для специальных роботов, и запретить доступ к определенным каталогам и файлам. Ниже приведен пример файла robots.txt, который препятствует всем роботам посещение всего сайта.
user-agent: * # applies to all robots
disallow: / # disallow indexing of all pages
Робот просто будет искать "/robots.txt" uri на вашем сайте, где сайт определен как HTTP-сервер, работающий на определенной ЭВМ с заданным номером порта. Ниже приведены примеры места положения robots.txt:
Сайт URI | URI для robots.txt |
http://www.w3.org/ | http://www.w3.org/robots.txt |
http://www.w3.org:80/ | http://www.w3.org:80/robots.txt |
http://www.w3.org:1234/ | http://www.w3.org:1234/robots.txt |
http://w3.org/ | http://w3.org/robots.txt |
Должен быть только один файл "/robots.txt" на сайт. В частности, не следует помещать файл "robots.txt" в пользовательские каталоги, так как робот туда не заглядывает. Если вы хотите, чтобы пользователи создали свои собственные "robots.txt", вы должны их объединить в один общий файл "/robots.txt". Если вы не хотите это делать, пользователи могут вместо этого использовать robots meta tag.
Некоторые советы: URI чувствительны к набору строчными или прописными буквами, а строка "/robots.txt" должна быть набрана строчными буквами. Пустые строки не допустимы.
Должен быть только одно поле "user-agent" на рекорд. Робот должен либерально интерпретировать это поле. Если значение равно "*", рекорд описывает политику доступа любого робота по умолчанию (робот не соответствует ни одному другому рекорду). Не допускается более одного такого рекорда в файле "/robots.txt".
Поле "disallow" специфицирует URI, который не должен посещаться. Это может быть полный проход, частичный проход, любой URI, который начинается с этой величины, не будет доступен. Например,
disallow: /help запрещает как /help.html так и /help/index.html, в то время как
disallow: /help/ запрещает посещение /help/index.html, но позволяет /help.html.
Пустое значение для "disallow", указывает, что все uri доступны. Хотя бы одно поле "disallow" должно присутствовать в файле robots.txt.
Поля ячейки
Два атрибута регулируют зазор между и внутри ячеек.
cellspacing = length
Этот атрибут определяет то, какое расстояние должно быть оставлено между рамкой таблицы и начальным или конечным краем ячейки для каждого ряда или колонки, а также между ячейками в таблице.
cellpadding = length
Этот атрибут определяет расстояние между границей ячейки и его содержимым.
Во всех последующих таблицах атрибут cellspacing определяет, что ячейки разделяются друг от друга и от рамки таблицы расстоянием в 20 пикселей. Атрибут cellpadding определяет, что верхняя и нижняя граница ячейки отстоит от его содержимого на 10% доступного пространства по вертикали (всего 20%). Аналогично поля ячейки в горизонтальном направлении составляют 10% от горизонтального размера ячейки.
<table>
<tr cellpadding="20"> <tr>data1 <td cellpadding="20%">data2 <td>data3
</table>
Ниже приведены примеры, где проиллюстрировано взаимодействие различных элементов. Пример 1.
<table border="border">
<caption>A test table with merged cells </caption>
<tr> |
<th> rowspan=2><th colspan="2">average |
|
<th rowspan="2">other<br>category<th>misc |
<tr> | <th>height<th>weight |
<tr> | <th>align="left">males<td>1.9<td>0.003 |
<tr> |
<th> align="left" rowspan="2">females<td>1.7<td>0.002 |
/table>
Таблица может быть отображена следующим образом.
A test table with merged cells
| Average | Other category | misc |
height | weight | |
males | 1.9 | 0.003 | | |
females | 1.7 | 0.002 | | |
Пример 2 иллюстрирует группировку рядов и колонок. Пример взят из "developing international software", by nadine kano.
Code-page support in Microsoft Window
Code-page ID | Name | ACP | OEMCP |
Windows NT 3.1 |
Windows NT 3.51 |
Windows 95 |
1200 1250 1251 1252 1253 1254 1255 1256 1257 1361 |
unicode (BMP of ISO/IEC-10646) windows 3.1 eastern european windows 3.1 cyrillic windows 3.1 us (ansi) windows 3.1 greek windows 3.1 turkish hebrew arabic baltic korean |
x x x x x x x x x |
|
x x x x x x |
x x x x x x ** |
* x x x x x x x x x |
437 708 709 710 720 |
MS-DOS united states arabic (asmo 708) arabic (asmo 449+, bcon v4) arabic (transparent arabic) arabic (transparent asmo) | |
x x x x x |
x | x |
x x x x x |
<
/p>
15. Информация о пути. Элемент base
<!element base - o empty>
<!attlist base href %url #required
target cdata #implied -- где развернуть подключенный ресурс -- >
Описание атрибута
href = url
Этот атрибут задает абсолютный url, который используется как базовый при определении относительных url.
В HTML проходы всегда задаются с помощью URL. Относительные URL получаются на основе базового URL, который может быть получен различными путями. Элемент base позволяет описать базовый URL явно. Например:
<html>
<head>
<base href=>
</head>
….
</html>
Относительный URL "../gee/foo/html" будет в этом случае получен в виде:
15.1. Связи и якоря
HTML-связь представляет собой соединение одного WWW-ресурса с другим.
Определение связей и якорей
В HTML любая связь имеет два конца и направление. Связь начинается в источнике и завершается в месте назначения. Любое описание связи определяет оба эти конца. Один конец задается местом описания связи, другой - атрибутом этой связи. Связь соответствует какому-то WWW-ресурсу (HTML-документу, изображению, видео-клипу, текущему документу, звуковому файлу и т.д.). Конец связи может быть также задан якорем.
Якорь - это именованный указатель на определенную часть документа. Связь устанавливает соответствие между источником и местом назначения. Но помимо этого связь может определять тип информации. Связи могут носить самый разный характер, например, указания "next" или "previous" также задают определенные связи. Связи могут использоваться пользователем и для определения порядка печати документов. Атрибут
rel определяет, что связь имеет начало в текущем документе. Атрибут
rev указывает, что описанная связь имеет в качестве места назначения текущий документ. В HTML имеется два элемента, определяющие связь, это link и a.
Link может появиться в секции head HTML-документа. Этот элемент определяет взаимоотношение между зоной текущего документа и другим ресурсом.
Элемент
A может появиться в теле документа, он устанавливает связь между зоной текущего документа и другим ресурсом.Элемент a в отличие от link может иметь содержимое (текст, изображения и т.д.). Другим важным отличием этих двух элементов является то, что А интерпретируется агентом пользователя как указание "извлечь ресурс, находящийся на другом конце связи". Извлеченный ресурс может обрабатываться агентом пользователя разными способами:
Открыть новый документ в том же окне, открыть документ в другом окне, запустить новую программу и т.д.
Атрибут title может быть установлен в элементах для выдачи дополнительной информации о природе связи.
Пользователь с картой вызова-отклика (Challenge-Response)
Сервер NAS с адресом 192.168.1.16 посылает запрос Access-Request серверу RADIUS для пользователя с именем MANYA, подключаемого к порту 7.
ID = 2
Request Authenticator = {16 октетов случайного числа }
Атрибуты:
>User-Name = " MANYA"
User-Password = {16 октетов пароля дополненные в конце нулями,
объединенный функцией XOR с MD5 (общий секретный ключ |Request Authenticator)}
NAS-IP-Address = 192.168.1.16
NAS-Port = 7
Сервер RADIUS решает вызвать MANYA, отсылая назад строку вызова и ожидая отклика. Сервер RADIUS посылает запрос Access-Challenge серверу NAS.
Code = 11 | (Access-Challenge} |
ID = 2 | (тот же что и в Access-Request) |
Response Authenticator = {16-октетов контрольной суммы MD-5 кода (11), ID (2), Request Authenticator, представленный выше, атрибуты данного отклика и общий секретный пароль}
Атрибуты:
Reply-Message = "Challenge 32769430. Enter response at prompt."
State = {Код, который должен быть прислан вместе с откликом пользователя }
Пользователь вводит свой отклик, а NAS посылает новый запрос Access-Request с этим откликом и атрибутом State.
Code = 1 |
(Access-Request) |
ID = 3 |
(Заметьте, что он изменяется) |
Request Authenticator = {Новое 16-октетное число}
Атрибуты:
User-Name = " MANYA"
User-Password = {16 октетов отклика дополненного в конце нулями и объединенного функцией XOR с контрольной суммой MD5 общего секретного пароля и представленного выше аутентификатора запроса (Request Authenticator)}
NAS-IP-Address = 192.168.1.16
NAS-Port = 7
State = |
{Код из пакета Access-Challenge} |
Отклик был некорректен, поэтому сервер RADIUS предлагает NAS отклонить попытку входа в систему.
Code = 3 | (Access-Reject) |
ID = 3 | (то же что и в Access-Request) |
Response Authenticator = {16-октетов контрольной суммы MD-5 кода (3), ID (3), описанного выше Request Authenticator, атрибутов этого отклика (если таковые имеются) и общего секретного пароля}
Атрибуты:
(отсутствуют, хотя сообщение Reply-Message может быть послано)
На практике, с сервером RADIUS связывается база данных, где хранятся имена пользователей и соответствующие им секретные пароли. Конкретный именованный пользователь должен аутентифицироваться только одним способом. Это уменьшает возможности атаки путем согласования использования наименее безопасного метода аутентификации. Если пользователь нуждается в использовании разных аутентификационных методов в различных ситуациях, тогда следует данному пользователю в каждом из этих вариантов выступать под разными именами.
Пароли должны храниться в местах с ограниченным доступом. Эти данные должны быть доступны только процессам, которые с ними работают.
Ссылки
[1] |
Rivest, R., and S. Dusse, "The MD5 Message-Digest Algorithm", RFC 1321, MIT Laboratory for Computer Science, RSA Data Security Inc., April 1992. |
[2] |
Postel, J., "User Datagram Protocol", STD 6, RFC 768, USC/Information Sciences Institute, August 1980. |
[3] |
Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700, USC/Information Sciences Institute, October 1994. |
[4] |
Kaufman, C., Perlman, R., and Speciner, M., "Network Security: Private Communications in a Public World", Prentice Hall, March 1995, ISBN 0-13-061466-1. |
[5] |
Jacobson, V., "Compressing TCP/IP headers for low-speed serial links", RFC 1144, Lawrence Berkeley Laboratory, February 1990. |
[6] |
ISO 8859. International Standard -- Information Processing -- 8-bit Single-Byte Coded Graphic Character Sets -- Part 1: Latin Alphabet No. 1, ISO 8859-1:1987. |
[7] |
Sklower, K., Lloyd, B., McGregor, G., and Carr, D., "The PPP Multilink Protocol (MP)", RFC 1717, University of California Berkeley, Lloyd Internetworking, Newbridge Networks Corporation, November 1994. |
[8] |
Galvin, J., McCloghrie, K., and J. Davin, "SNMP Security Protocols", RFC 1352, Trusted Information Systems, Inc., Hughes LAN Systems, Inc., MIT Laboratory for Computer Science, July 1992. |
[9] |
Rigney, C., "RADIUS Accounting", RFC 2139, January 1997. |
[10] |
B. Aboba, G. Zorn, RADIUS Authentication Client MIB. RFC-2618, June 1999. |
[11] |
G. Zorn, B. Aboba, RADIUS Authentication Server MIB. RFC-2619, June 1999. |
[12] |
B. Aboba, G. Zorn, RADIUS Accounting Client MIB. RFC-2620, June 1999. |
[13] |
G. Zorn, B. Aboba, RADIUS Accounting Server MIB. RFC-2621, June 1999. |
Помеченные секции
Помеченные секции играют роль, схожую с конструкцией #ifdef препроцессоров языка c.
<![include[
<!-- это будет включено -->
]]>
<![ignore[
<!-- это будет проигнорировано -->
]]>
SGML определяет также использование помеченных секций для содержимого Cdata, в пределах которого "<" не рассматривается как начало метки, напр.,
<![cdata[
<an> example of <sgml> markup that is
not <painful> to write with < and such.
]]>
Указание на то, что агент пользователя не распознал помеченную секцию, является появление символьной последовательности "]]>", которая будет отображена, когда агент пользователя ошибочно использует первый символ ">" в качестве конечной метки, начинающейся с "<![".
Инструкции обработки
Инструкции обработки представляют собой механизм выявления платформо зависимых идиом. Команды обработки начинаются с последовательности символов <? и завершаются >.
<?instruction >
Например:
<?>
<?style tt = font courier>
<?page break>
<?experiment> ... <?/experiment>
Разработчики должны учитывать то, что многие агенты пользователя отображают (render) инструкции обработки как часть текста документа.
Сжатая форма разметки документа (markup)
Некоторые конструкции SGML shorttag сокращают объем данных, вводимых с клавиатуры. Хотя эти конструкции технически не вводят неопределенности, они уменьшают ясность документов, особенно когда язык усовершенствуется и добавляются новые элементы. Документы, которые используют их, являются SGML документами, но могут не работать со многими существующими средствами HTML.
Конструкции shorttag, о которых идет речь, выглядят следующим образом:
* net tags:
<name/.../
* closed start tag:
<name1<name2>
* empty start tag:
<>
* empty end tag:
</>
Последовательное построение/разрушение
Метод последовательного построения/разрушения базируется на анализе упорядочивания ребер графа. Сначала все ребра находятся в нерабочем состоянии, затем ребра последовательно оказываются “отремонтированы”, т.е. переходят в рабочее состояние одно за другим в специфицированном порядке, пока вся система не перейдет в работоспособное состояние. Оценка надежности определяется тем, сколько времени требуется системе, чтобы стать работоспособной. Это позволяет получить лучшую оценку, чем наивный метод.
Пространство событий для последовательного метода построения состоит из пары (x,p), где х - вектор состояния системы, а p = (p(1),…,p(m)) является перестановкой индексов ребер Е, такой, что для некоторого индекса k мы имеем:
xp(1)=…=?x p(k) =1, xp(k+1)=,…,x p(m) =0.
Если вектор состояния х выбран согласно предписанным вероятностям состояния, а перестановки p выбраны независимо и однородно по отношению ко всем подходящим перестановкам, тогда вероятность реализации конкретной пары (x,p) равна
,
где k равно числу рабочих элементов в х. Метод последовательного конструирования испытывает перестановку
и рассматривает одновременно набор P
всех возможных пар состояний (x,p) p=
и х, согласующимся с
в рамках выше приведенных критериев. Значение надежности набора испытаний (sample)
является условной вероятностью работы системы с учетом P
, то есть, отношение суммы вероятностей пар (x,p) О P
, для которого Ф(х)=1, к вероятности P
. Подробности представлены ниже.
Метод последовательного конструирования
1. Выбираем образец перестановки
=(
(1),…,
(m)) из набора перестановок {1,…,m}. Определяем векторы x(k), k=1,…,m как
2. Определяем первый индекс r=0,…,m, для которого Ф(x(r))=1.
3. Вклад
в оценочный параметр R тогда
4. Складываем набор значений
и делим на число выбранных перестановок набора. Это является несмещенной оценкой R.
Оценка, полученная для каждой выбранной перестановки из набора, имеет меньшую вариацию, чем полученная для одного образца при наивном алгоритме. Наибольшие вычислительные усилия тратятся на этапе 2 и это сильно зависит оттого, как быстро можно обновить значение Ф(x(k)), т.е.
насколько легко можно определить функциональность системы по ребрам, восстановленным одно за другим. Заметим, однако, что восстановление ребер должно производиться только до тех пор, пока система не станет полностью функциональной (в предположении связности системы), так как дальнейшее восстановление ребер графа не изменит рабочего состояния системы. Таким образом, объем выполненной работы может быть много меньше чем порядок m. В случае надежности коннективности было показано, что определение индекса r может быть выполнено почти также легко, как определение Ф(х) для одного значения х, так что последовательные выборки будут получаться по той же цене, что одна выборка в наивном методе. Наконец, при равных вероятностях отказов для ребер мы получаем дополнительное преимущество того, что знаменатель в выражении для этапа 4 (см. выше) всегда равен 1, что сокращает объем вычислений.
Можно разработать метод разрушения, аналогичный методу конструирования, представленной выше, начав при условии, что все компоненты работают, и, разрушая ребра (связи) до тех пор, пока система не выйдет из строя. Это может иметь преимущество в ситуации, когда система имеет тенденцию выходить из строя при отказе небольшого числа связей, так что выполняется меньшее число итераций разрушения, чем итераций конструирования в обратном процессе.
Постоптимизация ограничений
До сих пор мы обсуждали базовые стратегии получения ограничений. Даже конспективное описание каждого показывает, что существует огромное разнообразие доступных методов получения ограничений. Естественно попытаться объединить их для уточнения границ или получения более общих ограничений. Предпочтительным путем является нахождение общей теории, в которой число границ унифицировано. Потерпев неудачу в этом, можно пожелать получить какую-либо информацию о надежности, и это возможно с помощью разных рассмотренных методов. Например, если известна вероятность достижения u из s, и независимо известна также вероятность достижения t из u, что можно сказать о вероятности достижения t из s? Используя известную теорему Алсведе и Дайкина, Брехт и Кольбурн разработали методы для улучшения нижних границ. Они заметили, что если сеть G соединена с терминальным набором К1, с вероятностью р1, соединена с терминальным набором К2 и с вероятностью р2 и К1ЗК2№0, то G соединена с терминальным набором К1cК2 с вероятностью, по крайней мере, р1р2. Это дает мультипликативный треугольник неравенств для границ двухтерминальной надежности, который Брехт и Кольбурн нашли эффективным для улучшения границ двухтерминальной надежности, которые были вычислены другими методами (в частности методом группирования ребер). Ключом здесь является постоптимизация, методика улучшения ограничений для произвольных границ.
В чем-то похожий метод для верхних границ, называемый ренормализацией, был изучен недавно. Для двухтерминальной надежности вероятность хе того, что один терминал s не может связаться с другим терминалом t через специфицированное ребро е, ограничена сверху вероятностью того, что само ребро е не обеспечивает связь плюс вероятность того, что е работает с вероятностью, кратной вероятности хf для каждого ребра f, соединенного с е. Двухтерминальные верхние границы могут быть использованы для определения исходных оценок вероятности хе для каждого ребра е. Тогда каждое неравенство может привести к некоторому сокращению значения хе.
Ренормализация дает верхнюю границу при недооценке влияния пересечения s,t-маршрутов и при рассмотрении s,t-маршрутов, а не только s,t-проходов. Для s,t-связности ориентированных графов без циклов отсутствие ориентированных циклов гарантирует, что все s,t-маршруты являются s,t-проходами; в этом случае ренормализация является методом с полиномиальным временем, который гарантирует улучшение для верхнего ограничения. Ренормализация является существенно постоптимизационной стратегией, но может использоваться сама по себе, начиная с начальной переоценки вероятности отказа хе для ребра е.
Одна стратегия окончательной постоптимизации была сформирована для применения, когда вероятности работоспособности всех ребер равны между собой. Кольбурн и Хармс заметили, что если произвести оценку полинома
при фиксированном значении
р, будет получена линейная комбинация F0,…,Fd. Следовательно, если известна верхняя или нижняя граница значения надежности и она полиномиальна при специфицированном значении
р, то мы получаем линейное ограничение. Таким образом, любой метод, применяемый к сети с ребрами, вероятности работоспособности которых равны между собой, выдает линейное ограничение этого вида. Все линейные неравенства, полученные так, удовлетворяются одновременно, и, следовательно, можно комбинировать ограничения разных видов, используя методы линейного программирования. Если все базовые используемые ограничения эффективно вычислимы, можно использовать алгоритмы с полиномиальным временем для линейного программирования, чтобы сохранить полное время вычислений в полиномиальных пределах.
Преобразования и аппроксимация графов
Мы имели до сих пор два метода расширения стратегии группирования ребер: группирование не минимальных проходов или разрезов и смягченные требования разделения ребер. В этом подразделе мы рассматриваем третье расширение, которое является, может быть менее прямым, чем предыдущие два.
Мы видели, что преобразования могут быть использованы, чтобы “упростить” сеть и уменьшить время, необходимое для точных алгоритмов. Такие преобразования сохраняют значение меры надежности. Другие преобразования сети могут иметь свойство, гарантирующее, что мера надежности не увеличится. Эти D-преобразования сохраняют нижние границы меры надежности (то есть, вычисление нижней границы после использования такого преобразования выдает то же значение нижней границы надежности, что и до преобразования). Аналогично, I-преобразования гарантируют неуменьшение меры надежности, и, следовательно, сохранение верхней границы.
Тривиальное D-преобразование ликвидирует ребро или дугу сети; оно следует принципам когерентности и статической независимости, так что мера надежности не может увеличиться после такого удаления. Аналогично, операция расщепления узла х на два узла х1 и х2, и замещение каждого ребра {y,x} на {y,x1} или {y,x2} не может увеличить надежность. Эти тривиальные преобразования имеют заметные последствия. Было показано, что нижняя граница при группировании ребер для двухтерминальной надежности может быть получена с помощью использования лишь удаления ребер и расщепления узлов (удалить все ребра, которые не работают для обеспечения проходов в группе и расщепить нетерминальные узлы, соответствующим образом, чтобы было более одного прохода в группе). Результатом этих преобразований является параллельная комбинация s,t-путей - очень простой параллельно-последовательный граф. Верхняя граница при группировании ребер для двухтерминальной надежности аналогична использованию I-преобразования, которое идентифицирует два узла [H.M.F. AboElFotoh and C.J.Colbourn, “Series-parallel bounds for the two-terminal reliability problem”, ORSA J.
Computing 1 (1989), 205-222]. Использование преобразований для получения двухтерминальных границ при группировании ребер позволяет “рано” остановить процесс преобразования. Раз сеть преобразована в последовательно-параллельную сеть, надежность может быть вычислена точно за полиномиальное время и в дальнейших преобразованиях нет необходимости.
Одним частным приложением преобразований является анализ блокирующих свойств “канальных графов”. Преобразования для канальных графов используются и в отношении s,t-связности.
Два преобразования, треугольник-звезда (delta-wye) и звезда-треугольник достойны отдельного упоминания. Дельта (или D) в сетях является набором из трех ребер {{x,y},{x,z},{y,z}}, образующих треугольник, а wye (или у) является набором из трех ребер {{x,w},{y,w},{z,w}}, для которого вершина w является входящей для перечисленных выше вершин. Преобразования треугольник-звезда и звезда-треугольник являются лишь заменой одной конфигурации на другую. В 1962 году Леманом были предложены два метода определения вероятностей для ребер звезды (треугольника) при заданных вероятностях ребер треугольника (звезды, соответственно). Его два метода не являются, вообще говоря, точными, он скорее показал, что одно из преобразований является I-преобразованием, а другое D-преобразованием в предположении, что центральный узел не является терминальным. Удивительно, но то, какое из этих преобразований является I-преобразованием, зависит от численного значения вероятностей. Таким образом, преобразования треугольник-звезда и звезда-треугольник представляются отличными от ранее упомянутых преобразований, так как здесь нет простой комбинаторной настройки преобразования.
Возможно, большинство существенных аспектов разработки ограничений путем комбинирования простых преобразований являются потенциалом для разработки более сложных мер надежности. Например, всякий раз, когда удаление ребра и расщепление вершины являются I-преобразованиями для специфицированной надежности или меры работоспособности, мы имеем эффективно вычисляемые границы для алгоритма группирования ребер.Если, кроме того, мера может быть вычислена точно для последовательно-параллельной сети за полиномиальное время, мы имеем эффективные последовательно-параллельные аппроксимации. Используя объединение Ломоносова, ограничения для статических мер надежности, обсуждаемые здесь, могут быть применены для времязависимых мер надежности.
Преобразования и сокращения
Ребро или дуга, которые не входят ни в один из минимальных наборов путей называется нерелевантным: работоспособность таких нерелевантных ребер не влияет на работу или отказ сети. Самым простым способом упрощающего преобразования графа является удаление нерелевантных ребер. По определению, такое преобразование не меняет меру надежности. Чтобы преобразование имело практическое применение для сети, время его эффективной реализации должно быть полиномиальным. Для все-, k- и 2-терминальных мер надежности петли всегда являются нерелевантными. А для k- и 2- терминальных мер надежности, нерелевантными являются также все ребра, не имеющие терминального окончания. Такие ребра легко находить и удалять. В случае ориентированных задач надежности поиск нерелевантных дуг отнюдь не простая задача. Было показано, что задача нахождения нерелевантных дуг в случае (s,t)-связанности имеет сложность NP, в то время как общая неориентированная задача допускает эффективное решение.
Сосредоточимся сначала на неориентированных задачах. Ребро или дуга, входящие во все минипути, является обязательным. После удаления всех нерелевантных ребер, каждое оставшееся соединение (набор разрезов ребер с мощностью 1) является обязательным. Пусть G=(V,E) с набором терминалов KНV, и ребро eОE имеет вероятность функционирования pe. Стягивание G?e , ребра e={x,y} из G получается путем удаления e, которое определяет x и y, и превращая результирующий узел в терминал всякий раз, когда K1{x,y}?0. Надежность Rel(G) графа G удовлетворяет соотношению Rel(G)=peRel(G?e), когда eявляется обязательным ребром. Таким образом, отображение G в G?e является преобразованием, сохраняющим меру надежности, с мультипликативным коэффициентом pe.
Два ребра e и f, имеющие одни и те же концы, являются параллельными. Так как любой минимальный путь содержит, по крайне мере, одно из двух таких ребер, а замена e на f будет естественным взаимно однозначным соответствием между минимальными наборами проходов, содержащих е, и минимальных путей с ребром f.
Замена e и f на одно ребро g с коэффициентом p=1-(1-pe)(1-pj) не изменит общую меру надежности. Это называется параллельным сокращением графа. Понятие параллельного сокращения можно обобщить на случай, когда e и f сами являются заменителями ребер.
Два ребра e={x,y} и f={y,z} называются последовательными, когда y является узлом степени 2. В этом случае любой миниразрез содержит либо ребро е, либо f. Замена e на f является естественной для миниразрезов, содержащих e и f, соответственно. Таким образом, преобразование, сохраняющее меру надежности, получается путем удаления узла y и ребер e, f и добавления ребра g = {x,z} с надежностью pg=pepf при условии, что y не является терминальной вершиной. Это называется последовательной редукцией. В более общем случае, когда два ребра являются дополнениями, могут быть использованы аналогичные преобразования.
Последовательную редукцию нельзя применять к терминальным узлам графа со степенью 2. Однако, в случае, когда x, y, z являются терминалами, некоторое структурное замещение с сохранением меры надежности возможно. Коэффициент такого преобразования будет равен 1-(1-pe)(1-pf), если надежность нового ребра g определяется вероятностью pg=pepf/(1-(1-pe)(1-pf)). Это называется редукцией второй степени. Остается рассмотреть случаи, когда y является терминалом, а x или z - нет.
В сущности, каждое упрощение может рассматриваться, как замещение некоторой субсети субсетью, которая имеет эквивалентные характеристики надежности, или характеристики, которые масштабируют исходную меру надежности определенным образом. Принимая это во внимание, рассмотрим сеть G=(V,E) с набором терминальных узлов KНV. Полученная из G подсеть H=(W,F) является s-связанной, если существует такой набор АНW, с |A|Јs, для которого каждое ребро графа G с одним концом в точке V\W и другим концом в W, имеет оконечную точка в А. Другими словами только узлы из А связывают подсеть с оставшейся сетью. Общий класс упрощений возникает из изучения s-связанных субграфов для малых s, и замещения каждого из них на более простые s-связанные графы.
1-связные субсети соединены с остальной сетью через один узел разреза. Если 1-связная субсеть не содержит терминалов, все ее ребра являются нерелевантными. С другой стороны, если субсеть, и остальная сеть содержат терминалы, сам узел разреза может рассматриваться как терминал, так как он связан с терминалами в любом минипути. Таким образом, добавляем узел разреза в качестве терминала. Затем сеть может быть разделена на две субсети H и G\(W-A), а мера надежности равна произведению мер этих двух объектов. Это обобщает понятие преобразования на процедуры, которые разделяет сеть на две или более субсети.
Для субсетей, объединенных в двух точках, мы рассматриваем замещение субсети как определение эквивалентного ребра. Если Н является субсетью, соединенной через {x,y}, и Н не содержит терминалов, то мы можем определить 2-терминальную надежность Н от х до у и заместить Н ребром {x,y}, чья вероятность работоспособности равна найденной 2-терминальной надежности. Когда Н содержит терминалы, ситуация более сложна, так как недостаточно знать, что х достижимо со стороны у, нужно также знать, могут ли все внутренние терминалы связаться с х или у или с обоими из них. Несмотря на это, разработаны преобразования, при которых ребрам присваивается несколько значений вероятности, а не только вероятность работоспособности. Число величин, которые нужно поддерживать, не зависит от размера сети, но растет экспоненциально с увеличением числа подсоединенных узлов.
Причины возникновения сбоев
Механизмы потерь и причины их возникновения относительно хорошо изучены в классической теории надежности. Например, в электронных системах деградация узлов происходит, когда они подвергаются непрерывному тепловому воздействию. В результате, такие узлы случайным образом выходят из строя. Анализ надежности для таких систем обычно включает в себя изучение этих случайных процессов и параметры их распределений. При анализе сетевой надежности часть механизмов, вызывающих потери, известна также как и параметры их функций распределения. Но остается много не менее важных механизмов, о функции распределения которых, мы ничего не можем сказать. Например, существует много публикаций о возникновении отказов в работе оптоволоконных сетей, вызванных естественными причинами, такими как пожары, или ошибками оператора транзитной сети, который совместно использовал канал. Таким образом, трудно построить модель сбоев в канале, удовлетворяющую реальной частоте сбоев. Обычно, прогноз частоты сбоев в сети строиться на основе исторического анализа или результатов измерений.
АОтличия html и html Изменения в элементах Новые элементы
Новыми элементами в HTML 4.0 являются: abbr, acronym, bdo, button, col, colgroup, del, fieldset, frame, frameset, iframe, ins, label, legend, noframes, noscript, object, optgroup, param, s (не рекомендуемый), span, tbody, tfoot, thead и q.
Не рекомендуемые элементы
Следующие элементы являются не рекомендуемыми: applet, basefont, center, dir, font, isindex, menu, strike и u.
Устаревшие элементы
Следующие элементы являются устаревшими: listing, plaintext, и xmp. Вместо них разработчикам следует использовать элемент pre.
Изменения в атрибутах
Почти все атрибуты, которые специфицируют представление HTML-документа (напр., colors, alignment, fonts, graphics, и т.д.) объявлены не рекомендуемыми, предпочтение отдается стилевым листам.
Атрибуты id и class позволяют разработчику присвоить имя и класс информации элементам для стилевых листов, для скриптов, для деклараций объектов и т.д..
Изменения в доступе
В HTML 4.0 введено много изменений для обеспечения доступа, включая:
Атрибут title может быть теперь установлен почти для любого элемента.
Разработчик может выдавать длинные описания таблиц, изображений и рамок.
Изменения для мета данных
Разработчики могут теперь специфицировать профайлы, которые выдают объяснения по поводу мета данных, заданных элементами meta или link.
Изменения для текста
Новые возможности интернационализации позволяют разработчикам специфицировать язык документа и направление текста.
Элементы ins и del позволяют разработчикам помечать изменения, внесенные в документ.
Элементы ABBR и acronym позволяют разработчикам помечать сокращения и акронимы в своих документах.
Изменения для связей
Атрибут ID делает любой элемент якорем назначения связи.
Изменения для таблиц
Модель таблиц HTML 4.0 выросла из более ранней концепции HTML+ и первоначального проекта HTML 3.0. Предыдущая модель была расширена в ответ на следующие запросы от информационных провайдеров:
Разработчики могут специфицировать таблицы, которые отображаются агентом пользователя по мере получения данных.
Разработчики могут специфицировать таблицы, которые доступны пользователям с не визуальными агентами пользователя.
Разработчики могут специфицировать таблицы, с фиксированными заголовками и подписями. Агенты пользователя могут использовать преимущества этого решения при скролировании больших таблиц или при отображении таблиц в многостраничном формате.
Модель таблиц HTML 4.0 удовлетворяет требованиям опционного выравнивания по колонкам, предоставляется больше гибкости при спецификации рамок и разделительных линий в таблицах. Ожидается, однако, что стилевые листы в самом ближайшем будущем возьмут на себя функции формирования и таблиц.
Кроме того главной целью является обеспечение обратной совместимости с широко распространенными приложениями таблиц Netscape. Другой целью было упрощение импорта таблиц совместимых с моделью SGML cals. Последний проект делает атрибут выравнивания совместимым с последней версией наиболее популярных броузеров.
Для формирования групп колонок с различной шириной и свойствами выравнивания введен новый элемент colgroup, который может работать с одним или более элементов col.
Стилевой атрибут включен как средство расширения свойств, связанных с краями внутренней области групп ячеек. Например, стиль линии: точечная, двойная, тонкая/толстая и т.д.; цвет заполнения внутренней области; поля ячейки и шрифты.
Атрибуты рамки и разделительных линий модифицированы для исключения конфликтов имен с sgml, а также для блокировки влияния совпадения имен атрибутов align и valign. Эти изменения стимулировались желанием исключить в будущем проблемы, если спецификация будет расширена и разрешит применение атрибутов рамок и разделительных линий другими элементами таблицы.
Изменения для изображений, объектов и карт изображений
Элемент object позволяет включать объекты.
Элементы iframe и object позволяют разработчикам создавать встраиваемые документы.
Атрибут alt необходим для элементов img и area.
Механизм создания карт изображения позволяет разработчикам создавать более доступные карты.
Модель содержимого элемента map по этой причине была изменена.
Изменения для форм
Данная спецификация вводит несколько новых атрибутов и элементов, для работы с формами:
Атрибут ключа доступа позволяет разработчику специфицировать прямой доступ к управлению формой через клавиатуру.
Атрибут disabled позволяет разработчику сделать управление формой заблокированным.
Атрибут readonly позволяет разработчику запретить какие-либо изменения в управлении формой.
Элемент label устанавливает связь между меткой и конкретным видом управления формой.
Элемент fieldset группирует связанные по смыслу поля в соответствии элементом legend. Оба эти новые элемента позволяют лучше организовать процесс отображения и улучшить интерактивность. Броузеры, ориентированные на воспроизведение речи при описании формы могут учитывать, вводимые этими элементами метки (ярлыки).
Новый набор атрибутов в сочетании со скриптами позволяют разработчику форм верифицировать данные, вводимые пользователем.
Элементы button и input с типом "button" могут использоваться в комбинации со скриптами для существенного обогащения возможностей форм.
Элемент optgroup позволяет разработчику группировать опции в меню select, который весьма важен для обеспечения доступа к форме.
Дополнительные изменения для интернационализации.
Изменения для стилевых листов
HTML 4.0 поддерживает больший набор описателей среды, так что разработчики могут писать стилевые листы, ориентированные на определенные внешние устройства.
Изменения для рамок
HTML 4.0 поддерживает документы со встроенными рамками.
Изменения для скриптов
Многие элементы имеют атрибуты событий, которые сопряжены со скриптами, исполняемыми при наступлении такого события (напр., при загрузке документа, при нажатии клавиши мышки и т.д.).
Изменения для интернационализации
HTML 4.0 интегрирует рекомендации RFC-2070 для интернационализации HTML.
Однако, эта спецификация и RFC-2070 отличаются в следующих пунктах:
Атрибут accept-charset был специфицирован скорее для элемента form, чем для textarea и input.
Спецификация HTML 4.0 дает дополнительные разъяснения для двунаправленных алгоритмов укладки текста.
Использование cdata для определения элементов script и style не сохраняет возможности перекодировки документа, как это описано в RFC-2070.
33. Приложение b Рабочие характеристики, приложения и заметки для разработчиков.
Следующие замечания являются информативными, а не нормативными.
Приложения Интерентовский тип среды "message/http"
В дополнение к определению протокола HTTP/1.1, данный документ является спецификацией для типов среды Интернет "message/http". Ниже приведенный список является официальным для IANA.
Media Type name: | message |
Media subtype name: | http |
Required parameters: | none |
Optional parameters: | version, msgtype |
version: Номер версии HTTP вложенного сообщения (напр., "1.1"). Если отсутствует, номер версии может быть определен по первой строке тела сообщения.
msgtype: Тип сообщения -- "запроса" или "отклика". Если отсутствует, тип может быть определен по первой строке тела сообщения.
Соображения кодирования: разрешено только "7bit", "8bit" или "binary" (двоичное).
16.2. Тип среды Интернет "multipart/byteranges"
Когда сообщение HTTP содержит несколько фрагментов (ranges) (например, отклик на запрос нескольких не перекрывающихся фрагментов), они пересылаются как многофрагментное сообщение MIME. Тип среды multipart для этих целей носит название "multipart/byteranges".
Тип среды multipart/byteranges содержит в себе две или более части, каждая из которых со своими полями Content-Type и Content-Range. Отдельные части разделяются с использованием пограничного параметра MIME.
Media Type name: | multipart |
Media subtype name: | byteranges |
Required parameters: | boundary |
Optional parameters: | none |
Соображения кодирования: разрешено только "7bit", "8bit" или "binary".
Например:
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 500-999/8000
...первый фрагмент ...
--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 7000-7999/8000
...второй фрагмент...
--THIS_STRING_SEPARATES--
16.3. Толерантные приложения
Хотя этот документ специфицирует требования к генерации HTTP/1.1 сообщений, не все приложения будут корректны.
Мы, следовательно, рекомендуем, чтобы рабочие приложения были толерантны (терпимы) к некоторым отклонениям от требований, при условии, что эти отклонения можно однозначно интерпретировать. Клиенту следует быть толерантным при разборе Status-Line, а серверу - при разборе Request-Line. В частности, им следует воспринимать любое число символов SP или HT между полями, хотя требуется только один пробел (SP). Терминатором строки полей заголовков сообщения является CRLF. Однако рекомендуется, чтобы приложение при разборе таких заголовков распознавало в качестве терминатора строки одиночный символ LF и игнорировала предыдущий символ CR. Символьный набор тела объекта должен быть снабжен меткой. Метка не нужна только для набора US-ASCII или ISO-8859-1. Правила разбора и кодирования дат и пр. включают в себя предположение, что HTTP/1.1 клиенты и кэши должны предполагать, что даты, следующие документу RFC-850 и относящиеся ко времени 50 лет в будущем, на самом деле относятся к прошлому (это помогает решить проблему "2000-го года").
Приложение HTTP/1.1 может внутри представлять время истечения годности раньше, чем истинное значение, но не должно представлять его позднее истинного значения.
Все вычисления, относящиеся ко времени пригодности должны выполняться в шкале GMT (по Гринвичу). Местные временные зоны не должны оказывать влияния на вычисления и сравнение возраста и времени пригодности.
Если заголовок HTTP несет в себе некорректное значение даты с временной зоной отличной от GMT, значение должно быть преобразовано в GMT.
16.4. Различие между объектами HTTP и MIME
HTTP/1.1 использует много конструкций, определенных для электронной почты Интернет (RFC 822) и MIME (Multipurpose Internet Mail Extensions), для обеспечения пересылки объектов в различных представлениях. MIME [7] обслуживает электронную почту, а HTTP имеет лишь ряд черт, которые отличают его от MIME. Эти отличия тщательно подобраны, чтобы оптимизировать работу в условиях двоичных соединений, с тем чтобы достичь большей свободы в использовании новых типов сред.
Прокси и шлюзы должны по возможности исключать такие отличия и обеспечивать соответствующие преобразования там, где это нужно.
16.4.1. Преобразование к канонической форме
MIME требует, чтобы почтовый объект Интернет перед посылкой был преобразован в каноническую форму. Раздел 2.7.1 описывает формы, допустимые для подтипов типа среды "text" при пересылке с использованием HTTP. MIME требует, чтобы содержимое типа "text" представляло разрывы строк в виде последовательности символов CRLF и запрещает использование CR или LF отдельно. Для обозначения разрыва строки HTTP позволяет использовать CRLF, одиночный CR и одиночный LF. Всюду где возможно, прокси и шлюзы между средами HTTP и MIME должны преобразовать все разрывы строк для текстовых типов среды, как это описано в разделе 2.7.1. Заметьте однако, что это может вызвать сложности в присутствии кодирования содержимого, а также вследствие того, что HTTP допускает применение символьных наборов, которые не используют октеты 13 и 10 для представления CR и LF, так как для этих целей здесь служат многобайтовые последовательности.
16.4.2. Преобразование форматов даты
Для того чтобы упростить сравнение, HTTP/1.1 использует ограниченный набор форматов даты (раздел 2.3.1). Прокси и шлюзы должны позаботиться о преобразовании полей заголовков даты в один из допустимых форматов всякий раз, когда это необходимо (при получении данных от других протоколов).
16.4.3. Введение кодирования содержимого
MIME не содержит какого-либо эквивалента полю заголовка Content-Encoding HTTP/1.1. Так как это поле работает как модификатор типа среды, прокси и шлюзы между HTTP и MIME протоколами должны или изменить значение поля заголовка Content-Type или декодировать тело объекта, прежде чем переадресовывать сообщение. Некоторые экспериментальные приложения Content-Type для почты Интернет используют параметр типа среды ";conversions=" для выполнения операции, аналогичной Content-Encoding. Однако, этот параметр не является частью MIME.
16.4.4. No Content-Transfer-Encoding
HTTP не использует поле MIME CTE (Content-Transfer-Encoding). Прокси и шлюзы от MIME к HTTP должны удалять любую не идентичность CTE ("quoted-printable" или "base64") кодирования, прежде чем доставлять сообщение-отклик клиенту HTTP.
Прокси и шлюзы от HTTP к MIME ответственны за то, чтобы сообщения имели корректные форматы и кодировки для безопасной транспортировки, (где безопасная транспортировка определяется ограничениями используемого протокола). Такие прокси и шлюзы должны помечать информацию согласно Content-Transfer-Encoding, поступая так, мы улучшаем вероятность безопасной транспортировки с использованием протокола места назначения.
16.4.5. Поля заголовка в многофрагментных телах
В MIME, большинство полей заголовка в многофрагментных частях игнорируются, если только имя поля не начинается с "Content-". В HTTP/1.1, многофрагментные части тела могут содержать любые поля заголовков HTTP, которые имеют смысл для этой части.
16.4.6. Введение транспортного кодирования
HTTP/1.1 вводит поле заголовка Transfer-Encoding (раздел 13.40). Прокси/шлюзы должны удалять любое транспортное кодирование перед переадресацией сообщения через протокол MIME.
Процесс декодирования транспортного кода (раздел 2.6) может быть представлен в виде псевдо-программы:
length := 0
read chunk-size, chunk-ext (if any) and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to entity-body
length := length + chunk-size
read chunk-size and CRLF
}
read entity-header
while (entity-header not empty) {
append entity-header to existing header fields
read entity-header
}
Content-Length := length
Remove "chunked" from Transfer-Encoding
16.4.7. MIME-Version
HTTP не является протоколом, совместимым с MIME (смотри приложение 16.4). Однако HTTP/1.1 сообщения могут включать поле общего заголовка MIME-Version, для того чтобы указать, какая версия протокола MIME была использована для конструирования сообщения.
Использование заголовка поля MIME- Version отмечает, сообщение полностью соответствует протоколу MIME. Прокси/шлюзы несут ответственность за полную совместимость (где возможно), когда осуществляется передача HTTP сообщений в среду MIME.
MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
HTTP/1.1 использует по умолчанию версию MIME "1.0". Однако разбор сообщений HTTP/1.1 и семантика определяются данным документом, а не спецификацией MIME.
16.5. Изменения по отношению HTTP/1.0
Этот раздел обобщает основные отличия между версиями HTTP/1.0 и HTTP/1.1.
16.5.1. Изменения с целью упрощения распределенных WWW-сервером и экономии IP адресов
Требование того, чтобы клиенты и серверы воспринимали абсолютные URI (раздел 4.1.2) и поддерживали заголовки Host, откликались кодами ошибки при отсутствии заголовка Host (раздел 13.23) в запросе HTTP/1.1, являются наиболее важными изменениями, внесенными данной спецификацией.
Более старые HTTP/1.0 клиенты предполагают однозначное соответствие IP адресов и серверов. Изменения, описанные выше, позволяют Интернет поддерживать несколько WWW узлов с помощью одного IP-адреса. Высокая скорость роста WWW-сети, большое число уже существующих серверов делают крайне важным, чтобы реализации HTTP (включая усовершенствования существующих HTTP/1.0 приложений) корректно следовали перечисленным ниже требованиям:
Как клиент, так и сервер должны поддерживать заголовки запроса Host.
Заголовки Host необходимы в запросах HTTP/1.1.
Серверы должны откликаться кодом ошибки 400 (Bad Request), если запрос HTTP/1.1 не содержит заголовка Host.
Серверы должны воспринимать абсолютные URI.
16.6. Дополнительные функции
Это приложение документирует протокольные элементы, используемые некоторыми существующими реализациями HTTP, но не вполне корректно совместимыми с большинством HTTP/1.1 приложений.
16.6.1. Дополнительные методы запросов
16.6.1.1. Метод PATCH
Метод PATCH подобен PUT, за исключением того, что объект содержит список отличий между оригинальной версией ресурса, идентифицированного Request-URI, и желательной версией ресурса после операции PATCH.
Список отличий записывается в формате, определенном типом среды объекта (например, "application/diff"), и должен включать достаточную информацию, чтобы позволить серверу выполнить изменения по преобразованию ресурса из исходной версии в заказанную.
Если запрос проходит через кэш и Request-URI идентифицирует объект в кэше, этот объект должен быть удален из кэша. Отклики для этого метода не кэшируются.
Реальный метод определения того, как разместится скорректированный ресурс и что случится с его предшественником, определяется исключительно исходным сервером. Если оригинальная версия ресурса, который предполагается скорректировать, включает в себя поле заголовка Content-Version, объект запроса должен включать поле заголовка Derived-From, соответствующее значению оригинального поля заголовка Content-Version. Приложениям рекомендуется использовать эти поля для работы с версиями с целью разрешения соответствующих конфликтов. Запросы PATCH должны подчиняться требованиям к передаче сообщений, установленным в разделе 7.2. Кэши, которые реализуют PATCH, должны объявить кэшированные отклики недействительными, как это описано в разделе 12.10 для PUT.
16.6.1.2. Метод LINK
Метод LINK устанавливает один или более связей между ресурсами, идентифицированными Request-URI, и другими существующими ресурсами. Отличие между LINK и другими методами, допускающими установление связей между ресурсами, заключается в том, что метод LINK не позволяет послать в запросе любое тело сообщения и не вызывает непосредственно создания новых ресурсов. Если запрос проходит через кэш и Request-URI идентифицирует кэшированный объект, этот объект должен быть удален из кэша. Отклики на этот метод не кэшируются. Кэши, которые реализуют LINK, должны объявить кэшированные отклики непригодными, как это определено в разделе 12.10 для PUT.
16.6.1.3. Метод UNLINK
Метод UNLINK удаляет одну или более связей между ресурсами, идентифицированными Request-URI. Эти связи могут быть установлены с использованием метода LINK или каким-либо другим методом, поддерживающим заголовок Link.
Удаление связи с ресурсом не подразумевает, что ресурс перестает существовать или становится недоступным. Если запрос проходит через кэш и Request-URI идентифицирует кэшированный объект, этот объект должен быть удален из кэша. Отклики на этот метод не кэшируются. Кэши, которые реализуют UNLINK, должны объявить кэшированные отклики непригодными, как это определено в разделе 12.10 для PUT.
16.6.2. Определения дополнительных полей заголовка
16.6.2.1. Поле Alternates
Поле заголовка отклика Alternates было предложено в качестве средства исходного сервера для информирования клиента о других доступных представлениях запрошенного ресурса. При этом выдается информация об их специфических атрибутах, все это образует более надежное основание агенту пользователя для выбора представления, которое лучше соответствует желаниям пользователя (описано как согласование под управлением агента пользователя в разделе 11). Поле заголовка Alternates является ортогональным по отношению к полю заголовка Vary, вместе с тем они могут сосуществовать в сообщении без последствий для интерпретации отклика или доступных представлений. Ожидается, что поле Alternates предоставит заметное улучшение по сравнению с согласованием под управлением сервера, предоставляемым полем Vary для ресурсов, которые варьируются в общих пределах подобно типу и языку. Поле заголовка Alternates будет определено в будущей спецификации.
16.6.2.2. Поле Content-Version
Поле заголовка объекта Content-Version определяет метку версии, ассоциированную с отображением объекта. Вместе с полем Derived-From, 16.6.2.3, это позволяет группе людей вести разработку в интерактивном режиме.
Content-Version = "Content-Version" ":" quoted-string.
Примеры использования поля Content-Version:
Content-Version: "2.1.2"
Content-Version: "Fred 19950116-12:26:48"
Content-Version: "2.5a4-omega7"
16.6.2.3. Поле Derived-From
Поле заголовка объекта Derived-From может использоваться для индикации метки версии ресурса, из которого был извлечен объект до модификации, выполненной отправителем.
Это поле используется для того, чтобы помочь управлять процессом эволюции ресурса, в частности, когда изменения выполняются в параллель многими субъектами.
Derived-From = "Derived-From" ":" quoted-string.
Пример использования поля:
Derived-From: "2.1.1".
Поле Derived-From необходимо для запросов PUT и PATCH, если посланный объект был перед этим извлечен из того же URI и заголовок Content-Version был включен в объект, когда он последний раз извлекался.
16.6.2.4. Поле Link
Поле заголовка объекта Link предоставляет средства для описания взаимоотношений между ресурсами. Объект может включать много значений поля Link. Связи на уровне метаинформации обычно указывают на отношения типа структуры иерархии и пути прохода. Поле Link семантически эквивалентно элементу >LINK> в HTML[5].
Link | = "Link" ":"#("<" URI ">" *(";" link-param) |
link-param | = (("rel" "=" relationship ) |
| | ("rev" "=" relationship) |
| | ( "title" "=" quoted-string ) |
| | ( "anchor" "=" <"> URI <"> ) |
| | (link-extension )) |
link-extension | = token ["=" (token | quoted-string )] |
relationship | = sgml-name |
| | ( <"> sgml-name *( SP sgml-name) <"> ) |
sgml-name | = ALPHA *( ALPHA | DIGIT | "." | "-") |
Запись значений отношения не зависит от использования строчных или прописных букв и может быть расширена в рамках синтаксиса имен sgml. Параметр заголовка может быть использован для пометки места назначения связи, такой как используется при идентификации в рамках меню для пользователя. Параметр типа якорь может использоваться для индикации источника якоря, отличного от всего текущего ресурса, такого как фрагмент данного ресурса. Примеры использования:
Link: ; rel="Previous"
Link: ; rev="Made"; title="Tim Berners-Lee"
Первый пример указывает, что глава 2 предшествует данному ресурсу с точки зрения логического прохода.
Второй указывает, что лицо, ответственное за данный ресурс, имеет приведенный адрес электронной почты.
16.6.2.5. Поле URI
Поле заголовка URI использовалось в прошлых версиях данной спецификации как комбинация существующих полей заголовка Location, Content-Location и Vary. Его первоначальной целью являлось включение списка дополнительных URI для ресурса, включая имена и положение зеркал. Однако, стало ясно, что комбинация многих различных функций в пределах одного поля мешает эффективной их реализации. Более того, мы полагаем, что идентификация имени положения зеркал лучше осуществлять через поле заголовка Link. Поле заголовка URI было признано менее удобным, чем эти поля.
URI-header = "URI" ":" 1#( "<" URI ">" )
16.7. Совместимость с предыдущими версиями
HTTP/1.1 был специально спроектирован так, чтобы обеспечить совместимость с предыдущими версиями. Следует заметить, что на фазе разработки этой спецификации мы предполагали, что коммерческие HTTP/1.1 серверы будут следовать следующим правилам:
распознают формат Request-Line для запросов HTTP/0.9, 1.0 и 1.1;
воспринимают любой корректный запрос в формате HTTP/0.9, 1.0 или 1.1;
корректно откликаются сообщениями с той же версией, что использовал клиент.
Мы также ожидаем, что клиенты HTTP/1.1:
распознают формат откликов Status-Line для HTTP/1.0 и 1.1;
воспринимают любой корректный отклик в формате HTTP/0.9, 1.0 или 1.1.
Для большинства реализаций HTTP/1.0, каждое соединение устанавливается клиентом до посылки запроса и закрывается сервером после посылки отклика. Некоторые реализации используют версию Keep-Alive постоянного соединения, описанную в разделе 16.7.1.1.
16.7.1. Совместимость с постоянными соединениями HTTP/1.0
Некоторые клиенты и серверы могут пожелать быть совместимыми с некоторыми предшествующими реализациями HTTP/1.0 постоянных соединений клиента и сервера. Постоянные соединения в HTTP/1.0 должны согласовываться в явном виде, так как это не является вариантом по умолчанию.
Экспериментальные реализации постоянных соединений в HTTP/1. 0 не лишены ошибок. Проблема была в том, что некоторые существующие клиенты 1.0 могут посылать Keep-Alive прокси-серверу, которые не понимает Connection, и ошибочно переадресует его ближайшему серверу. Последний установит соединение Keep-Alive, что приведет к повисанию системы, так как прокси будет ждать close для отклика. В результате клиентам HTTP/1.0 должно быть запрещено использование Keep-Alive, когда они работают с прокси. Однако, взаимодействие с прокси является наиболее важным использованием постоянных соединений, по этой причине подобный запрет является не приемлемым. Следовательно, нам нужен какой-то другой механизм для индикации намерения установить постоянное соединение. Этот механизм должен быть безопасным даже при взаимодействии со старыми прокси, которые игнорируют Connection. Постоянные соединения для сообщений HTTP/1.1 работают по умолчанию; мы вводим новое ключевое слово (Connection: close) для декларации непостоянства соединения. Ниже описана оригинальная форма постоянных соединений для HTTP/1.0. Когда HTTP клиент соединяется с исходным сервером, он может послать лексему соединения Keep-Alive в дополнение к лексеме соединения Persist:
Connection: Keep-Alive.
Сервер HTTP/1.0 откликнется лексемой соединения Keep-Alive и клиент сможет установить постоянное (или Keep-Alive) соединение с HTTP/1.0. Сервер HTTP/1.1 может также установить постоянное соединение с клиентом HTTP/1.0 по получении лексемы соединения Keep-Alive. Однако, постоянное соединение с клиентом HTTP/1.0 не может быть использовано для по-фрагментного кодирования и, следовательно, должно использовать Content-Length для пометки конца каждого сообщения. Клиент не должен посылать лексему соединения Keep-Alive прокси-серверу, так как прокси-сервера HTTP/1.0 не следуют правилам HTTP/1.1 при разборе поля заголовка Connection.
16.7.1.1. Заголовок Keep-Alive
Когда лексема соединения Keep-Alive передана в рамках запроса или отклика, поле заголовка Keep-Alive может также присутствовать.
Поле заголовка Keep-Alive имеет следующую форму:
Keep-Alive-header = "Keep-Alive" ":" 0# keepalive-param
keepalive-param = param-name "=" value.
Заголовок Keep-Alive является опционным и используется, если передается параметр. HTTP/1.1 не определяет каких-либо параметров. Если посылается заголовок Keep-Alive, должна быть передана соответствующая лексема соединения. Заголовок Keep-Alive без лексемы соединения должен игнорироваться.
Система прокси-серверов приобрела всемирный характер и главная ее задача - минимизация транзитного трафика. Но часто могут возникать ситуация, когда требующийся объект содержится в проки-сервере, размещенном неподалеку, но не вдоль маршрута к исходному серверу. В этом случае запрос будет послан исходному серверу, что может создать дополнительную загрузку в большом числе внешних каналов. Представляется целесообразным обмен данными между прокси о заголовках объектов, хранящихся там. Такая информация может существенно снизить транзитный трафик. Можно попытаться изменить протокол так, чтобы объекты размещались в тех прокси, для которых средне-квадратичные расстояние до совокупности клиентов, запрашивавших этот ресурс, было минимальным. |
Предлагается несколько примеров для иллюстрации
Предлагается несколько примеров для иллюстрации потока пакетов и использования типовых атрибутов.
Процедуры Интернет
Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru
Данный раздел наиболее динамично развивающаяся часть Интернет-технологий. Одни виды услуг устаревают и выходят из употребления (Gopher, WAIS, MOSAIC), другие появляются вновь (поисковые машины, например Alta Vista, NetScape, MSExplorer и др.). В последнее время несравненно большее внимание стали уделять сетевой безопасности, системам поиска и диагностическим аспектам работы с сетями. Безопасность вышла на первые позиции из-за внедрения Интернет в область финансов и бизнеса. Последнее время активно развивается технология мультимедиа (интеграция с кабельным телевидением), сфера развлечений (игровые серверы) и информационно-поисковые системы на основе техники WWW.
Прочие применения
Существует большое разнообразие сетевых моделей, часть из них применяется в других областях науки. Во всех анализируемых случаях сеть поддерживает работу многих пользователей, трафик каждого из них следует через сеть одним или несколькими маршрутами. Обычно подразумевается, что можно произвести более точную оценку надежности, если учесть в расчетах параметры маршрутизации. В завершение нужно отметить, что нужно учитывать величины пропускной способности. Одна из наиболее интересных областей применения - городские сети наземного транспорта. В этом контексте инциденты, такие как аварии на автомагистралях, вызывают отказ сетевых узлов или дуг. Хотя нарушения связанности в сети городского транспорта происходят очень редко, вполне типично, когда отказ узла или связи вызывает ситуацию значительной перегрузки.
Наконец, применение многих средств оценки надежности сети, разработанных для мер, базирующихся на связности, распространяется на совершенно другие проблемы надежности, например, в сфере диспетчеризации и распределения ресурсов (в том числе операционных систем).
Простые ограничения
Вычисление многих коэффициентов оставляет нас, тем не менее, со многими коэффициентами, о которых мы не можем ничего сказать. Когда p близко к нулю, для всетерминальной надежности мы имеем
RelA(p)»Nn-1pn-1(1-p)m-n+1
а когда р близко к 1,
RelA(p) »1-Ссpm-c(1-p)c
В заданном определении полинома надежности точная формулировка аппроксимации Кельмана верна для всех значений р:
Nn-1pn-1(1-p)m-n+1ЈRelA(p) Ј1 - Ccpm-c(1-p)c
Таким образом, аппроксимации Кельмана могут рассматриваться как абсолютные ограничения на полином надежности. Существенным наблюдением здесь является то, что для крайних значений р любой член, содержащий Nn-1 или член, включающий Cc, доминирует над остальными членами. Мы знаем, что Ni+Cm-I=
и, следовательно, мы имеем
.
Это наблюдение подводит нас к простому набору ограничений:
В нижней границе каждый “неизвестный” Ni аппроксимируется нулем; известные коэффициенты равны для i < n-1 (нуль) i=n-1 (число деревьев связи), i=m-c (m-c-реберный субграф, чьи компоненты не равны минимальной мощности набора разрезов), и i > m-c (все возможные i-ребра субграфов). В верхней границе “неизвестный” Ni аппроксимируется
. Расширение для k-терминальной надежности достаточно прямолинейно: просто всюду подставляем
l вместо n-1. Нижняя граница, несмотря на это, оказывается недооценивающей Nl как 0; верхняя граница получается просто путем использования недооценки для самого
l.
Эти ограничения крайне слабы и предоставляют полезную информацию, только когда р лежит вблизи 0 или 1.
Протокол новостей NNTP
Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru
Современное общество предъявляет весьма жесткие требования ко времени получения событийной информации. Это могут быть технические новинки, политические новости, уведомления о событиях (произошедших или грядущих) и т.д. Одной из форм оперативной рассылки и получения информации является электронная почта (в частности система LISTSERV). В таких системах помимо воли клиента в его почтовом ящике, как правило, скапливается огромное количество сообщений. Причем в настоящее время здесь нет пока каких-либо механизмов фильтрации. Несколько иное решение предлагает протокол NNTP и сеть рассылки новостей USENET (cм. RFC-0977, Network News Transfer Protocol, B. Kantor, P.Lapsley. and RFC-1036, Standard for interchange of USENET messages, M.R. Horton, R. Adams). В USENET системе сообщение запоминается в базе данных сервера, а не в почтовых ящиках подписчиков. Региональный депозитарий снабжается специальным программным обеспечением, которое позволяет подписчику отбирать статьи, представляющие для него интерес. Система имеет индексацию, облегчающую поиск, и удаление устаревших статей.
Для кластеров ЭВМ, объединенных ETHERNET (или другой быстродействующей локальной сетью) представляется целесообразным сконцентрировать функции хранения и распределения новостей в одном узле. При этом клиент может запросить любую статью тогда, когда это ему нужно, и он не обязан предоставлять ресурсы для хранения копий статей. Учитывая то, что даже в небольшой локальной сети обычно достаточно много клиентов-подписчиков такая схема позволяет сэкономить достаточно большой объем дискового пространства. Следует учитывать, что интегральный поток новостей сегодня превышает 300 Мбайт в сутки.
Сервер новостей должен размещаться в локальной сети, так как именно в этом случае время доступа минимально. Этот сервер должен заниматься сбором новостей и созданием необходимых индексных файлов. При большом числе ЭВМ такая схема дает значительную экономию дискового пространства.
NNTP представляет собой протокол для рассылки, подписки, поиска и доставки новостей на основе надежного протокола поточного типа (например, TCP) с использованием схемы клиент-сервер. NNTP сконструирован так, что статья, записанная в одном из серверов, становится доступной для всех подписчиков-клиентов.
Протокол NNTP предполагает применения стандартных сообщений, формат которых следует рекомендациям RFC 850. NNTP-сервер обычно работает в фоновом режиме. В больших сетях, где число клиентов велико, возможно использование нескольких серверов новостей, которые образуют иерархическую систему. При этом клиент сначала пытается подключиться к ближайшему серверу. При неуспехе соединение либо абортируется, либо переадресуется другому серверу.
Единицей хранения на сервере является статья. Статьи составляют содержательную часть пересылаемых сообщений. В NNTP предусмотрены команды, которые обеспечивают непосредственный обмен статьями между взаимодействующими узлами (более эффективно, чем это позволяет, например, UUCP).
Традиционный метод рассылки новостей предполагает распространение статей от узла к узлу, так что каждый сервер пересылает другому все новости, которые имеет. При этом неизбежно дублирование, связанное с этим увеличение трафика и повышенный расход ресурсов ЭВМ. Но такая схема предельно проста и вполне оправдана, когда обмен новостями происходит один раз в сутки (дубликаты статей могут быть отфильтрованы позднее).
При использовании NNTP ЭВМ, обменивающиеся новостями, пользуются интерактивным механизмом в процессе принятия решения о том, какие статьи следует передать. При этом ЭВМ контактирует с одним или несколькими серверами новостей. Процедура начинается с запроса о формировании новых групп новостей, для чего выдается команда NEWGROUPS. Далее клиент делает запрос о наличии новых статей из групп, представляющих интерес (команда NEWNEWS). В ответ сервер высылает список статей, а клиент может запросить их присылку, если он их не имеет. В заключение клиент может сообщить серверу, какие новые статьи он получил в последнее время.
Сервер новостей, специфицированный в NNTP, использует поточный обмен (подобный TCP), а также набор команд и откликов, схожий с SMTP. Этот сервер является единственным интерфейсом между программами и базами данных, хранящими новости. Он не выполняет взаимодействия с пользователем или каких-либо операций презентационного уровня. Эти функции передаются программам клиента, которые имеют исчерпывающую информацию о среде. При работе через Интернет в рамках протокола TCP используется порт 119. На команды, посылаемые клиентом, предусмотрены текстовые и статусные отклики. Всякая сессия начинается с процедуры установления соединения между клиентом и сервером по инициативе клиента (например, с использованием протокола TCP).
Текст может посылаться только после цифрового статусного отклика. Текст имеет вид последовательности строк, каждая из которых завершается парой символов CR-LF. В конце текста всегда посылается строка, содержащая один символ (.), за которым следует CR-LF (как и в SMTP).
Если исходный текст содержит точку в начале строки, то она перед посылкой должна быть задублирована. Таким образом, клиент должен просматривать первые символы каждой полученной строки и, если это одиночная точка, прерывать дальнейший прием текста. Предполагается, что текстовый отклик будет отображен на дисплее пользователя, в то время как командно-статусный отклик интерпретируется программой клиента.
Статусный отклик представляет собой реакцию сервера на команду, полученную от клиента. Строки статусного отклика начинаются с 3-значного десятичного кода, достаточного для описания любого отклика. Некоторые коды являются предшественниками последующего текстового отклика. Первая цифра говорит об успехе, ошибке или процессе исполнения команды.
1xx | Информационное сообщение |
2xx | Команда ok |
3xx | Команда корректна, можно продолжать обмен. |
4xx | Команда корректна, но не может быть выполнена по какой-то причине. |
5xx | Команда неприменима, неверна или произошла серьезная ошибка в программе. |
Следующая цифра кода характеризует категорию отклика.
x0x | Соединение, установка режима, прочие сообщения |
x1x | Выбор группы новостей |
x2x | Выбор статьи |
x3x | Функции распределения |
x4x | Отправка адресату |
x8x | Нестандартное (частное применение) расширение |
x9x | Отладочный вывод |
Конкретное значение кодов отклика можно найти только в описании конкретной команды. Ниже приведен список кодов общего назначения, которые могут быть получены в любое время.
Некоторые статусные отклики могут иметь параметры (числа или имена). Число и тип параметров фиксировано для каждого конкретного отклика. Параметры отделяются от кода отклика и друг от друга одиночным пробелом. Все цифровые параметры имеют десятичное представление и могут начинаться с нулей. Все строковые параметры начинаются после пробела и завершаются пробелом или символьной парой CR-LF, то есть не могут содержать в себе пробелов. Любой текст, который не является параметром отклика, должен отделяться от последнего параметра, если таковой имеется, пробелом и завершаться пробелом.
Не специфицированные коды-отклики могут использоваться для специфических новых команд. Такой код должен относиться к категории x8x (см. таблицу, приведенную выше). Применение не специфицированных откликов для стандартных команд запрещено.
Коды категории x9x зарезервированы для отладочных целей. Так как большинство отладочных откликов можно рассматривать как информационные сообщения, для отладочных выдач зарезервирован диапазон кодов 190-199.
Ниже приведен список сообщений общего назначения, которые может послать NNTP сервер. Эти отклики не привязаны к каким-то конкретным командам и могут быть присланы в результате сбоя или каких-то других необычных обстоятельств.
Вообще говоря, коды 1xx могут игнорироваться; коды 200 или 201 посылаются при начальном подключении к NNTP серверу в зависимости от наличия разрешения пересылки. Код 400 отправляется, когда NNTP сервер прерывает обслуживание, например по запросу оператора, а коды 5xx указывают на то, что процедура не будет выполнена, по какой-то необычной причине.
100 | Поясняющий текст |
190 - 199 | Отладочный вывод |
200 | Сервер готов - отправка разрешена |
201 | Сервер готов - отправка запрещена |
400 | Обслуживание прерывается |
500 | Команда не распознана |
501 | Синтаксическая ошибка в команде |
502 | Доступ ограничен или нет разрешения |
503 | Ошибка в программе - команда не выполнена |
Команды записываются в этом документе прописными буквами, хотя NNTP сервер игнорирует регистр, в котором они напечатаны. Параметры команд, помещенные в квадратные скобки, являются опционными. Длина команды не должна превышать 512 байт.
Команды ARTICLE, BODY, HEAD и STAT
Существует две формы команды ARTICLE (и соответственно команд BODY, HEAD, и STAT), каждая из которых использует различные методы спецификации извлекаемой статьи. Когда за командой ARTICLE следует идентификатор сообщения в угольных скобках ("<" и ">"), используется первая форма команды; когда же имеется цифровой параметр или нет параметра совсем, реализуется вторая форма. Текст статьи присылается в виде текстового отклика.
Команды HEAD и BODY идентичны команде ARTICLE за исключением того, что они возвращают соответственно только строки заголовка или основной текст статьи.
Команда STAT похожа на команду ARTICLE за исключением того, что не присылается никакого текста. Выбирая номер сообщения в пределах группы, команда STAT служит для установки указателя статьи без пересылки какого-либо текста. Возвращаемый отклик содержит идентификатор сообщения. Использование команды STAT для выбора статей по их идентификатору вполне работоспособно, хотя и не слишком эффективно, так как такой отбор не изменяет текущий указатель статьи.
ARTICLE <message-id>
Команда отображает заголовок, пустую строку и текст заданной статьи. Идентификатор сообщения (message-ID) представляет собой идентификатор, представленный в заголовке статьи. Предполагается, что клиент получит идентификатор сообщения из списка, предоставляемого командой NEWNEWS. Команда не изменяет указателя текущей статьи.
ARTICLE [nnn]
Отображает заголовок, пустую строку и текст текущей или специфицированной статьи. Опционный параметр nnn представляет собой числовой идентификатор статьи (номер) в текущей группе новостей. Он должен быть выбран из диапазона, который был выдан при выборе группы. Если этого параметра нет, предполагается текущая статья.
Эта команда устанавливает указатель текущей статьи, если номер статьи указан корректно.
Откликом на команду будет номер текущей статьи, строка-идентификатор сообщения и собственно текст статьи. Присылаемая строка идентификатора сообщения представляет собой последовательность символов, заключенную в угловые скобки, которая извлечена из заголовка статьи (согласно RFC-850). Если идентификаторная строка заголовка в статье отсутствует, в угловых скобках будет записан нуль.
Так как поле идентификатора сообщения для каждой статьи уникально, оно может использоваться для поиска и удаления статей-дубликатов.
Отклики:
220 n <a> article retrieved - далее следует заголовок и сама статья (n = номер статьи, <a> = message-id)
221 n <a> article retrieved - далее следует заголовок
222 n <a> article retrieved - далее следует текст статьи
223 n <a> article retrieved - текст запрашивается отдельно
412 no newsgroup has been selected
420 no current article has been selected
423 no such article number in this group
430 no such article found
Команда GROUP ggg
Обязательный параметр ggg представляет собой имя группы новостей, которая должна быть выбрана. Список доступных групп новостей может быть получен с помощью команды LIST.
Отклик на успешный выбор группы возвращает номера первой и последней статьи в группе и оценку общего числа статей в группе. Оценка может быть и не вполне корректной, она равна или превосходит реальное число статей.
Когда с помощью данной команды группа выбрана, внутренний указатель статьи устанавливается на первую запись в группе. Если выбрана несуществующая группа, остается в силе выбор предыдущей группы. При наборе имени группы выбранный регистр (строчные или прописные буквы) не играет роли.
Отклики:
211 n f l s group selected
(n = оценка числа статей в группе; f = номер первой статьи в группе,
l = номер последней статьи в группе; s = имя группы.)
411 no such news group
Команда HELP
Команда дает краткое описание команд, которые может воспринять сервер.
Отклик на команду имеет текстовую форму и завершается строкой с одиночной точкой в начале.
Отклик: 100 help далее следует текст
Команда IHAVE <messageid>
Команда IHAVE информирует сервер о том, что клиент владеет статьей с идентификационным кодом <messageid>. Если сервер хочет скопировать статью, он пришлет отклик, предлагающий клиенту прислать ее. Если же сервер по какой-либо причине не хочет, чтобы ему прислали копию этой статьи (например, он ее уже имеет), он оповещает клиента об этом в своем отклике.
Если запрошена передача статьи, клиент должен выслать полный текст статьи, включая заголовок. Сервер в этом случае пришлет отклик, уведомляющий об успехе или неудаче этой операции.
Эта процедура отличается от команды POST в том, что последняя предназначена для пересылки полученных извне статей. Сервер может и не пересылать полученную статью другим серверам, в этом случае будут переданы коды ошибок 436 или 437.
Причиной отказа в рассылке может стать неверный код группы, ошибка в заголовке, неприемлемая длина статьи или ограничения дискового пространства. Обычно эти ограничения связаны с конфигурацией программного обеспечения на сервере.
Отклики:
235 article transferred ok
335 send article to be transferred. Завершение последовательностью <CR-LF>.<CR-LF>
435 article not wanted - статью посылать не следует
436 transfer failed - попытайтесь еще раз позднее
437 article rejected - и не пытайтесь
Так как некоторые серверы новостей не могут немедленно принять решение относительно рассылки конкретной статьи, прием статьи подтверждается (код 235), а позднее она может быть молча выброшена. Такое решение не идеально, возможно оно будет пересмотрено позднее.
Команда LAST
Внутренний указатель на статью устанавливается на предшествующую запись в текущей группе. Если указатель уже установлен на первую статью, отправляется сообщение об ошибке, а указатель остается неизменным.
Отклик содержит текущий номер статьи и ее идентификатор.
Отклики:
223 n a article retrieved - выборочно запрашивает текст
(n = номер статьи, a = уникальный идентификатор статьи)
412 no newsgroup selected
420 no current article has been selected
422 no previous article in this group
Команда LIST
Присылает список доступных групп новостей. Каждой группе новостей соответствует строка в следующем формате:
group last first p
где <group> название группы новостей, <last> номер последней известной статьи в данной группе, <first> номер первой статьи в группе, и <p> может быть либо 'y' либо 'n', указывая на наличие или отсутствие разрешения на рассылку соответственно.
Поля <first> и <last> являются числовыми. Они могут начинаться с нулей. Если код поля <last> превосходит код поля <first>, в файле данной группы новостей нет ни одной статьи.
Обратите внимание на то, что рассылка может быть запрещена клиенту, хотя команда LIST указывает на то, что она разрешена для данной группы новостей. Флаг рассылки существует для каждой группы новостей, так как некоторые группы подвергаются редактированию или обобщению и по этой причине не могут рассылаться. Присылаемая статья сначала по почте пересылается посреднику-редактору, который может осуществить ее рассылку. Это не зависит от права рассылки, предоставленного клиенту NNTP-сервером.
Заметьте, что пустой список может быть вполне корректным откликом и означает, что в данный момент на сервере нет новостей.
Отклик: | 215 далее следует список групп новостей |
Команда NEWGROUPS date time [GMT] [<distributions>]
Список групп новостей создан с <date и time> будет представлен в том же формате, что и в случае команды LIST.
Дата посылается в виде 6 цифр в формате ГГММДД, где ГГ последние две цифры года, MM - номер месяца (с нулем в начале, если требуется) и ДД номер дня в месяце. Дополнение для года берется из предположения о ближайшем тысячелетии, так 86 предполагает 1986, 30 - 2030, 99 - 1999, а 00 - 2000 годы.
Время должно характеризоваться также 6 цифрами в формате ЧЧMMСС, где ЧЧ - часы с начала суток в 24-часовом исчислении, MM минуты 00-59, а СС секунды 00-59.
Временная зона определяется сервером, в противном случае появляется символьная комбинация "GMT", в этом случае и время и дата привязаны к нулевому меридиану.
Опционный параметр "distributions" представляет собой список групп рассылки, заключенный в угловые скобки. Если параметр задан, рассылаемая часть новых групп новостей будет сравниваться с данным списком, и только при совпадении включается в список. Если необходимо использовать более одного такого фильтра, то они разделяются друг от друга запятыми в пределах угловых скобок.
Отклик: | 231 далее следует список новых групп |
Команда NEWNEWS newsgroups date time [GMT] [<distribution>]
Команда формирует список идентификаторов статей для заданной группы новостей, с датой после указанной. Для каждого идентификатора сообщения в списке выделяется одна строка. Список завершается строкой с одиночным символом точки, за которым следует CR-LF. Дата и время задаются в том же формате, что и для команды NEWGROUPS.
Для расширения зоны поиска в имени группы новостей можно использовать символ "*". Программа может подставить вместо звездочки любую комбинацию символов. Если вместо имени группы подставлен символ звездочка, поиск будет проведен по всем группам новостей.
Если звездочка в имени группы отсутствует, новые статьи будут искаться только в группе, имя которой приведено в качестве параметра запроса. Имя группы должно быть взято из списка доступных групп. Допускается спецификация нескольких групп (имена разделяются запятыми). После последнего имени группы не должно быть запятой.
Для отрицания соответствия может использоваться восклицательный знак. Это можно использовать для селективного исключения определенных групп новостей с целью сокращения размера списка. Например, спецификация групп "net.*,mod.*,!mod.map.*" определяет, что следует просмотреть все статьи в группах net.<что-то> и mod.<что-то> за исключением mod.map.<что-то>. Восклицательный знак должен использоваться непосредственно перед первым символом выбранного имени группы новостей.
Опционный параметр "distributions" представляет собой список групп рассылки, заключенный в треугольные скобки. Если этот параметр задан, производится отбор статей, соответствующих категориям, приведенным в списке distribution.
Заметьте, что пустой список является вполне допустимым откликом и означает отсутствие новых статей.
Отклик: | 230 далее следует список идентификаторов новых статей |
Команда NEXT
Команда перемещает указатель текущей статьи на следующую запись в текущей группе новостей. Если в группе нет больше статей, посылается сообщение об ошибке, а указатель текущей статьи остается не измененным.
В качестве отклика на команду возвращается номер текущей статьи и идентификатор сообщения. Никаких текстовых сообщений не посылается.
Отклики:
223 n a article retrieved, где n = номер статьи, a = уникальный идентификатор статьи
412 no newsgroup selected
420 no current article has been selected
421 no next article in this group
Команда POST
Если рассылка разрешена, в качестве отклика присылается код 340, который указывает, что статью, предназначенную для рассылки, можно присылать. Код отклика 440 указывает, что рассылка запрещена по причинам, зависящим от инсталляции.
Если рассылка разрешена, статья должна быть представлена в формате, описанном в RFC-850, и должна включать в себя все необходимые строки заголовка. После передачи заголовка и текста статьи от клиента к серверу последующий отклик будет свидетельствовать об успехе или неудаче доставки.
Сервер не осуществляет какой-либо фильтрации текста, и он в неизмененном виде будет рассылаться.
Отклики:
240 article posted ok
340 send article to be posted. Конец отмечается последовательностью <CR-LF>.<CR-LF>
440 posting not allowed
441 posting failed
Команда QUIT
Сервер подтверждает получение команды QUIT и затем закрывает канал связи с клиентом. Эта команда предоставляет клиенту корректную возможность сообщить NNTP-серверу, что все операции завершены и сессия закончена.
Если клиент просто разорвет связь, сервер должен также прекратить попытки взаимодействовать с клиентом.
Отклик: | 205 closing connection - goodbye! |
Команда SLAVE
Команда сообщает серверу, что он связывается не с пользователем, а с обслуживающим сервером (slave). Эта команда позволяет разделить случаи соединения сервера с отдельным пользователем и промежуточными обслуживающими серверами. Это может использоваться для предоставления приоритета запросам от таких клиентов, так как они обслуживают многих пользователей. Это может быть также использовано при возникновении проблем с внутренними ресурсами сервера, когда он может разорвать связи с некоторыми клиентами, сохраняя каналы с обслуживающими серверами. В NNTP-серверах, где приоритетное обслуживание не предусмотрено, команда должна все равно распознаваться и подтверждаться ее получение
Отклик: | 202 slave status noted |
Ниже приведены примеры (Примеры заимствованы из RFC-0977, Network News Transfer Protocol, B. Kantor, P.Lapsley. (Там их больше)) диалога между клиентом и сервером. Букве C: соответствует клиент, а букве S: - сервер.
Пример 1 - относительный доступ с помощью команды NEXT
S: | прослушивает порт 119 TCP |
C: | запрашивает соединения к порту 119 TCP |
S: | 200 wombatvax news server ready - posting ok |
(Клиент запрашивает список текущих новостей)
C: | LIST |
S: | 215 далее следует список групп новостей |
S: | net.wombats 00543 00501 y |
S: | net.unix-wizards 10125 10011 y |
(какая-то еще информация)
S: | net.idiots 00100 00001 n |
S: | . |
(Клиент выбирает группу новостей)
C: | GROUP net.unix-wizards |
S: | 211 104 10011 10125 net.unix-wizards group selected |
(В файле 104 статьи с 10011 по 10125)
(Клиент выбирает статью для чтения)
C: | STAT 10110 |
S: | 223 10110 <23445@sdcsvax.ARPA> article retrieved - statistics |
only (article 10110 selected, its message-id is
<23445@sdcsvax.ARPA>)
(Клиент просматривает заголовок)
C: | HEAD |
S: | 221 10110 <23445@sdcsvax.ARPA> article retrieved - далее следует заголовок |
S: | . |
(Клиент хочет просмотреть текст статьи)
C: | BODY |
S: | 222 10110 <23445@sdcsvax.ARPA> article retrieved - далее следует текст статьи |
S: | . |
(Клиент хочет просмотреть следующую статью данной группы)
C: | NEXT |
S: | 223 10113 <21495@nudebch.uucp> article retrieved - statistics only (статья 10113 является следующей в группе) |
(Клиент завершает сессию)
Пример 2 - абсолютный доступ к статье с помощью команды ARTICLE
S: | прослушивает порт 119 TCP |
C: | запрашивает соединения к порту 119 TCP |
S: | 201 UCB-VAX netnews server ready - рассылка запрещена |
C: | GROUP msgs |
S: | 211 103 402 504 msgs Your new group is msgs |
(Здесь 103 статьи с 402 по 504)
C: | ARTICLE 401 |
S: | 423 No such article in this newsgroup |
C: | ARTICLE 402 |
S: | 220 402 <4105@ucbvax.ARPA> Article retrieved |
S: | Следует заголовок текст и статьи |
S: | . |
C: | HEAD 403 |
S: | 221 403 <3108@mcvax.UUCP> Article retrieved, header follows |
S: | Следует заголовок статьи |
S: | . |
C: | QUIT |
S: | 205 UCB-VAX news server closing connection. Goodbye. |
Пример 3 - Команда NEWGROUPS
S: | прослушивает порт 119 TCP |
C: | запрашивает соединения к порту 119 TCP |
S: | 200 Imaginary Institute News Server ready (posting ok) |
(Клиент запрашивает группы новостей после 3-го апреля 1985)
C: | NEWGROUPS 850403 020000 |
S: | 231 Далее следуют группы новостей после 03/04/85 02:00:00 follow |
S: | net.music.gdead |
S: | net.games.sources |
S: | . |
C: | GROUP net.music.gdead |
S: | 211 0 1 1 net.music.gdead Newsgroup selected |
(Нет статей в этой группе новостей, номера первой и последней статей следует игнорировать)
C: | QUIT |
S: | 205 Imaginary Institute news server ceasing service. Bye! |
Пример 4 - рассылка новых статей
S: | прослушивает порт 119 TCP |
C: | запрашивает соединения к порту 119 TCP |
S: | 200 BANZAIVAX news server ready, рассылка разрешена. |
C: | POST |
S: | 340 Continue posting; Period on a line by itself to end |
C: | Передает статью в формате RFC850 |
C: | . |
S: | 240 Article posted successfully. |
C: | QUIT |
S: | 205 BANZAIVAX closing connection. Goodbye. |
Сессия завершается, канал закрывается.
Протокол пересылки файлов FTP
Семёнов Ю.А. (ГНЦ ИТЭФ), book.itep.ru
FTP довольно необычная процедура, так как поддерживает две логические связи между ЭВМ (Рис 4.5.4.1). Одна связь служит для удаленного доступа и использует протокол Telnet. Другая связь предназначена для обмена данными. Сервер производит операцию passive open для порта 21 и ждет соединения с клиентом. Клиент осуществляет операцию active open для порта 21. Канал остается активным до завершения процедуры FTP. TOS (тип IP-сервиса) соответствует минимуму задержки, так как этот канал используется для ручного ввода команд. Канал для передачи данных (TCP) формируется каждый раз для пересылки файлов. Канал открывается перед началом пересылки и закрывается по коду end_of_file (конец файла). IP-тип сервиса (TOS) в этом случае ориентирован на максимальную пропускную способность.
Конечный пользователь взаимодействует с протокольным интерпретатором, в задачи которого входит управление обменом информацией между пользователем и файловой системой, как местной, так и удаленной. Схема взаимодействия различных частей Internet при работе FTP изображена на рис. 4.5.4.1.
Сначала по запросу клиента формируется канал управления, который в дальнейшем используется для передачи команд от клиента и откликов от сервера. Информационный канал формируется сервером по команде клиента, он не должен существовать постоянно на протяжении всей FTP-сессии и может формироваться и ликвидироваться по мере необходимости. Канал управления может быть закрыт только после завершения информационного обмена. Для канала управления используется протокол Telnet. После того как управляющий канал сформирован, клиент может посылать по нему команды. Сервер воспринимает, интерпретирует эти команды и передает отклики.
Рис. 4.5.4.1 Схема работы протокола ftp.
Возможна и другая схема взаимодействия, когда по инициативе клиента осуществляется файловый обмен между двумя ЭВМ, ни одна из которых не является машиной клиента (см. рис. 4.5.4.2).
Рис. 4.5.4.2. Организация информационного обмена между двумя удаленными машинами
На фазе задания режима обмена предоставляются следующие возможности:
Команда Block сохраняет структуру логических записей файла.
Команда Stream устанавливает режим, при котором не производится пересылки контрольной информации для блоков. Это наиболее быстрый режим обмена, он работает по умолчанию.
Команда TYPE может задать режимы обмена IMAGE, ASCII или EBCDIC. Из них ASCII - используется по умолчанию. Режим EBCDIC применяется для обменов между ЭВМ, работающими с набором символов EBCDIC. Режим IMAGE предполагает обмен 8-битными байтами, используется для передачи двоичной (а не текстовой) информации. Более подробный список команд помещен ниже. Структурно информация может передаваться в виде файлов (структура по умолчанию), в виде последовательности записей (применимо для текстовых файлов ASCII или EBCDIC) или постранично (последняя структура не относится к числу рекомендуемых).
Для копирования файла из удаленного сервера используется команда GET, для копирования группы файлов - MGET, в последнем случае применяются символы заменители, например, MGET *.txt (или RFC-18*.txt, при этом скопируются файлы с RFC-1800.txt до RFC-1899.txt, если таковые существуют в текущем каталоге). Аналогом команды GET в какой-то степени является команда DIR (ls), только она переносит содержимое каталога, что для некоторых операционных систем эквивалентно. При использовании модификации mget проявляйте осторожность - вы можете заблокировать телекоммуникационный канал длительным копированием. Для записи файла в удаленный сервер применяется команда PUT. При операциях обмена обычно используется текущий каталог локальной ЭВМ. В вашем распоряжении всегда имеется возможность поменять местный каталог с помощью команды LCD или ее аналога. Любая команда обмена выполняется в несколько этапов:
Формирование канала под управлением клиента, так как именно клиент выдал команду get, dir, put и т.д.
Клиент выбирает произвольный номер порта на своей ЭВМ и осуществляет процедуру passive open для этого порта.
Клиент посылает номер порта серверу по каналу управления (порт 21), используя команду PORT. Можно обойтись и без команды PORT (используется тот же порт, что и в командном канале), но это увеличивает задержки и по этой причине не рекомендуется.
Сервер получает номер порта по каналу управления и выдает команду active open в указанный порт ЭВМ-клиента. Сервер для канала данных всегда использует порт с номером 20.
Рассмотрим пример FTP-сессии. Для этого выдадим команду (тексты, набираемые с клавиатуры, выделены курсивом):
FTP -d ns.itep.ru | (флаг -d означает установку отладочного режима, при котором выдаются все сообщения и внутренние команды на экран терминала). |
FTP Trying...Open
220- *** Welcome at FTP-Server ftp.ITEP.RU ***
220-
220 ns.itep.ru FTP server ready.
Userid for logging in on ns.itep.ru (SEMENOV)? semenov
FTP command: USER semenov
FTP response: 331 Password required for semenov.
331 Password required for semenov.
Password for logging in as semenov on ns.itep.ru? XXXXXXXX
PASS XXXXXXXX | (ввод пароля не отображается на экране) |
FTP response: 230 User semenov logged in.
230 User semenov logged in.
ftp:ns.itep.ru> hel |
(просьба выдать список доступных на данном сервере FTP-команд) |
Any unambiguous abbreviation for a command may be used.
Available commands are:
! | ? | acct | append | ascii | binary | bye | cd | debug |
delete | dir | drive | exit | fcd | fdir | fpwd | get | help |
iget | image | iput | lcd | ldir | lmkdir | local | login | lpwd |
ls | mdelete | mget | mkdir | mput | option | parent | passive | put |
pwd | quit | quote | rename | retrieve | rmdir | send | server | show |
stat | store | take | tenex | tget | tput | type | user | verbose |
version
ftp:ns.itep.ru> quit
FTP command: QUIT
FTP response: 221 Goodbye.
Уход из FTP производится по команде quit. В приведенном примере файловый обмен не производился, но и команда HELP требует переноса информации (также как и dir), так как вам выдается список команд, доступных на удаленном сервере. Из воспроизведенного списка команд, самая опасная mdelete, так как способна стереть целый каталог. Нетекстовые файлы (архивированные, графические и программные) следует пересылать в режиме binary.
Для перевода в этот режим используется одноименная команда. Для перехода из одного каталога в другой на удаленном сервере служит команда cd имя_каталога, а для возврата в предшествующий cd .. . Например, cd /pub/msdos.
Ссылка на объект, доступный через анонимное FTP, обычно записывается в виде:
Название ресурса | Имя сервера | Имя каталога в сервере. |
Например:
Internet-cmc | | /pub/communications/internet-cmc.txt |
ftp://ftp.rpi.edu/pub/communications/internet-cmc.txt
Internet-cmc (CMC - computer-mediated communication) -это межкомпьютерный обмен по сети Internet.
Ниже приведен список базовых команд FTP. Следует разделять внутренний набор команд FTP, которыми обмениваются клиент и сервер по командному каналу, и набор команд доступный пользователю. Служебные команды содержат три или четыре заглавные буквы. Эти наборы команд перекрываются лишь частично. Служебные команды унифицированы (они выделены в приведенном выше примере FTP-сессии жирным шрифтом, в помещенной ниже таблице эти команды представлены в ее верхней части), пользовательский же набор команд может варьироваться от реализации к реализации. Если выдать команду FTP без аргументов, система обычно откликается приглашением FTP> и вы можете выполнить некоторые из приведенных ниже команд (весь набор становится доступным только после идентификации).
Таблица 4.5.4.1
Субкоманды FTP | Описание |
ABOR |
Прерывание исполнения предыдущей FTP-команды и связанного с ней обмена |
ACCT<SP> <account-information> | Ввод идентификатора пользователя (ID); |
ALLO <SP> <десятичное целое> [<SP> R <SP> <десятичное целое>] |
Зарезервировать достаточно места (в байтах) для пересылки файла. Для файлов с постраничной структурой после символа R указывается число записей |
APPE <SP> <проход> |
Присовокупить передаваемые данные к файлу, указанному в параметре проход |
CDUP | Переход в каталог прародитель |
CWD <SP> <проход> | Изменить рабочий каталог (CD); |
DELE <SP> <проход> | Стереть файл (del); |
HELP |
Выдать справочную информацию о выполнимых командах |
HELP [<SP> <строка>] |
Выдать описание работы данной команды |
LIST [<SP> <проход>] |
Вывод списка файлов или каталогов (dir); |
MKD <SP> <проход> | Создать каталог |
MODE <SP> <код режима> | Режим обмена = поток, блоки или со сжатием |
NLST [<SP> <проход>] | Переслать оглавление каталога от сервера к клиенту |
NOOP | Пустая команда |
PASS <SP> <пароль> | Слово-пропуск (пароль) пользователя, заполняется пользователем |
PASV | Перевести сервер в режим прослушивания информационного порта на предмет установления соединения |
PORT <SP> <порт ЭВМ> | IP-адрес и номер порта клиента |
PWD | Выдать имя текущего каталога |
QUIT | Уход из FTP |
REIN | Завершение сессии и открытие новой |
REST <SP> <маркер> |
Возобновление обмена, начиная с места, указанного маркером |
RETR <SP> <проход> | Переслать копию файла (get) другому адресату |
RMD <SP> <проход> | Удалить каталог |
RNFR <SP> <проход> | Начало процедуры переименования файла (Rename From) |
RNTO <SP> <проход> |
Указание нового имени файла при переименовании (Rename To)_ |
SITE <SP> <строка> | Используется сервером для реализации локально специфических команд |
SMNT <SP> <проход> |
Позволяет пользователю смонтировать нужную файловую систему |
STAT | Выдать текущие значения параметров (STATUS) |
STOR <SP> <проход> |
Сервер должен запомнить полученные данные в виде файла |
STOU | Аналог команды STOR но записывает файл в текущий каталог и присваивает файлу уникальное имя |
STRU <SP> <код структуры> | Структура файла = файл, запись или страница |
SYST | Сервер сообщает тип системы |
TYPE <SP> <код типа> | Специфицирует тип информации, часто для этой цели используются команды binary и ASCII |
USER <SP> < [имя [пропуск]] > | Идентифицирует пользователя, запрашивается сервером |
? | тоже что и HELP; |
lcd | Изменить локальный каталог (на вашей ЭВМ); |
! | Выйти временно из FTP и уйти в Shell (UNIX) |
! команда | Исполнить команду Shell (UNIX) |
close | Прервать связь с удаленным сервером, оставаясь в FTP |
open [имя_ЭВМ] | Установить связь с указанным удаленным сервером |
dir | Выдать содержимое удаленного каталога |
<
/p>
<SP> пробел; все команды завершаются последовательностью <CRLF> возврат каретки + перевод строки. В квадратных скобках записан опционный аргумент. Выполнение любой команды можно прервать с помощью Ctrl-C.
Возможная форма обращения к FTP (SunOS 4.1): FTP [ -опции ] [ имя_ЭВМ ]
Допустимы следующие опции (модификаторы) команды:
-d | включение отладочного режима. |
-g | блокировка группового исполнения команд. |
-i |
Выключение интерактивного приглашения при множественной пересылке файлов. |
-v |
Отображает все отклики удаленного сервера и статистику обмена; этот режим работает обычно по умолчанию. |
В рамках процедуры FTP доступны следующие команды (приведенный перечень команд является неполным):
! [ команда ] |
Исполняется команда интерпретатора shell вашей ЭВМ (UNIX). Если имя команды явно не введено, система переходит в интерактивный режим shell. |
$ имя-макро [ аргументы ] | Выполняется макро, имя которого введено, аргументы используются этим макро. |
account [ пароль ] | Позволяет ввести пароль, необходимый для доступа в удаленный сервер. |
append имя_местного_файла [ имя_удаленного_файла ] |
Добавить местный файл к файлу на удаленном сервере. |
Bye | Завершает FTP-сессию. |
case | Переключает регистр символов, которыми записаны имена файлов на удаленной ЭВМ, в процессе выполнения команды MGET. Если case включен (по умолчанию выключен), все прописные буквы в именах файлов на удаленной ЭВМ, меняются при переносе в вашу ЭВМ на строчные. |
close | Завершает FTP-сессию и возвращает систему в интерактивный командный режим. Все описанные ранее макро стираются. |
debug [ debug-value ] | Включает/выключает режим отладки. Значение debug-value определяет отладочный уровень. Если отладка включена, FTP отображает на экране каждую команду, посылаемую удаленной ЭВМ. Эта информация помечается символом '-->'. |
dir [ удаленный каталог ] [ местный файл ] | Выдает на экран содержимое удаленного каталога. Если в качестве параметра указано имя местного файла, результат заносится в него. Если имя удаленного каталога не указано, команда выполняется для текущего каталога. |
disconnect | синоним close. |
hash | включает/выключает знак (#). Во включенном состоянии отмечается пересылка каждого блока, что позволяет визуально контролировать процесс обмена. |
macdef macro-name | Определяет макро. Последующие строки запоминаются в качестве текста макро с именем macro-name. Нулевая строка (двойное нажатие клавиши RETURN) завершает ввод текста макро. Можно ввести до 16 макро с суммарным объемом до 4096 символов. |
mdelete [ имена_файлов_на удаленной_ЭВМ ] | удаляет файлы на удаленной ЭВМ. |
open имя-ЭВМ [ port ] | устанавливает связь с указанным FTP-сервером (ЭВМ) через специфицированный порт. |
prompt | включает/выключает нтерактивные запросы со стороны ЭВМ. Это бывает полезным при выполнении групповых команд MPUT, MGET или MDELETE и позволяет проводить соответствующие операции над файлами выборочно. |
proxy | ftp-команда выполняет FTP-команду на вторичной удаленной ЭВМ. Эта команда позволяет связать два удаленных FTP-сервера и осуществить пересылку файлов между ними. Первой proxy-командой должна быть команда open, необходимая для связи со вторичным сервером. Введите команду proxy ?, чтобы проверить выполнимость этих команд на данном сервере. |
quit | синоним bye. |
recv |
удаленный_файл [ местный_файл ] синоним команды get. |
remotehelp [ имя_команды ] |
Запрашивает справочную информацию у удаленного FTP-сервера. Если имя_команды задано, запрашивается информация о конкретной команде. |
runique | Включает режим записи файлов в вашу ЭВМ только с уникальными именами. Если файл с таким именем уже существует, то новому файлу будет присвоено имя с расширением .1, если и такое имя уже есть, то с расширением .2. Это может продолжаться вплоть до расширения .99, после чего будет выдано сообщение об ошибке. Впрочем, такую ситуацию вообразить крайне трудно, если вы сами не наплодили файлов с цифровыми расширениями. Для команды mget это крайне полезная функция, которая застрахует вас от стирания ваших файлов из текущего каталога, имеющих имена, совпадающие с именами на удаленном сервере. По умолчанию runique не включено. |
send local-file [ remote-file ] | Синоним команды put. |
status | Отображает текущее состояние ftp. |
<
/p>
В депозитариях можно встретить файлы следующих разновидностей (все виды ниже перечисленных файлов пересылаются в режиме binary, а не ASCII):
Таблица 4.5.4.2
Тип файла | Пример записи имени файла | Программа обработки файла |
Архивированный файл | файл.Z | compress, uncompress |
tar-файл | файл.tar | tar |
Архивированный tar-файл | файл.tar.Z | tar, compress, uncompress |
файл.tar.gz | Применен архиватор GZIP |
uuencode-файл | файл.uue | uuencode, uudecode |
Архивированный uuencode-файл | файл.uue.Z | uuencode, uudecode, compress, uncompress |
zip-файл | файл.zip | pkzip, pkunzip |
shar-файл | файл.shar | shar, sh, unshar |
сжатый shar-файл | файл.shar.Z | shar, sh, unshar, compress, uncompress |
При выполнении FTP система возвращает трехразрядные десятичные коды-отклики, которые позволяют судить о корректности обмена и диагностировать процедуру. Выдача кода сопровождается текстом-комментарием. Первая цифра может принимать значения от 1 до 5. Структура кодов показана в таблице 4.5.4.3:
Таблица 4.5.4.3. Коды диагностики
Значение кода-отклика | Описание |
1yz | Позитивный предварительный отклик, который означает, что операция начата. До завершения процедуры следует ожидать как минимум еще один отклик |
2yz | Сигнал успешного завершения процедуры, говорящий о том, что можно ввести новую команду |
3yz | Положительный промежуточный отклик, указывающий на то, что команда воспринята, но для продолжения требуется дополнительная информация |
4yz | Негативный отклик, свидетельствующий о том, что команда не воспринята, но можно попробовать ее исполнить еще раз |
5yz | Отклик, говорящий о том, что команда не выполнена и не может быть выполнена вообще |
Значение кода "y" в вышеприведенной таблице может принимать значения от 0 до 5. Значения кодов "y" приведены ниже:
Значение кода-отклика | Описание |
x0z | Указывает на синтаксическую ошибку; синтаксис верен но команда не имеет смысла |
x1z | Указание на необходимость ввода дополнительной информации |
x2z | Отклик, связанный с управлением каналом связи |
x3z | Отклик для команд идентификации пользователя и проверки пароля |
x4z | Функция не определена |
x5z | Отклик, характеризующий состояние файловой системы |
Далее в тексте встречается выражение "анонимное FTP", это подразумевает следующую процедуру (см. также RFC-1635):
ftp> login: anonymous
ftp> password: [ваш полный E-mail адрес]
ftp> cd <имя_каталога > | (смена каталога) |
ftp> binary |
(если текст, например, архивирован, в противном случае команду выдавать не нужно) |
ftp> get <имя_файла> | (копирование файла) |
ftp> quit | (уход из процедуры) |
Следует иметь в виду, что некоторые анонимные FTP-серверы (также как, например, GOPHER-серверы) требуют, чтобы ЭВМ, с которой осуществляется ввод, имела не только IP-адрес, но и зарегистрированное в локальном DNS-сервере имя. Эти FTP-серверы, получив запрос, пытаются выяснить имя ЭВМ, так как они ведут "журнал посещений", и в случае неуспеха прерывают сессию. Таким образом, анонимное FTP может считаться таковым лишь условно, в смысле ненужности быть авторизованным на сервере, чтобы иметь к нему доступ. Конкретные примеры кодов статуса обмена для FTP
Таблица 4.5.4.4. Коды откликов
Код-отклик | Описание |
110 | Комментарий |
120 | Функция будет реализована через nnn минут |
125 | Канал открыт, обмен данными начат |
150 | Статус файла правилен, подготавливается открытие канала |
200 | Команда корректна |
211 |
Системный статус или отклик на справочный запрос |
212 | Состояние каталога |
213 | Состояние файла |
214 | Справочное поясняющее сообщение |
220 | Слишком много подключений к FTP-серверу (можете попробовать позднее). В некоторых версиях указывает на успешное завершение промежуточной процедуры |
221 |
Благополучное завершение по команде quit |
225 | Канал сформирован, но информационный обмен отсутствует |
226 |
Закрытие канала, обмен завершен успешно |
230 | Пользователь идентифицирован, продолжайте |
250 | Запрос прошел успешно |
331 | Имя пользователя корректно, нужен пароль |
332 | Для входа в систему необходима аутентификация |
421 | Процедура не возможна, канал закрывается |
425 | Открытие информационного канала не возможно |
426 | Канал закрыт, обмен прерван |
450 |
Запрошенная функция не реализована, файл не доступен, например, занят |
451 | Локальная ошибка, операция прервана |
452 | Ошибка при записи файла (не достаточно места) |
500 |
Синтаксическая ошибка, команда не может быть интерпретирована (возможно она слишком длинна) |
501 |
Синтаксическая ошибка (неверный параметр или аргумент) |
502 | Команда не используется (нелегальный тип MODE) |
503 | Неудачная последовательность команд |
504 | Команда не применима для такого параметра |
530 | Система не загружена (not logged in) |
532 | Необходима аутентификация для запоминания файла |
550 |
Запрошенная функция не реализована, файл не доступен, например, не найден |
552 | Запрошенная операция прервана, недостаточно выделено памяти |
В настоящее время разработаны версии FTP для работы с IPv6 (RFC-2428).