http_header.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #ifndef BRPC_HTTP_HEADER_H
  18. #define BRPC_HTTP_HEADER_H
  19. #include "butil/strings/string_piece.h" // StringPiece
  20. #include "butil/containers/case_ignored_flat_map.h"
  21. #include "brpc/uri.h" // URI
  22. #include "brpc/http_method.h" // HttpMethod
  23. #include "brpc/http_status_code.h"
  24. #include "brpc/http2.h"
  25. // To rpc developers: DON'T put impl. details here, use opaque pointers instead.
  26. namespace brpc {
  27. class InputMessageBase;
  28. namespace policy {
  29. void ProcessHttpRequest(InputMessageBase *msg);
  30. class H2StreamContext;
  31. }
  32. // Non-body part of a HTTP message.
  33. class HttpHeader {
  34. public:
  35. typedef butil::CaseIgnoredFlatMap<std::string> HeaderMap;
  36. typedef HeaderMap::const_iterator HeaderIterator;
  37. HttpHeader();
  38. // Exchange internal fields with another HttpHeader.
  39. void Swap(HttpHeader &rhs);
  40. // Reset internal fields as if they're just default-constructed.
  41. void Clear();
  42. // Get http version, 1.1 by default.
  43. int major_version() const { return _version.first; }
  44. int minor_version() const { return _version.second; }
  45. // Change the http version
  46. void set_version(int http_major, int http_minor)
  47. { _version = std::make_pair(http_major, http_minor); }
  48. // True if version of http is earlier than 1.1
  49. bool before_http_1_1() const
  50. { return (major_version() * 10000 + minor_version()) <= 10000; }
  51. // True if the message is from HTTP2.
  52. bool is_http2() const { return major_version() == 2; }
  53. // Get/set "Content-Type". Notice that you can't get "Content-Type"
  54. // via GetHeader().
  55. // possible values: "text/plain", "application/json" ...
  56. const std::string& content_type() const { return _content_type; }
  57. void set_content_type(const std::string& type) { _content_type = type; }
  58. void set_content_type(const char* type) { _content_type = type; }
  59. std::string& mutable_content_type() { return _content_type; }
  60. // Get value of a header which is case-insensitive according to:
  61. // https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
  62. // Namely, GetHeader("log-id"), GetHeader("Log-Id"), GetHeader("LOG-ID")
  63. // point to the same value.
  64. // Return pointer to the value, NULL on not found.
  65. // NOTE: Not work for "Content-Type", call content_type() instead.
  66. const std::string* GetHeader(const char* key) const
  67. { return _headers.seek(key); }
  68. const std::string* GetHeader(const std::string& key) const
  69. { return _headers.seek(key); }
  70. // Set value of a header.
  71. // NOTE: Not work for "Content-Type", call set_content_type() instead.
  72. void SetHeader(const std::string& key, const std::string& value)
  73. { GetOrAddHeader(key) = value; }
  74. // Remove a header.
  75. void RemoveHeader(const char* key) { _headers.erase(key); }
  76. void RemoveHeader(const std::string& key) { _headers.erase(key); }
  77. // Append value to a header. If the header already exists, separate
  78. // old value and new value with comma(,) according to:
  79. // https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
  80. void AppendHeader(const std::string& key, const butil::StringPiece& value);
  81. // Get header iterators which are invalidated after calling AppendHeader()
  82. HeaderIterator HeaderBegin() const { return _headers.begin(); }
  83. HeaderIterator HeaderEnd() const { return _headers.end(); }
  84. // #headers
  85. size_t HeaderCount() const { return _headers.size(); }
  86. // Get the URI object, check src/brpc/uri.h for details.
  87. const URI& uri() const { return _uri; }
  88. URI& uri() { return _uri; }
  89. // Get/set http method.
  90. HttpMethod method() const { return _method; }
  91. void set_method(const HttpMethod method) { _method = method; }
  92. // Get/set status-code and reason-phrase. Notice that the const char*
  93. // returned by reason_phrase() will be invalidated after next call to
  94. // set_status_code().
  95. int status_code() const { return _status_code; }
  96. const char* reason_phrase() const;
  97. void set_status_code(int status_code);
  98. // The URL path removed with matched prefix.
  99. // NOTE: always normalized and NOT started with /.
  100. //
  101. // Accessing HttpService.Echo
  102. // [URL] [unresolved_path]
  103. // "/HttpService/Echo" ""
  104. // "/HttpService/Echo/Foo" "Foo"
  105. // "/HttpService/Echo/Foo/Bar" "Foo/Bar"
  106. // "/HttpService//Echo///Foo//" "Foo"
  107. //
  108. // Accessing FileService.default_method:
  109. // [URL] [unresolved_path]
  110. // "/FileService" ""
  111. // "/FileService/123.txt" "123.txt"
  112. // "/FileService/mydir/123.txt" "mydir/123.txt"
  113. // "/FileService//mydir///123.txt//" "mydir/123.txt"
  114. const std::string& unresolved_path() const { return _unresolved_path; }
  115. private:
  116. friend class HttpMessage;
  117. friend class HttpMessageSerializer;
  118. friend class policy::H2StreamContext;
  119. friend void policy::ProcessHttpRequest(InputMessageBase *msg);
  120. std::string& GetOrAddHeader(const std::string& key) {
  121. if (!_headers.initialized()) {
  122. _headers.init(29);
  123. }
  124. return _headers[key];
  125. }
  126. HeaderMap _headers;
  127. URI _uri;
  128. int _status_code;
  129. HttpMethod _method;
  130. std::string _content_type;
  131. std::string _unresolved_path;
  132. std::pair<int, int> _version;
  133. };
  134. const HttpHeader& DefaultHttpHeader();
  135. } // namespace brpc
  136. #endif //BRPC_HTTP_HEADER_H