blob: aa54baf14708ef03ec9caab46e6a987e2eab3fb8 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/fetch/FetchHeaderList.h"
#include "core/fetch/FetchUtils.h"
#include "platform/network/HTTPParsers.h"
#include "wtf/PtrUtil.h"
namespace blink {
FetchHeaderList* FetchHeaderList::create()
{
return new FetchHeaderList();
}
FetchHeaderList* FetchHeaderList::clone()
{
FetchHeaderList* list = create();
for (size_t i = 0; i < m_headerList.size(); ++i)
list->append(m_headerList[i]->first, m_headerList[i]->second);
return list;
}
FetchHeaderList::FetchHeaderList()
{
}
FetchHeaderList::~FetchHeaderList()
{
}
void FetchHeaderList::append(const String& name, const String& value)
{
// "To append a name/value (|name|/|value|) pair to a header list (|list|),
// append a new header whose name is |name|, byte lowercased, and value is
// |value|, to |list|."
m_headerList.append(wrapUnique(new Header(name.lower(), value)));
}
void FetchHeaderList::set(const String& name, const String& value)
{
// "To set a name/value (|name|/|value|) pair in a header list (|list|), run
// these steps:
// 1. Byte lowercase |name|.
// 2. If there are any headers in |list| whose name is |name|, set the value
// of the first such header to |value| and remove the others.
// 3. Otherwise, append a new header whose name is |name| and value is
// |value|, to |list|."
const String lowercasedName = name.lower();
for (size_t i = 0; i < m_headerList.size(); ++i) {
if (m_headerList[i]->first == lowercasedName) {
m_headerList[i]->second = value;
for (size_t j = i + 1; j < m_headerList.size(); ) {
if (m_headerList[j]->first == lowercasedName)
m_headerList.remove(j);
else
++j;
}
return;
}
}
m_headerList.append(wrapUnique(new Header(lowercasedName, value)));
}
String FetchHeaderList::extractMIMEType() const
{
// To extract a MIME type from a header list (headers), run these steps:
// 1. Let MIMEType be the result of parsing `Content-Type` in headers.
String mimeType;
if (!get("Content-Type", mimeType)) {
// 2. If MIMEType is null or failure, return the empty byte sequence.
return String();
}
// 3. Return MIMEType, byte lowercased.
return mimeType.lower();
}
size_t FetchHeaderList::size() const
{
return m_headerList.size();
}
void FetchHeaderList::remove(const String& name)
{
// "To delete a name (|name|) from a header list (|list|), remove all headers
// whose name is |name|, byte lowercased, from |list|."
const String lowercasedName = name.lower();
for (size_t i = 0; i < m_headerList.size(); ) {
if (m_headerList[i]->first == lowercasedName)
m_headerList.remove(i);
else
++i;
}
}
bool FetchHeaderList::get(const String& name, String& result) const
{
const String lowercasedName = name.lower();
for (size_t i = 0; i < m_headerList.size(); ++i) {
if (m_headerList[i]->first == lowercasedName) {
result = m_headerList[i]->second;
return true;
}
}
return false;
}
void FetchHeaderList::getAll(const String& name, Vector<String>& result) const
{
const String lowercasedName = name.lower();
result.clear();
for (size_t i = 0; i < m_headerList.size(); ++i) {
if (m_headerList[i]->first == lowercasedName)
result.append(m_headerList[i]->second);
}
}
bool FetchHeaderList::has(const String& name) const
{
const String lowercasedName = name.lower();
for (size_t i = 0; i < m_headerList.size(); ++i) {
if (m_headerList[i]->first == lowercasedName)
return true;
}
return false;
}
void FetchHeaderList::clearList()
{
m_headerList.clear();
}
bool FetchHeaderList::containsNonSimpleHeader() const
{
for (size_t i = 0; i < m_headerList.size(); ++i) {
if (!FetchUtils::isSimpleHeader(AtomicString(m_headerList[i]->first), AtomicString(m_headerList[i]->second)))
return true;
}
return false;
}
bool FetchHeaderList::isValidHeaderName(const String& name)
{
// "A name is a case-insensitive byte sequence that matches the field-name
// token production."
return isValidHTTPToken(name);
}
bool FetchHeaderList::isValidHeaderValue(const String& value)
{
// "A value is a byte sequence that matches the field-value token production
// and contains no 0x0A or 0x0D bytes."
return isValidHTTPHeaderValue(value);
}
} // namespace blink