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