blob: 460221cf6c21f39e1b3463250b65a345175f918b [file] [log] [blame] [edit]
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
#include <algorithm>
#include <cstdint>
#include <map>
#include <ostream>
#include <sstream>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/http2/core/spdy_protocol.h"
#include "quiche/quic/core/http/http_constants.h"
#include "quiche/quic/core/quic_types.h"
namespace quic {
enum class HttpFrameType {
DATA = 0x0,
HEADERS = 0x1,
CANCEL_PUSH = 0x3,
SETTINGS = 0x4,
PUSH_PROMISE = 0x5,
GOAWAY = 0x7,
// https://www.rfc-editor.org/rfc/rfc9412.html
ORIGIN = 0xC,
MAX_PUSH_ID = 0xD,
// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
ACCEPT_CH = 0x89,
// https://tools.ietf.org/html/draft-ietf-httpbis-priority-03
PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
// https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
WEBTRANSPORT_STREAM = 0x41,
METADATA = 0x4d,
};
// 7.2.1. DATA
//
// DATA frames (type=0x0) convey arbitrary, variable-length sequences of
// octets associated with an HTTP request or response payload.
struct QUICHE_EXPORT DataFrame {
absl::string_view data;
};
// 7.2.2. HEADERS
//
// The HEADERS frame (type=0x1) is used to carry a header block,
// compressed using QPACK.
struct QUICHE_EXPORT HeadersFrame {
absl::string_view headers;
};
// 7.2.4. SETTINGS
//
// The SETTINGS frame (type=0x4) conveys configuration parameters that
// affect how endpoints communicate, such as preferences and constraints
// on peer behavior
using SettingsMap = absl::flat_hash_map<uint64_t, uint64_t>;
struct QUICHE_EXPORT SettingsFrame {
SettingsMap values;
bool operator==(const SettingsFrame& rhs) const {
return values == rhs.values;
}
std::string ToString() const {
std::string s;
for (auto it : values) {
std::string setting = absl::StrCat(
H3SettingsToString(
static_cast<Http3AndQpackSettingsIdentifiers>(it.first)),
" = ", it.second, "; ");
absl::StrAppend(&s, setting);
}
return s;
}
friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
const SettingsFrame& s) {
os << s.ToString();
return os;
}
};
// 7.2.6. GOAWAY
//
// The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection by
// either endpoint.
struct QUICHE_EXPORT GoAwayFrame {
// When sent from server to client, |id| is a stream ID that should refer to
// a client-initiated bidirectional stream.
// When sent from client to server, |id| is a push ID.
uint64_t id;
bool operator==(const GoAwayFrame& rhs) const { return id == rhs.id; }
};
// https://www.rfc-editor.org/rfc/rfc9412.html
// The ORIGIN HTTP/3 frame allows a server to indicate what origin or origins
// [RFC6454] the server would like the client to consider as one or more
// members of the Origin Set (Section 2.3 of [ORIGIN]) for the connection
// within which it occurs
struct QUICHE_EXPORT OriginFrame {
std::vector<std::string> origins;
bool operator==(const OriginFrame& rhs) const {
return origins == rhs.origins;
}
std::string ToString() const {
std::string result = "Origin Frame: {origins: ";
for (const std::string& origin : origins) {
absl::StrAppend(&result, "\n", origin);
}
result += "}";
return result;
}
friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
const OriginFrame& s) {
os << s.ToString();
return os;
}
};
// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
//
// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream.
// Frame type 0xf0700 (called PRIORITY_UPDATE_REQUEST_STREAM in the
// implementation) is used for for request streams.
// Frame type 0xf0701 would be used for push streams but it is not implemented;
// incoming 0xf0701 frames are treated as frames of unknown type.
// Length of a priority frame's first byte.
inline constexpr QuicByteCount kPriorityFirstByteLength = 1;
struct QUICHE_EXPORT PriorityUpdateFrame {
uint64_t prioritized_element_id = 0;
std::string priority_field_value;
bool operator==(const PriorityUpdateFrame& rhs) const {
return std::tie(prioritized_element_id, priority_field_value) ==
std::tie(rhs.prioritized_element_id, rhs.priority_field_value);
}
std::string ToString() const {
return absl::StrCat(
"Priority Frame : {prioritized_element_id: ", prioritized_element_id,
", priority_field_value: ", priority_field_value, "}");
}
friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
const PriorityUpdateFrame& s) {
os << s.ToString();
return os;
}
};
// ACCEPT_CH
// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
//
struct QUICHE_EXPORT AcceptChFrame {
std::vector<spdy::AcceptChOriginValuePair> entries;
bool operator==(const AcceptChFrame& rhs) const {
return entries.size() == rhs.entries.size() &&
std::equal(entries.begin(), entries.end(), rhs.entries.begin());
}
std::string ToString() const {
std::stringstream s;
s << *this;
return s.str();
}
friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
const AcceptChFrame& frame) {
os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: ";
for (auto& entry : frame.entries) {
os << "origin: " << entry.origin << "; value: " << entry.value;
}
return os;
}
};
} // namespace quic
#endif // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_