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