1616#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_HTTP_HEADER_H
1717
1818#include " google/cloud/version.h"
19+ #include " absl/container/flat_hash_map.h"
20+ #include " absl/strings/ascii.h"
1921#include < string>
2022#include < vector>
2123
@@ -24,17 +26,67 @@ namespace cloud {
2426namespace rest_internal {
2527GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2628
29+ // This class represents a case-insensitive HTTP header name by storing all
30+ // strings in lower-case.
31+ class HttpHeaderName {
32+ public:
33+ HttpHeaderName () = default ;
34+ HttpHeaderName (std::string name) // NOLINT(google-explicit-constructor)
35+ : name_(std::move(name)) {
36+ absl::AsciiStrToLower (&name_);
37+ }
38+ HttpHeaderName (std::string_view name) // NOLINT(google-explicit-constructor)
39+ : HttpHeaderName(std::string{name}) {}
40+ HttpHeaderName (char const * name) // NOLINT(google-explicit-constructor)
41+ : HttpHeaderName(std::string{name}) {}
42+
43+ operator std::string () const { // NOLINT(google-explicit-constructor)
44+ return name_;
45+ }
46+ operator std::string_view () const { // NOLINT(google-explicit-constructor)
47+ return name_;
48+ }
49+ operator char const *() const { // NOLINT(google-explicit-constructor)
50+ return name_.c_str ();
51+ }
52+
53+ bool empty () const { return name_.empty (); }
54+ std::string const & name () const { return name_; }
55+
56+ friend bool operator ==(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
57+ return lhs.name_ == rhs.name_ ;
58+ }
59+ friend bool operator <(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
60+ return lhs.name_ < rhs.name_ ;
61+ }
62+ friend bool operator !=(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
63+ return !(lhs == rhs);
64+ }
65+ friend bool operator >(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
66+ return !(lhs < rhs) && (lhs != rhs);
67+ }
68+ friend bool operator >=(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
69+ return !(lhs < rhs);
70+ }
71+ friend bool operator <=(HttpHeaderName const & lhs, HttpHeaderName const & rhs) {
72+ return !(lhs > rhs);
73+ }
74+
75+ private:
76+ std::string name_;
77+ };
78+
2779/* *
2880 * This class represents an HTTP header field.
2981 */
3082class HttpHeader {
3183 public:
3284 HttpHeader () = default ;
33- explicit HttpHeader (std::string key);
34- HttpHeader (std::string key , std::string value );
35- HttpHeader (std::string key, std::initializer_list< char const *> values );
36-
37- HttpHeader (std::string key, std::vector<std::string> values);
85+ explicit HttpHeader (HttpHeaderName key);
86+ explicit HttpHeader (std::pair<std:: string, std::string> header );
87+ HttpHeader (HttpHeaderName key, std::string value );
88+ HttpHeader (HttpHeaderName key, std::initializer_list< char const *> values);
89+ HttpHeader (HttpHeaderName key, std::vector<std::string> values);
3890
3991 HttpHeader (HttpHeader&&) = default ;
4092 HttpHeader& operator =(HttpHeader&&) = default ;
@@ -57,14 +109,20 @@ class HttpHeader {
57109 friend bool operator <(HttpHeader const & lhs, HttpHeader const & rhs);
58110
59111 // If the key is empty, the entire HttpHeader is considered empty.
60- bool empty () const { return key_.empty (); }
112+ bool empty () const { return name_.empty (); }
113+
114+ // Number of values.
115+ std::size_t size () const { return values_.size (); }
61116
62117 // Checks to see if the values are empty. Does not inspect the key field.
63118 bool EmptyValues () const { return values_.empty (); }
64119
65120 // Performs a case-insensitive comparison of the key.
66121 bool IsSameKey (HttpHeader const & other) const ;
67- bool IsSameKey (std::string const & key) const ;
122+ bool IsSameKey (std::string_view key) const ;
123+
124+ std::string name () const { return name_; }
125+ std::vector<std::string> const & values () const { return values_; }
68126
69127 // While the RFCs indicate that header keys are case-insensitive, no attempt
70128 // to convert them to all lowercase is made. Header keys are printed in the
@@ -83,11 +141,20 @@ class HttpHeader {
83141 HttpHeader& MergeHeader (HttpHeader const & other);
84142 HttpHeader& MergeHeader (HttpHeader&& other);
85143
144+ using value_type = std::string;
145+ using const_iterator = std::vector<value_type>::const_iterator;
146+ const_iterator begin () const { return values_.begin (); }
147+ const_iterator end () const { return values_.end (); }
148+ const_iterator cbegin () const { return begin (); }
149+ const_iterator cend () const { return end (); }
150+
86151 private:
87- std::string key_ ;
152+ HttpHeaderName name_ ;
88153 std::vector<std::string> values_;
89154};
90155
156+ using HttpHeaders = absl::flat_hash_map<HttpHeaderName, HttpHeader>;
157+
91158GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
92159} // namespace rest_internal
93160} // namespace cloud
0 commit comments