Home | History | Annotate | Download | only in serviceworkers
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "config.h"
      6 #include "FetchHeaderList.h"
      7 
      8 #include "core/fetch/FetchUtils.h"
      9 #include "platform/network/HTTPParsers.h"
     10 #include "wtf/PassOwnPtr.h"
     11 
     12 namespace blink {
     13 
     14 FetchHeaderList* FetchHeaderList::create()
     15 {
     16     return new FetchHeaderList();
     17 }
     18 
     19 FetchHeaderList* FetchHeaderList::createCopy()
     20 {
     21     FetchHeaderList* list = create();
     22     for (size_t i = 0; i < m_headerList.size(); ++i)
     23         list->append(m_headerList[i]->first, m_headerList[i]->second);
     24     return list;
     25 }
     26 
     27 FetchHeaderList::FetchHeaderList()
     28 {
     29 }
     30 
     31 FetchHeaderList::~FetchHeaderList()
     32 {
     33 }
     34 
     35 void FetchHeaderList::append(const String& name, const String& value)
     36 {
     37     // "To append a name/value (|name|/|value|) pair to a header list (|list|),
     38     // append a new header whose name is |name|, byte lowercased, and value is
     39     // |value|, to |list|."
     40     m_headerList.append(adoptPtr(new Header(name.lower(), value)));
     41 }
     42 
     43 void FetchHeaderList::set(const String& name, const String& value)
     44 {
     45     // "To set a name/value (|name|/|value|) pair in a header list (|list|), run
     46     // these steps:
     47     // 1. Byte lowercase |name|.
     48     // 2. If there are any headers in |list| whose name is |name|, set the value
     49     //    of the first such header to |value| and remove the others.
     50     // 3. Otherwise, append a new header whose name is |name| and value is
     51     //    |value|, to |list|."
     52     const String lowercasedName = name.lower();
     53     for (size_t i = 0; i < m_headerList.size(); ++i) {
     54         if (m_headerList[i]->first == lowercasedName) {
     55             m_headerList[i]->second = value;
     56             for (size_t j = i + 1; j < m_headerList.size(); ) {
     57                 if (m_headerList[j]->first == lowercasedName)
     58                     m_headerList.remove(j);
     59                 else
     60                     ++j;
     61             }
     62             return;
     63         }
     64     }
     65     m_headerList.append(adoptPtr(new Header(lowercasedName, value)));
     66 }
     67 
     68 size_t FetchHeaderList::size() const
     69 {
     70     return m_headerList.size();
     71 }
     72 
     73 void FetchHeaderList::remove(const String& name)
     74 {
     75     // "To delete a name (|name|) from a header list (|list|), remove all headers
     76     // whose name is |name|, byte lowercased, from |list|."
     77     const String lowercasedName = name.lower();
     78     for (size_t i = 0; i < m_headerList.size(); ) {
     79         if (m_headerList[i]->first == lowercasedName)
     80             m_headerList.remove(i);
     81         else
     82             ++i;
     83     }
     84 }
     85 
     86 bool FetchHeaderList::get(const String& name, String& result) const
     87 {
     88     const String lowercasedName = name.lower();
     89     for (size_t i = 0; i < m_headerList.size(); ++i) {
     90         if (m_headerList[i]->first == lowercasedName) {
     91             result = m_headerList[i]->second;
     92             return true;
     93         }
     94     }
     95     return false;
     96 }
     97 
     98 void FetchHeaderList::getAll(const String& name, Vector<String>& result) const
     99 {
    100     const String lowercasedName = name.lower();
    101     result.clear();
    102     for (size_t i = 0; i < m_headerList.size(); ++i) {
    103         if (m_headerList[i]->first == lowercasedName)
    104             result.append(m_headerList[i]->second);
    105     }
    106 }
    107 
    108 bool FetchHeaderList::has(const String& name) const
    109 {
    110     const String lowercasedName = name.lower();
    111     for (size_t i = 0; i < m_headerList.size(); ++i) {
    112         if (m_headerList[i]->first == lowercasedName)
    113             return true;
    114     }
    115     return false;
    116 }
    117 
    118 void FetchHeaderList::clearList()
    119 {
    120     m_headerList.clear();
    121 }
    122 
    123 bool FetchHeaderList::containsNonSimpleHeader() const
    124 {
    125     for (size_t i = 0; i < m_headerList.size(); ++i) {
    126         if (!FetchUtils::isSimpleHeader(AtomicString(m_headerList[i]->first), AtomicString(m_headerList[i]->second)))
    127             return true;
    128     }
    129     return false;
    130 }
    131 
    132 bool FetchHeaderList::isValidHeaderName(const String& name)
    133 {
    134     // "A name is a case-insensitive byte sequence that matches the field-name
    135     // token production."
    136     return isValidHTTPToken(name);
    137 }
    138 
    139 bool FetchHeaderList::isValidHeaderValue(const String& value)
    140 {
    141     // "A value is a byte sequence that matches the field-value token production
    142     // and contains no 0x0A or 0x0D bytes."
    143     return isValidHTTPHeaderValue(value);
    144 }
    145 
    146 } // namespace blink
    147