llcorehttpheaders.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. * @file llcorehttpheaders.h
  3. * @brief Public-facing declarations for the HttpHeaders class
  4. *
  5. * $LicenseInfo:firstyear=2012&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2012, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef _LLCORE_HTTP_HEADERS_H_
  27. #define _LLCORE_HTTP_HEADERS_H_
  28. #include <string>
  29. #include <vector>
  30. #include "llcorehttpcommon.h"
  31. // Convenient shortcut
  32. #define DEFAULT_HTTP_HEADERS std::make_shared<LLCore::HttpHeaders>()
  33. namespace LLCore
  34. {
  35. // Maintains an ordered list of name/value pairs representing HTTP header
  36. // lines. This is used both to provide additional headers when making HTTP
  37. // requests and in responses when the caller has asked that headers be
  38. // returned (not the default option).
  39. //
  40. // Class is mostly a thin wrapper around a vector of pairs of strings. Methods
  41. // provided are few and intended to reflect actual use patterns. These include:
  42. // - Clearing the list
  43. // - Appending a name/value pair to the vector
  44. // - Processing a raw byte string into a normalized name/value pair and
  45. // appending the result.
  46. // - Simple case-sensitive find-last-by-name search
  47. // - Forward and reverse iterators over all pairs
  48. //
  49. // Container is ordered and multi-valued. Headers are written in the order in
  50. // which they are appended and are stored in the order in which they're
  51. // received from the wire. The same header may appear two or more times in any
  52. // container. Searches using the simple find() interface will find only the
  53. // last occurrence (somewhat simulates the use of std::map). Fuller searches
  54. // require the use of an iterator. Headers received from the wire are only
  55. // returned from the last request when redirections are involved.
  56. //
  57. // Threading: not intrinsically thread-safe. It *is* expected that callers will
  58. // build these objects and then share them via reference counting with the
  59. // worker thread. The implication is that once an HttpHeader instance is handed
  60. // to a request, the object must be treated as read-only.
  61. //
  62. // Allocation: refcounted, heap only. Caller of the constructor is given a
  63. // refcount.
  64. class HttpHeaders
  65. {
  66. public:
  67. typedef std::pair<std::string, std::string> header_t;
  68. typedef std::vector<header_t> container_t;
  69. typedef container_t::iterator iterator;
  70. typedef container_t::const_iterator const_iterator;
  71. typedef container_t::reverse_iterator reverse_iterator;
  72. typedef container_t::const_reverse_iterator const_reverse_iterator;
  73. typedef container_t::value_type value_type;
  74. typedef container_t::size_type size_type;
  75. typedef std::shared_ptr<HttpHeaders> ptr_t;
  76. public:
  77. // In addition to the instance, caller has a refcount to the instance.
  78. // A call to release() will destroy the instance.
  79. HttpHeaders() = default;
  80. // Non-copyable
  81. HttpHeaders(const HttpHeaders&) = delete;
  82. HttpHeaders& operator=(const HttpHeaders&) = delete;
  83. public:
  84. // Empty the list of headers.
  85. LL_INLINE void clear() { mHeaders.clear(); }
  86. // Append a name/value pair supplied as either std::strings or
  87. // NUL-terminated char * to the header list. No normalization is performed
  88. // on the strings. No conformance test is performed (names may contain
  89. // spaces, colons, etc).
  90. void append(const char* name, const char* value);
  91. void append(const std::string& name, const char* value);
  92. LL_INLINE void append(const char* name, const std::string& value)
  93. {
  94. append(name, value.c_str());
  95. }
  96. LL_INLINE void append(const std::string& name, const std::string& value)
  97. {
  98. append(name, value.c_str());
  99. }
  100. // Extract a name/value pair from a raw byte array using the first colon
  101. // character as a separator. Input string does not need to be
  102. // NUL-terminated. Resulting name/value pair is appended to the header
  103. // list.
  104. //
  105. // Normalization is performed on the name/value pair as follows:
  106. // - name is lower-cased according to mostly ASCII rules
  107. // - name is left- and right-trimmed of spaces and tabs
  108. // - value is left-trimmed of spaces and tabs
  109. // - either or both of name and value may be zero-length
  110. //
  111. // By convention, headers read from the wire will be normalized in this
  112. // fashion prior to delivery to any HttpHandler code. Headers to be written
  113. // to the wire are left as appended to the list.
  114. void appendNormal(const char* header, size_t size);
  115. // Perform a simple, case-sensitive search of the header list
  116. // returning a pointer to the value of the last matching header
  117. // in the header list. If none is found, a NULL pointer is returned.
  118. //
  119. // Any pointer returned references objects in the container itself and will
  120. // have the same lifetime as this class. If you want the value beyond the
  121. // lifetime of this instance, make a copy.
  122. //
  123. // @arg name string giving the name of a header to search.
  124. // The comparison is case-sensitive though list entries
  125. // may have been normalized to lower-case.
  126. //
  127. // @return NULL if the header wasn't found otherwise a pointer to
  128. // a std::string in the container. Pointer is valid only
  129. // for the lifetime of the container or until container is
  130. // modifed.
  131. const std::string* find(const char* name) const;
  132. const std::string* find(const std::string& name) const;
  133. // Remove the header from the list if found.
  134. void remove(const char* name);
  135. LL_INLINE void remove(const std::string& name)
  136. {
  137. remove(name.c_str());
  138. }
  139. // Count of headers currently in the list.
  140. LL_INLINE size_type size() const { return mHeaders.size(); }
  141. // Standard std::vector-based forward iterators.
  142. LL_INLINE iterator begin() { return mHeaders.begin(); }
  143. LL_INLINE const_iterator begin() const { return mHeaders.begin(); }
  144. LL_INLINE iterator end() { return mHeaders.end(); }
  145. LL_INLINE const_iterator end() const { return mHeaders.end(); }
  146. // Standard std::vector-based reverse iterators.
  147. LL_INLINE reverse_iterator rbegin() { return mHeaders.rbegin(); }
  148. LL_INLINE const_reverse_iterator rbegin() const { return mHeaders.rbegin(); }
  149. LL_INLINE reverse_iterator rend() { return mHeaders.rend(); }
  150. LL_INLINE const_reverse_iterator rend() const { return mHeaders.rend(); }
  151. protected:
  152. container_t mHeaders;
  153. };
  154. } // End namespace LLCore
  155. #endif // _LLCORE_HTTP_HEADERS_H_