12c593315Sopenharmony_ci/*
22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library
32c593315Sopenharmony_ci *
42c593315Sopenharmony_ci * Copyright (c) 2013 Tatsuhiro Tsujikawa
52c593315Sopenharmony_ci *
62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the
82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
122c593315Sopenharmony_ci * the following conditions:
132c593315Sopenharmony_ci *
142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be
152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software.
162c593315Sopenharmony_ci *
172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242c593315Sopenharmony_ci */
252c593315Sopenharmony_ci#ifndef HTTP2_H
262c593315Sopenharmony_ci#define HTTP2_H
272c593315Sopenharmony_ci
282c593315Sopenharmony_ci#include "nghttp2_config.h"
292c593315Sopenharmony_ci
302c593315Sopenharmony_ci#include <cstdio>
312c593315Sopenharmony_ci#include <cstring>
322c593315Sopenharmony_ci#include <string>
332c593315Sopenharmony_ci#include <vector>
342c593315Sopenharmony_ci#include <array>
352c593315Sopenharmony_ci
362c593315Sopenharmony_ci#include <nghttp2/nghttp2.h>
372c593315Sopenharmony_ci
382c593315Sopenharmony_ci#include "url-parser/url_parser.h"
392c593315Sopenharmony_ci
402c593315Sopenharmony_ci#include "util.h"
412c593315Sopenharmony_ci#include "memchunk.h"
422c593315Sopenharmony_ci#include "template.h"
432c593315Sopenharmony_ci#include "allocator.h"
442c593315Sopenharmony_ci#include "base64.h"
452c593315Sopenharmony_ci
462c593315Sopenharmony_cinamespace nghttp2 {
472c593315Sopenharmony_ci
482c593315Sopenharmony_cistruct Header {
492c593315Sopenharmony_ci  Header(std::string name, std::string value, bool no_index = false,
502c593315Sopenharmony_ci         int32_t token = -1)
512c593315Sopenharmony_ci      : name(std::move(name)),
522c593315Sopenharmony_ci        value(std::move(value)),
532c593315Sopenharmony_ci        token(token),
542c593315Sopenharmony_ci        no_index(no_index) {}
552c593315Sopenharmony_ci
562c593315Sopenharmony_ci  Header() : token(-1), no_index(false) {}
572c593315Sopenharmony_ci
582c593315Sopenharmony_ci  bool operator==(const Header &other) const {
592c593315Sopenharmony_ci    return name == other.name && value == other.value;
602c593315Sopenharmony_ci  }
612c593315Sopenharmony_ci
622c593315Sopenharmony_ci  bool operator<(const Header &rhs) const {
632c593315Sopenharmony_ci    return name < rhs.name || (name == rhs.name && value < rhs.value);
642c593315Sopenharmony_ci  }
652c593315Sopenharmony_ci
662c593315Sopenharmony_ci  std::string name;
672c593315Sopenharmony_ci  std::string value;
682c593315Sopenharmony_ci  int32_t token;
692c593315Sopenharmony_ci  bool no_index;
702c593315Sopenharmony_ci};
712c593315Sopenharmony_ci
722c593315Sopenharmony_cistruct HeaderRef {
732c593315Sopenharmony_ci  HeaderRef(const StringRef &name, const StringRef &value,
742c593315Sopenharmony_ci            bool no_index = false, int32_t token = -1)
752c593315Sopenharmony_ci      : name(name), value(value), token(token), no_index(no_index) {}
762c593315Sopenharmony_ci
772c593315Sopenharmony_ci  HeaderRef() : token(-1), no_index(false) {}
782c593315Sopenharmony_ci
792c593315Sopenharmony_ci  bool operator==(const HeaderRef &other) const {
802c593315Sopenharmony_ci    return name == other.name && value == other.value;
812c593315Sopenharmony_ci  }
822c593315Sopenharmony_ci
832c593315Sopenharmony_ci  bool operator<(const HeaderRef &rhs) const {
842c593315Sopenharmony_ci    return name < rhs.name || (name == rhs.name && value < rhs.value);
852c593315Sopenharmony_ci  }
862c593315Sopenharmony_ci
872c593315Sopenharmony_ci  StringRef name;
882c593315Sopenharmony_ci  StringRef value;
892c593315Sopenharmony_ci  int32_t token;
902c593315Sopenharmony_ci  bool no_index;
912c593315Sopenharmony_ci};
922c593315Sopenharmony_ci
932c593315Sopenharmony_ciusing Headers = std::vector<Header>;
942c593315Sopenharmony_ciusing HeaderRefs = std::vector<HeaderRef>;
952c593315Sopenharmony_ci
962c593315Sopenharmony_cinamespace http2 {
972c593315Sopenharmony_ci
982c593315Sopenharmony_ci// Returns reason-phrase for given |status code|.  If there is no
992c593315Sopenharmony_ci// known reason-phrase for the given code, returns empty string.
1002c593315Sopenharmony_ciStringRef get_reason_phrase(unsigned int status_code);
1012c593315Sopenharmony_ci
1022c593315Sopenharmony_ci// Returns string version of |status_code|. (e.g., "404")
1032c593315Sopenharmony_ciStringRef stringify_status(BlockAllocator &balloc, unsigned int status_code);
1042c593315Sopenharmony_ci
1052c593315Sopenharmony_civoid capitalize(DefaultMemchunks *buf, const StringRef &s);
1062c593315Sopenharmony_ci
1072c593315Sopenharmony_ci// Returns true if |value| is LWS
1082c593315Sopenharmony_cibool lws(const char *value);
1092c593315Sopenharmony_ci
1102c593315Sopenharmony_ci// Copies the |field| component value from |u| and |url| to the
1112c593315Sopenharmony_ci// |dest|. If |u| does not have |field|, then this function does
1122c593315Sopenharmony_ci// nothing.
1132c593315Sopenharmony_civoid copy_url_component(std::string &dest, const http_parser_url *u, int field,
1142c593315Sopenharmony_ci                        const char *url);
1152c593315Sopenharmony_ci
1162c593315Sopenharmony_ciHeaders::value_type to_header(const uint8_t *name, size_t namelen,
1172c593315Sopenharmony_ci                              const uint8_t *value, size_t valuelen,
1182c593315Sopenharmony_ci                              bool no_index, int32_t token);
1192c593315Sopenharmony_ci
1202c593315Sopenharmony_ci// Add name/value pairs to |nva|.  If |no_index| is true, this
1212c593315Sopenharmony_ci// name/value pair won't be indexed when it is forwarded to the next
1222c593315Sopenharmony_ci// hop.  This function strips white spaces around |value|.
1232c593315Sopenharmony_civoid add_header(Headers &nva, const uint8_t *name, size_t namelen,
1242c593315Sopenharmony_ci                const uint8_t *value, size_t valuelen, bool no_index,
1252c593315Sopenharmony_ci                int32_t token);
1262c593315Sopenharmony_ci
1272c593315Sopenharmony_ci// Returns pointer to the entry in |nva| which has name |name|.  If
1282c593315Sopenharmony_ci// more than one entries which have the name |name|, last occurrence
1292c593315Sopenharmony_ci// in |nva| is returned.  If no such entry exist, returns nullptr.
1302c593315Sopenharmony_ciconst Headers::value_type *get_header(const Headers &nva, const char *name);
1312c593315Sopenharmony_ci
1322c593315Sopenharmony_ci// Returns true if the value of |nv| is not empty.
1332c593315Sopenharmony_cibool non_empty_value(const HeaderRefs::value_type *nv);
1342c593315Sopenharmony_ci
1352c593315Sopenharmony_ci// Creates nghttp2_nv using |name| and |value| and returns it. The
1362c593315Sopenharmony_ci// returned value only references the data pointer to name.c_str() and
1372c593315Sopenharmony_ci// value.c_str().  If |no_index| is true, nghttp2_nv flags member has
1382c593315Sopenharmony_ci// NGHTTP2_NV_FLAG_NO_INDEX flag set.
1392c593315Sopenharmony_cinghttp2_nv make_nv(const std::string &name, const std::string &value,
1402c593315Sopenharmony_ci                   bool no_index = false);
1412c593315Sopenharmony_ci
1422c593315Sopenharmony_cinghttp2_nv make_nv(const StringRef &name, const StringRef &value,
1432c593315Sopenharmony_ci                   bool no_index = false);
1442c593315Sopenharmony_ci
1452c593315Sopenharmony_cinghttp2_nv make_nv_nocopy(const std::string &name, const std::string &value,
1462c593315Sopenharmony_ci                          bool no_index = false);
1472c593315Sopenharmony_ci
1482c593315Sopenharmony_cinghttp2_nv make_nv_nocopy(const StringRef &name, const StringRef &value,
1492c593315Sopenharmony_ci                          bool no_index = false);
1502c593315Sopenharmony_ci
1512c593315Sopenharmony_ci// Create nghttp2_nv from string literal |name| and |value|.
1522c593315Sopenharmony_citemplate <size_t N, size_t M>
1532c593315Sopenharmony_ciconstexpr nghttp2_nv make_nv_ll(const char (&name)[N], const char (&value)[M]) {
1542c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value, N - 1, M - 1,
1552c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
1562c593315Sopenharmony_ci}
1572c593315Sopenharmony_ci
1582c593315Sopenharmony_ci// Create nghttp2_nv from string literal |name| and c-string |value|.
1592c593315Sopenharmony_citemplate <size_t N>
1602c593315Sopenharmony_cinghttp2_nv make_nv_lc(const char (&name)[N], const char *value) {
1612c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
1622c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME};
1632c593315Sopenharmony_ci}
1642c593315Sopenharmony_ci
1652c593315Sopenharmony_citemplate <size_t N>
1662c593315Sopenharmony_cinghttp2_nv make_nv_lc_nocopy(const char (&name)[N], const char *value) {
1672c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
1682c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
1692c593315Sopenharmony_ci}
1702c593315Sopenharmony_ci
1712c593315Sopenharmony_ci// Create nghttp2_nv from string literal |name| and std::string
1722c593315Sopenharmony_ci// |value|.
1732c593315Sopenharmony_citemplate <size_t N>
1742c593315Sopenharmony_cinghttp2_nv make_nv_ls(const char (&name)[N], const std::string &value) {
1752c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
1762c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME};
1772c593315Sopenharmony_ci}
1782c593315Sopenharmony_ci
1792c593315Sopenharmony_citemplate <size_t N>
1802c593315Sopenharmony_cinghttp2_nv make_nv_ls_nocopy(const char (&name)[N], const std::string &value) {
1812c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
1822c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
1832c593315Sopenharmony_ci}
1842c593315Sopenharmony_ci
1852c593315Sopenharmony_citemplate <size_t N>
1862c593315Sopenharmony_cinghttp2_nv make_nv_ls_nocopy(const char (&name)[N], const StringRef &value) {
1872c593315Sopenharmony_ci  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
1882c593315Sopenharmony_ci          NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
1892c593315Sopenharmony_ci}
1902c593315Sopenharmony_ci
1912c593315Sopenharmony_cienum HeaderBuildOp {
1922c593315Sopenharmony_ci  HDOP_NONE,
1932c593315Sopenharmony_ci  // Forwarded header fields must be stripped.  If this flag is not
1942c593315Sopenharmony_ci  // set, all Forwarded header fields other than last one are added.
1952c593315Sopenharmony_ci  HDOP_STRIP_FORWARDED = 1,
1962c593315Sopenharmony_ci  // X-Forwarded-For header fields must be stripped.  If this flag is
1972c593315Sopenharmony_ci  // not set, all X-Forwarded-For header fields other than last one
1982c593315Sopenharmony_ci  // are added.
1992c593315Sopenharmony_ci  HDOP_STRIP_X_FORWARDED_FOR = 1 << 1,
2002c593315Sopenharmony_ci  // X-Forwarded-Proto header fields must be stripped.  If this flag
2012c593315Sopenharmony_ci  // is not set, all X-Forwarded-Proto header fields other than last
2022c593315Sopenharmony_ci  // one are added.
2032c593315Sopenharmony_ci  HDOP_STRIP_X_FORWARDED_PROTO = 1 << 2,
2042c593315Sopenharmony_ci  // Via header fields must be stripped.  If this flag is not set, all
2052c593315Sopenharmony_ci  // Via header fields other than last one are added.
2062c593315Sopenharmony_ci  HDOP_STRIP_VIA = 1 << 3,
2072c593315Sopenharmony_ci  // Early-Data header fields must be stripped.  If this flag is not
2082c593315Sopenharmony_ci  // set, all Early-Data header fields are added.
2092c593315Sopenharmony_ci  HDOP_STRIP_EARLY_DATA = 1 << 4,
2102c593315Sopenharmony_ci  // Strip above all header fields.
2112c593315Sopenharmony_ci  HDOP_STRIP_ALL = HDOP_STRIP_FORWARDED | HDOP_STRIP_X_FORWARDED_FOR |
2122c593315Sopenharmony_ci                   HDOP_STRIP_X_FORWARDED_PROTO | HDOP_STRIP_VIA |
2132c593315Sopenharmony_ci                   HDOP_STRIP_EARLY_DATA,
2142c593315Sopenharmony_ci  // Sec-WebSocket-Accept header field must be stripped.  If this flag
2152c593315Sopenharmony_ci  // is not set, all Sec-WebSocket-Accept header fields are added.
2162c593315Sopenharmony_ci  HDOP_STRIP_SEC_WEBSOCKET_ACCEPT = 1 << 5,
2172c593315Sopenharmony_ci  // Sec-WebSocket-Key header field must be stripped.  If this flag is
2182c593315Sopenharmony_ci  // not set, all Sec-WebSocket-Key header fields are added.
2192c593315Sopenharmony_ci  HDOP_STRIP_SEC_WEBSOCKET_KEY = 1 << 6,
2202c593315Sopenharmony_ci  // Transfer-Encoding header field must be stripped.  If this flag is
2212c593315Sopenharmony_ci  // not set, all Transfer-Encoding header fields are added.
2222c593315Sopenharmony_ci  HDOP_STRIP_TRANSFER_ENCODING = 1 << 7,
2232c593315Sopenharmony_ci};
2242c593315Sopenharmony_ci
2252c593315Sopenharmony_ci// Appends headers in |headers| to |nv|.  |headers| must be indexed
2262c593315Sopenharmony_ci// before this call (its element's token field is assigned).  Certain
2272c593315Sopenharmony_ci// headers, including disallowed headers in HTTP/2 spec and headers
2282c593315Sopenharmony_ci// which require special handling (i.e. via), are not copied.  |flags|
2292c593315Sopenharmony_ci// is one or more of HeaderBuildOp flags.  They tell function that
2302c593315Sopenharmony_ci// certain header fields should not be added.
2312c593315Sopenharmony_civoid copy_headers_to_nva(std::vector<nghttp2_nv> &nva,
2322c593315Sopenharmony_ci                         const HeaderRefs &headers, uint32_t flags);
2332c593315Sopenharmony_ci
2342c593315Sopenharmony_ci// Just like copy_headers_to_nva(), but this adds
2352c593315Sopenharmony_ci// NGHTTP2_NV_FLAG_NO_COPY_NAME and NGHTTP2_NV_FLAG_NO_COPY_VALUE.
2362c593315Sopenharmony_civoid copy_headers_to_nva_nocopy(std::vector<nghttp2_nv> &nva,
2372c593315Sopenharmony_ci                                const HeaderRefs &headers, uint32_t flags);
2382c593315Sopenharmony_ci
2392c593315Sopenharmony_ci// Appends HTTP/1.1 style header lines to |buf| from headers in
2402c593315Sopenharmony_ci// |headers|.  |headers| must be indexed before this call (its
2412c593315Sopenharmony_ci// element's token field is assigned).  Certain headers, which
2422c593315Sopenharmony_ci// requires special handling (i.e. via and cookie), are not appended.
2432c593315Sopenharmony_ci// |flags| is one or more of HeaderBuildOp flags.  They tell function
2442c593315Sopenharmony_ci// that certain header fields should not be added.
2452c593315Sopenharmony_civoid build_http1_headers_from_headers(DefaultMemchunks *buf,
2462c593315Sopenharmony_ci                                      const HeaderRefs &headers,
2472c593315Sopenharmony_ci                                      uint32_t flags);
2482c593315Sopenharmony_ci
2492c593315Sopenharmony_ci// Return positive window_size_increment if WINDOW_UPDATE should be
2502c593315Sopenharmony_ci// sent for the stream |stream_id|. If |stream_id| == 0, this function
2512c593315Sopenharmony_ci// determines the necessity of the WINDOW_UPDATE for a connection.
2522c593315Sopenharmony_ci//
2532c593315Sopenharmony_ci// If the function determines WINDOW_UPDATE is not necessary at the
2542c593315Sopenharmony_ci// moment, it returns -1.
2552c593315Sopenharmony_ciint32_t determine_window_update_transmission(nghttp2_session *session,
2562c593315Sopenharmony_ci                                             int32_t stream_id);
2572c593315Sopenharmony_ci
2582c593315Sopenharmony_ci// Dumps name/value pairs in |nv| to |out|. The |nv| must be
2592c593315Sopenharmony_ci// terminated by nullptr.
2602c593315Sopenharmony_civoid dump_nv(FILE *out, const char **nv);
2612c593315Sopenharmony_ci
2622c593315Sopenharmony_ci// Dumps name/value pairs in |nva| to |out|.
2632c593315Sopenharmony_civoid dump_nv(FILE *out, const nghttp2_nv *nva, size_t nvlen);
2642c593315Sopenharmony_ci
2652c593315Sopenharmony_ci// Dumps name/value pairs in |nva| to |out|.
2662c593315Sopenharmony_civoid dump_nv(FILE *out, const Headers &nva);
2672c593315Sopenharmony_ci
2682c593315Sopenharmony_civoid dump_nv(FILE *out, const HeaderRefs &nva);
2692c593315Sopenharmony_ci
2702c593315Sopenharmony_ci// Ereases header in |hd|.
2712c593315Sopenharmony_civoid erase_header(HeaderRef *hd);
2722c593315Sopenharmony_ci
2732c593315Sopenharmony_ci// Rewrites redirection URI which usually appears in location header
2742c593315Sopenharmony_ci// field. The |uri| is the URI in the location header field. The |u|
2752c593315Sopenharmony_ci// stores the result of parsed |uri|. The |request_authority| is the
2762c593315Sopenharmony_ci// host or :authority header field value in the request. The
2772c593315Sopenharmony_ci// |upstream_scheme| is either "https" or "http" in the upstream
2782c593315Sopenharmony_ci// interface.  Rewrite is done only if location header field value
2792c593315Sopenharmony_ci// contains |match_host| as host excluding port.  The |match_host| and
2802c593315Sopenharmony_ci// |request_authority| could be different.  If |request_authority| is
2812c593315Sopenharmony_ci// empty, strip authority.
2822c593315Sopenharmony_ci//
2832c593315Sopenharmony_ci// This function returns the new rewritten URI on success. If the
2842c593315Sopenharmony_ci// location URI is not subject to the rewrite, this function returns
2852c593315Sopenharmony_ci// empty string.
2862c593315Sopenharmony_ciStringRef rewrite_location_uri(BlockAllocator &balloc, const StringRef &uri,
2872c593315Sopenharmony_ci                               const http_parser_url &u,
2882c593315Sopenharmony_ci                               const StringRef &match_host,
2892c593315Sopenharmony_ci                               const StringRef &request_authority,
2902c593315Sopenharmony_ci                               const StringRef &upstream_scheme);
2912c593315Sopenharmony_ci
2922c593315Sopenharmony_ci// Returns parsed HTTP status code.  Returns -1 on failure.
2932c593315Sopenharmony_ciint parse_http_status_code(const StringRef &src);
2942c593315Sopenharmony_ci
2952c593315Sopenharmony_ci// Header fields to be indexed, except HD_MAXIDX which is convenient
2962c593315Sopenharmony_ci// member to get maximum value.
2972c593315Sopenharmony_ci//
2982c593315Sopenharmony_ci// generated by genheaderfunc.py
2992c593315Sopenharmony_cienum {
3002c593315Sopenharmony_ci  HD__AUTHORITY,
3012c593315Sopenharmony_ci  HD__HOST,
3022c593315Sopenharmony_ci  HD__METHOD,
3032c593315Sopenharmony_ci  HD__PATH,
3042c593315Sopenharmony_ci  HD__PROTOCOL,
3052c593315Sopenharmony_ci  HD__SCHEME,
3062c593315Sopenharmony_ci  HD__STATUS,
3072c593315Sopenharmony_ci  HD_ACCEPT_ENCODING,
3082c593315Sopenharmony_ci  HD_ACCEPT_LANGUAGE,
3092c593315Sopenharmony_ci  HD_ALT_SVC,
3102c593315Sopenharmony_ci  HD_CACHE_CONTROL,
3112c593315Sopenharmony_ci  HD_CONNECTION,
3122c593315Sopenharmony_ci  HD_CONTENT_LENGTH,
3132c593315Sopenharmony_ci  HD_CONTENT_TYPE,
3142c593315Sopenharmony_ci  HD_COOKIE,
3152c593315Sopenharmony_ci  HD_DATE,
3162c593315Sopenharmony_ci  HD_EARLY_DATA,
3172c593315Sopenharmony_ci  HD_EXPECT,
3182c593315Sopenharmony_ci  HD_FORWARDED,
3192c593315Sopenharmony_ci  HD_HOST,
3202c593315Sopenharmony_ci  HD_HTTP2_SETTINGS,
3212c593315Sopenharmony_ci  HD_IF_MODIFIED_SINCE,
3222c593315Sopenharmony_ci  HD_KEEP_ALIVE,
3232c593315Sopenharmony_ci  HD_LINK,
3242c593315Sopenharmony_ci  HD_LOCATION,
3252c593315Sopenharmony_ci  HD_PROXY_CONNECTION,
3262c593315Sopenharmony_ci  HD_SEC_WEBSOCKET_ACCEPT,
3272c593315Sopenharmony_ci  HD_SEC_WEBSOCKET_KEY,
3282c593315Sopenharmony_ci  HD_SERVER,
3292c593315Sopenharmony_ci  HD_TE,
3302c593315Sopenharmony_ci  HD_TRAILER,
3312c593315Sopenharmony_ci  HD_TRANSFER_ENCODING,
3322c593315Sopenharmony_ci  HD_UPGRADE,
3332c593315Sopenharmony_ci  HD_USER_AGENT,
3342c593315Sopenharmony_ci  HD_VIA,
3352c593315Sopenharmony_ci  HD_X_FORWARDED_FOR,
3362c593315Sopenharmony_ci  HD_X_FORWARDED_PROTO,
3372c593315Sopenharmony_ci  HD_MAXIDX,
3382c593315Sopenharmony_ci};
3392c593315Sopenharmony_ci
3402c593315Sopenharmony_ciusing HeaderIndex = std::array<int16_t, HD_MAXIDX>;
3412c593315Sopenharmony_ci
3422c593315Sopenharmony_ci// Looks up header token for header name |name| of length |namelen|.
3432c593315Sopenharmony_ci// Only headers we are interested in are tokenized.  If header name
3442c593315Sopenharmony_ci// cannot be tokenized, returns -1.
3452c593315Sopenharmony_ciint lookup_token(const uint8_t *name, size_t namelen);
3462c593315Sopenharmony_ciint lookup_token(const StringRef &name);
3472c593315Sopenharmony_ci
3482c593315Sopenharmony_ci// Initializes |hdidx|, header index.  The |hdidx| must point to the
3492c593315Sopenharmony_ci// array containing at least HD_MAXIDX elements.
3502c593315Sopenharmony_civoid init_hdidx(HeaderIndex &hdidx);
3512c593315Sopenharmony_ci// Indexes header |token| using index |idx|.
3522c593315Sopenharmony_civoid index_header(HeaderIndex &hdidx, int32_t token, size_t idx);
3532c593315Sopenharmony_ci
3542c593315Sopenharmony_ci// Returns header denoted by |token| using index |hdidx|.
3552c593315Sopenharmony_ciconst Headers::value_type *get_header(const HeaderIndex &hdidx, int32_t token,
3562c593315Sopenharmony_ci                                      const Headers &nva);
3572c593315Sopenharmony_ci
3582c593315Sopenharmony_ciHeaders::value_type *get_header(const HeaderIndex &hdidx, int32_t token,
3592c593315Sopenharmony_ci                                Headers &nva);
3602c593315Sopenharmony_ci
3612c593315Sopenharmony_cistruct LinkHeader {
3622c593315Sopenharmony_ci  // The region of URI.  This might not be NULL-terminated.
3632c593315Sopenharmony_ci  StringRef uri;
3642c593315Sopenharmony_ci};
3652c593315Sopenharmony_ci
3662c593315Sopenharmony_ci// Returns next URI-reference in Link header field value |src|.  If no
3672c593315Sopenharmony_ci// URI-reference found after searching all input, returned uri field
3682c593315Sopenharmony_ci// is empty.  This imply that empty URI-reference is ignored during
3692c593315Sopenharmony_ci// parsing.
3702c593315Sopenharmony_cistd::vector<LinkHeader> parse_link_header(const StringRef &src);
3712c593315Sopenharmony_ci
3722c593315Sopenharmony_ci// Constructs path by combining base path |base_path| with another
3732c593315Sopenharmony_ci// path |rel_path|.  The base path and another path can have optional
3742c593315Sopenharmony_ci// query component.  This function assumes |base_path| is normalized.
3752c593315Sopenharmony_ci// In other words, it does not contain ".." or "."  path components
3762c593315Sopenharmony_ci// and starts with "/" if it is not empty.
3772c593315Sopenharmony_cistd::string path_join(const StringRef &base, const StringRef &base_query,
3782c593315Sopenharmony_ci                      const StringRef &rel_path, const StringRef &rel_query);
3792c593315Sopenharmony_ci
3802c593315Sopenharmony_ciStringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
3812c593315Sopenharmony_ci                    const StringRef &base_query, const StringRef &rel_path,
3822c593315Sopenharmony_ci                    const StringRef &rel_query);
3832c593315Sopenharmony_ci
3842c593315Sopenharmony_ci// true if response has body, taking into account the request method
3852c593315Sopenharmony_ci// and status code.
3862c593315Sopenharmony_cibool expect_response_body(const std::string &method, int status_code);
3872c593315Sopenharmony_cibool expect_response_body(int method_token, int status_code);
3882c593315Sopenharmony_ci
3892c593315Sopenharmony_ci// true if response has body, taking into account status code only.
3902c593315Sopenharmony_cibool expect_response_body(int status_code);
3912c593315Sopenharmony_ci
3922c593315Sopenharmony_ci// Looks up method token for method name |name| of length |namelen|.
3932c593315Sopenharmony_ci// Only methods defined in llhttp.h (llhttp_method) are tokenized.  If
3942c593315Sopenharmony_ci// method name cannot be tokenized, returns -1.
3952c593315Sopenharmony_ciint lookup_method_token(const uint8_t *name, size_t namelen);
3962c593315Sopenharmony_ciint lookup_method_token(const StringRef &name);
3972c593315Sopenharmony_ci
3982c593315Sopenharmony_ci// Returns string representation of |method_token|.  This is wrapper
3992c593315Sopenharmony_ci// around llhttp_method_name from llhttp.  If |method_token| is
4002c593315Sopenharmony_ci// unknown, program aborts.  The returned StringRef is guaranteed to
4012c593315Sopenharmony_ci// be NULL-terminated.
4022c593315Sopenharmony_ciStringRef to_method_string(int method_token);
4032c593315Sopenharmony_ci
4042c593315Sopenharmony_ciStringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
4052c593315Sopenharmony_ci                         const StringRef &query);
4062c593315Sopenharmony_ci
4072c593315Sopenharmony_ci// normalize_path_colon is like normalize_path, but it additionally
4082c593315Sopenharmony_ci// does percent-decoding %3A in order to workaround the issue that ':'
4092c593315Sopenharmony_ci// cannot be included in backend pattern.
4102c593315Sopenharmony_ciStringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
4112c593315Sopenharmony_ci                               const StringRef &query);
4122c593315Sopenharmony_ci
4132c593315Sopenharmony_cistd::string normalize_path(const StringRef &path, const StringRef &query);
4142c593315Sopenharmony_ci
4152c593315Sopenharmony_ciStringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src);
4162c593315Sopenharmony_ci
4172c593315Sopenharmony_ci// Returns path component of |uri|.  The returned path does not
4182c593315Sopenharmony_ci// include query component.  This function returns empty string if it
4192c593315Sopenharmony_ci// fails.
4202c593315Sopenharmony_ciStringRef get_pure_path_component(const StringRef &uri);
4212c593315Sopenharmony_ci
4222c593315Sopenharmony_ci// Deduces scheme, authority and path from given |uri|, and stores
4232c593315Sopenharmony_ci// them in |scheme|, |authority|, and |path| respectively.  If |uri|
4242c593315Sopenharmony_ci// is relative path, path resolution takes place using path given in
4252c593315Sopenharmony_ci// |base| of length |baselen|.  This function returns 0 if it
4262c593315Sopenharmony_ci// succeeds, or -1.
4272c593315Sopenharmony_ciint construct_push_component(BlockAllocator &balloc, StringRef &scheme,
4282c593315Sopenharmony_ci                             StringRef &authority, StringRef &path,
4292c593315Sopenharmony_ci                             const StringRef &base, const StringRef &uri);
4302c593315Sopenharmony_ci
4312c593315Sopenharmony_ci// Copies |src| and return its lower-cased version.
4322c593315Sopenharmony_ciStringRef copy_lower(BlockAllocator &balloc, const StringRef &src);
4332c593315Sopenharmony_ci
4342c593315Sopenharmony_ci// Returns true if te header field value |s| contains "trailers".
4352c593315Sopenharmony_cibool contains_trailers(const StringRef &s);
4362c593315Sopenharmony_ci
4372c593315Sopenharmony_ci// Creates Sec-WebSocket-Accept value for |key|.  The capacity of
4382c593315Sopenharmony_ci// buffer pointed by |dest| must have at least 24 bytes (base64
4392c593315Sopenharmony_ci// encoded length of 16 bytes data).  It returns empty string in case
4402c593315Sopenharmony_ci// of error.
4412c593315Sopenharmony_ciStringRef make_websocket_accept_token(uint8_t *dest, const StringRef &key);
4422c593315Sopenharmony_ci
4432c593315Sopenharmony_ci// Returns true if HTTP version represents pre-HTTP/1.1 (e.g.,
4442c593315Sopenharmony_ci// HTTP/0.9 or HTTP/1.0).
4452c593315Sopenharmony_cibool legacy_http1(int major, int minor);
4462c593315Sopenharmony_ci
4472c593315Sopenharmony_ci// Returns true if transfer-encoding field value |s| conforms RFC
4482c593315Sopenharmony_ci// strictly.  This function does not allow empty value, BWS, and empty
4492c593315Sopenharmony_ci// list elements.
4502c593315Sopenharmony_cibool check_transfer_encoding(const StringRef &s);
4512c593315Sopenharmony_ci
4522c593315Sopenharmony_ci} // namespace http2
4532c593315Sopenharmony_ci
4542c593315Sopenharmony_ci} // namespace nghttp2
4552c593315Sopenharmony_ci
4562c593315Sopenharmony_ci#endif // HTTP2_H
457