netwerk/protocol/http/nsHttpHeaderArray.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim: set sw=4 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef nsHttpHeaderArray_h__
     8 #define nsHttpHeaderArray_h__
    10 #include "nsHttp.h"
    11 #include "nsTArray.h"
    12 #include "nsString.h"
    14 class nsIHttpHeaderVisitor;
    16 namespace mozilla { namespace net {
    18 class nsHttpHeaderArray
    19 {
    20 public:
    21     const char *PeekHeader(nsHttpAtom header) const;
    23     // Used by internal setters: to set header from network use SetHeaderFromNet
    24     nsresult SetHeader(nsHttpAtom header, const nsACString &value,
    25                        bool merge = false);
    27     // Merges supported headers. For other duplicate values, determines if error
    28     // needs to be thrown or 1st value kept.
    29     nsresult SetHeaderFromNet(nsHttpAtom header, const nsACString &value);
    31     nsresult GetHeader(nsHttpAtom header, nsACString &value) const;
    32     void     ClearHeader(nsHttpAtom h);
    34     // Find the location of the given header value, or null if none exists.
    35     const char *FindHeaderValue(nsHttpAtom header, const char *value) const
    36     {
    37         return nsHttp::FindToken(PeekHeader(header), value,
    38                                  HTTP_HEADER_VALUE_SEPS);
    39     }
    41     // Determine if the given header value exists.
    42     bool HasHeaderValue(nsHttpAtom header, const char *value) const
    43     {
    44         return FindHeaderValue(header, value) != nullptr;
    45     }
    47     nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor);
    49     // parse a header line, return the header atom and a pointer to the
    50     // header value (the substring of the header line -- do not free).
    51     nsresult ParseHeaderLine(const char *line,
    52                              nsHttpAtom *header=nullptr,
    53                              char **value=nullptr);
    55     void Flatten(nsACString &, bool pruneProxyHeaders=false);
    57     uint32_t Count() const { return mHeaders.Length(); }
    59     const char *PeekHeaderAt(uint32_t i, nsHttpAtom &header) const;
    61     void Clear();
    63     // Must be copy-constructable and assignable
    64     struct nsEntry
    65     {
    66         nsHttpAtom header;
    67         nsCString value;
    69         struct MatchHeader {
    70           bool Equals(const nsEntry &entry, const nsHttpAtom &header) const {
    71             return entry.header == header;
    72           }
    73         };
    74     };
    76 private:
    77     int32_t LookupEntry(nsHttpAtom header, const nsEntry **) const;
    78     int32_t LookupEntry(nsHttpAtom header, nsEntry **);
    79     void MergeHeader(nsHttpAtom header, nsEntry *entry, const nsACString &value);
    81     // Header cannot be merged: only one value possible
    82     bool    IsSingletonHeader(nsHttpAtom header);
    83     // For some headers we want to track empty values to prevent them being
    84     // combined with non-empty ones as a CRLF attack vector
    85     bool    TrackEmptyHeader(nsHttpAtom header);
    87     // Subset of singleton headers: should never see multiple, different
    88     // instances of these, else something fishy may be going on (like CLRF
    89     // injection)
    90     bool    IsSuspectDuplicateHeader(nsHttpAtom header);
    92     // All members must be copy-constructable and assignable
    93     nsTArray<nsEntry> mHeaders;
    95     friend struct IPC::ParamTraits<nsHttpHeaderArray>;
    96 };
    99 //-----------------------------------------------------------------------------
   100 // nsHttpHeaderArray <private>: inline functions
   101 //-----------------------------------------------------------------------------
   103 inline int32_t
   104 nsHttpHeaderArray::LookupEntry(nsHttpAtom header, const nsEntry **entry) const
   105 {
   106     uint32_t index = mHeaders.IndexOf(header, 0, nsEntry::MatchHeader());
   107     if (index != UINT32_MAX)
   108         *entry = &mHeaders[index];
   109     return index;
   110 }
   112 inline int32_t
   113 nsHttpHeaderArray::LookupEntry(nsHttpAtom header, nsEntry **entry)
   114 {
   115     uint32_t index = mHeaders.IndexOf(header, 0, nsEntry::MatchHeader());
   116     if (index != UINT32_MAX)
   117         *entry = &mHeaders[index];
   118     return index;
   119 }
   121 inline bool
   122 nsHttpHeaderArray::IsSingletonHeader(nsHttpAtom header)
   123 {
   124     return header == nsHttp::Content_Type        ||
   125            header == nsHttp::Content_Disposition ||
   126            header == nsHttp::Content_Length      ||
   127            header == nsHttp::User_Agent          ||
   128            header == nsHttp::Referer             ||
   129            header == nsHttp::Host                ||
   130            header == nsHttp::Authorization       ||
   131            header == nsHttp::Proxy_Authorization ||
   132            header == nsHttp::If_Modified_Since   ||
   133            header == nsHttp::If_Unmodified_Since ||
   134            header == nsHttp::From                ||
   135            header == nsHttp::Location            ||
   136            header == nsHttp::Max_Forwards;
   137 }
   139 inline bool
   140 nsHttpHeaderArray::TrackEmptyHeader(nsHttpAtom header)
   141 {
   142     return header == nsHttp::Content_Length ||
   143            header == nsHttp::Location;
   144 }
   146 inline void
   147 nsHttpHeaderArray::MergeHeader(nsHttpAtom header,
   148                                nsEntry *entry,
   149                                const nsACString &value)
   150 {
   151     if (value.IsEmpty())
   152         return;   // merge of empty header = no-op
   154     // Append the new value to the existing value
   155     if (header == nsHttp::Set_Cookie ||
   156         header == nsHttp::WWW_Authenticate ||
   157         header == nsHttp::Proxy_Authenticate)
   158     {
   159         // Special case these headers and use a newline delimiter to
   160         // delimit the values from one another as commas may appear
   161         // in the values of these headers contrary to what the spec says.
   162         entry->value.Append('\n');
   163     } else {
   164         // Delimit each value from the others using a comma (per HTTP spec)
   165         entry->value.AppendLiteral(", ");
   166     }
   167     entry->value.Append(value);
   168 }
   170 inline bool
   171 nsHttpHeaderArray::IsSuspectDuplicateHeader(nsHttpAtom header)
   172 {
   173     bool retval =  header == nsHttp::Content_Length         ||
   174                      header == nsHttp::Content_Disposition    ||
   175                      header == nsHttp::Location;
   177     MOZ_ASSERT(!retval || IsSingletonHeader(header),
   178                "Only non-mergeable headers should be in this list\n");
   180     return retval;
   181 }
   183 }} // namespace mozilla::net
   185 #endif

mercurial