xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains data structures and utility functions used for serializing
6 // and parsing alternative service header values, common to HTTP/1.1 header
7 // fields and HTTP/2 and QUIC ALTSVC frames.  See specification at
8 // https://httpwg.github.io/http-extensions/alt-svc.html.
9 
10 #ifndef QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
11 #define QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
12 
13 #include <cstdint>
14 #include <string>
15 #include <vector>
16 
17 #include "absl/container/inlined_vector.h"
18 #include "absl/strings/string_view.h"
19 #include "quiche/common/platform/api/quiche_export.h"
20 
21 namespace spdy {
22 
23 namespace test {
24 class SpdyAltSvcWireFormatPeer;
25 }  // namespace test
26 
27 class QUICHE_EXPORT SpdyAltSvcWireFormat {
28  public:
29   using VersionVector = absl::InlinedVector<uint32_t, 8>;
30 
31   struct QUICHE_EXPORT AlternativeService {
32     std::string protocol_id;
33     std::string host;
34 
35     // Default is 0: invalid port.
36     uint16_t port = 0;
37     // Default is one day.
38     uint32_t max_age_seconds = 86400;
39     // Default is empty: unspecified version.
40     VersionVector version;
41 
42     AlternativeService();
43     AlternativeService(const std::string& protocol_id, const std::string& host,
44                        uint16_t port, uint32_t max_age_seconds,
45                        VersionVector version);
46     AlternativeService(const AlternativeService& other);
47     ~AlternativeService();
48 
49     bool operator==(const AlternativeService& other) const {
50       return protocol_id == other.protocol_id && host == other.host &&
51              port == other.port && version == other.version &&
52              max_age_seconds == other.max_age_seconds;
53     }
54   };
55   // An empty vector means alternative services should be cleared for given
56   // origin.  Note that the wire format for this is the string "clear", not an
57   // empty value (which is invalid).
58   typedef std::vector<AlternativeService> AlternativeServiceVector;
59 
60   friend class test::SpdyAltSvcWireFormatPeer;
61   static bool ParseHeaderFieldValue(absl::string_view value,
62                                     AlternativeServiceVector* altsvc_vector);
63   static std::string SerializeHeaderFieldValue(
64       const AlternativeServiceVector& altsvc_vector);
65 
66  private:
67   // Forward |*c| over space and tab or until |end| is reached.
68   static void SkipWhiteSpace(absl::string_view::const_iterator* c,
69                              absl::string_view::const_iterator end);
70   // Decode percent-decoded string between |c| and |end| into |*output|.
71   // Return true on success, false if input is invalid.
72   static bool PercentDecode(absl::string_view::const_iterator c,
73                             absl::string_view::const_iterator end,
74                             std::string* output);
75   // Parse the authority part of Alt-Svc between |c| and |end| into |*host| and
76   // |*port|.  Return true on success, false if input is invalid.
77   static bool ParseAltAuthority(absl::string_view::const_iterator c,
78                                 absl::string_view::const_iterator end,
79                                 std::string* host, uint16_t* port);
80   // Parse a positive integer between |c| and |end| into |*value|.
81   // Return true on success, false if input is not a positive integer or it
82   // cannot be represented on uint16_t.
83   static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
84                                      absl::string_view::const_iterator end,
85                                      uint16_t* value);
86   // Parse a positive integer between |c| and |end| into |*value|.
87   // Return true on success, false if input is not a positive integer or it
88   // cannot be represented on uint32_t.
89   static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
90                                      absl::string_view::const_iterator end,
91                                      uint32_t* value);
92   // Parse |c| as hexadecimal digit, case insensitive.  |c| must be [0-9a-fA-F].
93   // Output is between 0 and 15.
94   static char HexDigitToInt(char c);
95   // Parse |data| as hexadecimal number into |*value|.  |data| must only contain
96   // hexadecimal digits, no "0x" prefix.
97   // Return true on success, false if input is empty, not valid hexadecimal
98   // number, or cannot be represented on uint32_t.
99   static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value);
100 };
101 
102 }  // namespace spdy
103 
104 #endif  // QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
105