1/*
2 * Copyright (C) 2016 Canon Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted, provided that the following conditions
6 * are required to be met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Canon Inc. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY CANON INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL CANON INC. AND ITS CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#pragma once
30
31#include "ExceptionOr.h"
32#include "HTTPHeaderMap.h"
33#include <wtf/HashTraits.h>
34#include <wtf/Variant.h>
35#include <wtf/Vector.h>
36
37namespace WebCore {
38
39class FetchHeaders : public RefCounted<FetchHeaders> {
40public:
41 enum class Guard {
42 None,
43 Immutable,
44 Request,
45 RequestNoCors,
46 Response
47 };
48
49 using Init = Variant<Vector<Vector<String>>, Vector<WTF::KeyValuePair<String, String>>>;
50 static ExceptionOr<Ref<FetchHeaders>> create(Optional<Init>&&);
51
52 static Ref<FetchHeaders> create(Guard guard = Guard::None, HTTPHeaderMap&& headers = { }) { return adoptRef(*new FetchHeaders { guard, WTFMove(headers) }); }
53 static Ref<FetchHeaders> create(const FetchHeaders& headers) { return adoptRef(*new FetchHeaders { headers }); }
54
55 ExceptionOr<void> append(const String& name, const String& value);
56 ExceptionOr<void> remove(const String&);
57 ExceptionOr<String> get(const String&) const;
58 ExceptionOr<bool> has(const String&) const;
59 ExceptionOr<void> set(const String& name, const String& value);
60
61 ExceptionOr<void> fill(const Init&);
62 ExceptionOr<void> fill(const FetchHeaders&);
63 void filterAndFill(const HTTPHeaderMap&, Guard);
64
65 String fastGet(HTTPHeaderName name) const { return m_headers.get(name); }
66 bool fastHas(HTTPHeaderName name) const { return m_headers.contains(name); }
67 void fastSet(HTTPHeaderName name, const String& value) { m_headers.set(name, value); }
68
69 class Iterator {
70 public:
71 explicit Iterator(FetchHeaders&);
72 Optional<WTF::KeyValuePair<String, String>> next();
73
74 private:
75 Ref<FetchHeaders> m_headers;
76 size_t m_currentIndex { 0 };
77 Vector<String> m_keys;
78 };
79 Iterator createIterator() { return Iterator { *this }; }
80
81 const HTTPHeaderMap& internalHeaders() const { return m_headers; }
82
83 void setGuard(Guard);
84 Guard guard() const { return m_guard; }
85
86private:
87 FetchHeaders(Guard, HTTPHeaderMap&&);
88 FetchHeaders(const FetchHeaders&);
89
90 Guard m_guard;
91 HTTPHeaderMap m_headers;
92};
93
94inline FetchHeaders::FetchHeaders(Guard guard, HTTPHeaderMap&& headers)
95 : m_guard(guard)
96 , m_headers(WTFMove(headers))
97{
98}
99
100inline FetchHeaders::FetchHeaders(const FetchHeaders& other)
101 : RefCounted<FetchHeaders>()
102 , m_guard(other.m_guard)
103 , m_headers(other.m_headers)
104{
105}
106
107inline void FetchHeaders::setGuard(Guard guard)
108{
109 ASSERT(!m_headers.size());
110 m_guard = guard;
111}
112
113} // namespace WebCore
114
115namespace WTF {
116
117template<> struct EnumTraits<WebCore::FetchHeaders::Guard> {
118 using values = EnumValues<
119 WebCore::FetchHeaders::Guard,
120 WebCore::FetchHeaders::Guard::None,
121 WebCore::FetchHeaders::Guard::Immutable,
122 WebCore::FetchHeaders::Guard::Request,
123 WebCore::FetchHeaders::Guard::RequestNoCors,
124 WebCore::FetchHeaders::Guard::Response
125 >;
126};
127
128}
129