Ключ заголовка HTTP может быть повторен?

#http #header

#http #заголовок

Вопрос:

В JAVA HttpURLConnection основной логический код настроек заголовка запроса выглядит следующим образом:

 public synchronized void set(String k, String v) {
        for (int i = nkeys; --i >= 0;)
            if (k.equalsIgnoreCase(keys[i])) {
                values[i] = v;
                return;
            }
        add(k, v);
}
  

Проверено, что ключ должен быть уникальным, ключ должен сохранять взаимно однозначное соответствие со значением.

Напротив, в заголовочных полях модуля ответа структура определяется как запись >. То есть ключ не поддерживает взаимно однозначное сопоставление со значением.

Почему это? Имеет ли протокол HTTP соответствующее соглашение?

Добавьте: В HttpClient4 основной логический код настроек заголовка запроса следующим образом:

  /**
 * Replaces the first occurence of the header with the same name. If no header with
 * the same name is found the given header is added to the end of the list.
 *
 * @param header the new header that should replace the first header with the same
 * name if present in the list.
 */
public void updateHeader(final Header header) {
    if (header == null) {
        return;
    }
    // HTTPCORE-361 : we don't use the for-each syntax, i.e.
    //     for (Header header : headers)
    // as that creates an Iterator that needs to be garbage-collected
    for (int i = 0; i < this.headers.size(); i  ) {
        final Header current = this.headers.get(i);
        if (current.getName().equalsIgnoreCase(header.getName())) {
            this.headers.set(i, header);
            return;
        }
    }
    this.headers.add(header);
}
  

Заголовок ответа

 /**
 * Gets all of the headers with the given name.  The returned array
 * maintains the relative order in which the headers were added.
 *
 * <p>Header name comparison is case insensitive.
 *
 * @param name the name of the header(s) to get
 *
 * @return an array of length >= 0
 */
public Header[] getHeaders(final String name) {
    final List<Header> headersFound = new ArrayList<Header>();
    // HTTPCORE-361 : we don't use the for-each syntax, i.e.
    //     for (Header header : headers)
    // as that creates an Iterator that needs to be garbage-collected
    for (int i = 0; i < this.headers.size(); i  ) {
        final Header header = this.headers.get(i);
        if (header.getName().equalsIgnoreCase(name)) {
            headersFound.add(header);
        }
    }

    return headersFound.toArray(new Header[headersFound.size()]);
}
  

Они совпадают с HttpURLConnection

Ответ №1:

Имеет ли протокол HTTP соответствующее соглашение?

Да. В разделе 4.2 RFC 2616 «Заголовки сообщений» говорится:

Несколько полей заголовка сообщения с одинаковым именем поля МОГУТ присутствовать в сообщении тогда и только тогда, когда все значение поля для этого поля заголовка определено как список, разделенный запятыми [т. Е. #(значения)]. Должна быть возможность объединить несколько полей заголовка в одну пару «имя поля: значение поля» без изменения семантики сообщения, путем добавления каждого последующего значения поля к первому, разделенного запятой. Порядок, в котором принимаются поля заголовка с одинаковым именем поля, поэтому важен для интерпретации объединенного значения поля, и, следовательно, прокси-сервер НЕ ДОЛЖЕН изменять порядок значений этих полей при пересылке сообщения.

Это дополнительно расширено в разделе 3.2.2 RFC 7230 «Порядок полей»:

Отправитель НЕ ДОЛЖЕН генерировать несколько полей заголовка с одинаковым именем поля в сообщении, если только либо все значение поля для этого поля заголовка не определено в виде списка, разделенного запятыми [т. Е. #(значения)], либо поле заголовка не является хорошо известным исключением (как указано ниже).).

Получатель МОЖЕТ объединить несколько полей заголовка с одинаковым именем поля в одну пару «имя поля: значение поля», не изменяя семантику сообщения, добавляя каждое последующее значение поля к объединенному значению поля по порядку, разделенному запятой. Порядок, в котором принимаются поля заголовка с одинаковым именем поля, следовательно, важен для интерпретации объединенного значения поля; прокси-сервер НЕ ДОЛЖЕН изменять порядок значений этих полей при пересылке сообщения.