construct/ircd/http2.cc

170 lines
4.2 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
decltype(ircd::http2::connection_preface)
ircd::http2::connection_preface
{
"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
};
///////////////////////////////////////////////////////////////////////////////
//
// stream.h
//
ircd::http2::stream::stream()
:state
{
state::IDLE
}
{
}
ircd::string_view
ircd::http2::reflect(const enum stream::state &state)
{
switch(state)
{
case stream::state::IDLE: return "IDLE";
case stream::state::RESERVED_LOCAL: return "RESERVED_LOCAL";
case stream::state::RESERVED_REMOTE: return "RESERVED_REMOTE";
case stream::state::OPEN: return "OPEN";
case stream::state::HALF_CLOSED_LOCAL: return "HALF_CLOSED_LOCAL";
case stream::state::HALF_CLOSED_REMOTE: return "HALF_CLOSED_REMOTE";
case stream::state::CLOSED: return "CLOSED";
}
return "??????";
}
///////////////////////////////////////////////////////////////////////////////
//
// settings.h
//
/// RFC 7540 6.5.2 default settings
///
ircd::http2::settings::settings()
:array_type
{
4096, // HEADER_TABLE_SIZE
1, // ENABLE_PUSH
0, // MAX_CONCURRENT_STREAMS (unlimited)
65535, // INITIAL_WINDOW_SIZE
16384, // MAX_FRAME_SIZE
0, // MAX_HEADER_LIST_SIZE (unlimited)
}
{
}
ircd::string_view
ircd::http2::reflect(const frame::settings::code &code)
{
switch(code)
{
case frame::settings::code::HEADER_TABLE_SIZE: return "HEADER_TABLE_SIZE";
case frame::settings::code::ENABLE_PUSH: return "ENABLE_PUSH";
case frame::settings::code::MAX_CONCURRENT_STREAMS: return "MAX_CONCURRENT_STREAMS";
case frame::settings::code::INITIAL_WINDOW_SIZE: return "INITIAL_WINDOW_SIZE";
case frame::settings::code::MAX_FRAME_SIZE: return "MAX_FRAME_SIZE";
case frame::settings::code::MAX_HEADER_LIST_SIZE: return "MAX_HEADER_LIST_SIZE";
case frame::settings::code::_NUM_: assert(0);
}
return "??????";
}
///////////////////////////////////////////////////////////////////////////////
//
// frame.h
//
static_assert
(
sizeof(ircd::http2::frame::header) == 9
);
///////////////////////////////////////////////////////////////////////////////
//
// error.h
//
namespace ircd::http2
{
static thread_local char error_fmt_buf[512];
}
ircd::http2::error::error()
:error
{
code::INTERNAL_ERROR
}
{
}
ircd::http2::error::error(const enum code &code)
:ircd::error
{
"(%x) %s",
uint32_t(code),
reflect(code),
}
,code
{
code
}
{
}
ircd::http2::error::error(const enum code &code,
const string_view &fmt,
va_rtti &&ap)
:ircd::error
{
"(%x) %s :%s",
uint32_t(code),
reflect(code),
string_view{fmt::vsprintf
{
error_fmt_buf, fmt, std::move(ap)
}}
}
,code
{
code
}
{
}
ircd::string_view
ircd::http2::reflect(const enum error::code &code)
{
switch(code)
{
case error::code::NO_ERROR: return "NO_ERROR";
case error::code::PROTOCOL_ERROR: return "PROTOCOL_ERROR";
case error::code::INTERNAL_ERROR: return "INTERNAL_ERROR";
case error::code::FLOW_CONTROL_ERROR: return "FLOW_CONTROL_ERROR";
case error::code::SETTINGS_TIMEOUT: return "SETTINGS_TIMEOUT";
case error::code::STREAM_CLOSED: return "STREAM_CLOSED";
case error::code::FRAME_SIZE_ERROR: return "FRAME_SIZE_ERROR";
case error::code::REFUSED_STREAM: return "REFUSED_STREAM";
case error::code::CANCEL: return "CANCEL";
case error::code::COMPRESSION_ERROR: return "COMPRESSION_ERROR";
case error::code::CONNECT_ERROR: return "CONNECT_ERROR";
case error::code::ENHANCE_YOUR_CALM: return "ENHANCE_YOUR_CALM";
case error::code::INADEQUATE_SECURITY: return "INADEQUATE_SECURITY";
case error::code::HTTP_1_1_REQUIRED: return "HTTP_1_1_REQUIRED";
}
return "??????";
}