mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd::http2: Start an RFC7540 implementation.
This commit is contained in:
parent
c944818f4b
commit
d17afdd531
8 changed files with 439 additions and 0 deletions
85
include/ircd/http2/error.h
Normal file
85
include/ircd/http2/error.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_HTTP2_ERROR_H
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
struct error;
|
||||
}
|
||||
|
||||
struct ircd::http2::error
|
||||
:ircd::error
|
||||
{
|
||||
enum code :uint32_t;
|
||||
|
||||
enum code code;
|
||||
|
||||
error();
|
||||
error(const enum code &);
|
||||
|
||||
explicit
|
||||
error(const enum code &,
|
||||
const string_view &fmt,
|
||||
va_rtti &&ap);
|
||||
|
||||
template<class... args>
|
||||
error(const enum code &,
|
||||
const string_view &fmt,
|
||||
args&&...);
|
||||
|
||||
template<class... args>
|
||||
error(const string_view &fmt,
|
||||
args&&...);
|
||||
};
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
string_view reflect(const enum error::code &);
|
||||
}
|
||||
|
||||
enum ircd::http2::error::code
|
||||
:uint32_t
|
||||
{
|
||||
NO_ERROR = 0x0,
|
||||
PROTOCOL_ERROR = 0x1,
|
||||
INTERNAL_ERROR = 0x2,
|
||||
FLOW_CONTROL_ERROR = 0x3,
|
||||
SETTINGS_TIMEOUT = 0x4,
|
||||
STREAM_CLOSED = 0x5,
|
||||
FRAME_SIZE_ERROR = 0x6,
|
||||
REFUSED_STREAM = 0x7,
|
||||
CANCEL = 0x8,
|
||||
COMPRESSION_ERROR = 0x9,
|
||||
CONNECT_ERROR = 0xa,
|
||||
ENHANCE_YOUR_CALM = 0xb,
|
||||
INADEQUATE_SECURITY = 0xc,
|
||||
HTTP_1_1_REQUIRED = 0xd,
|
||||
};
|
||||
|
||||
template<class... args>
|
||||
ircd::http2::error::error(const string_view &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
code::INTERNAL_ERROR, fmt, va_rtti{std::forward<args>(a)...}
|
||||
}
|
||||
{}
|
||||
|
||||
template<class... args>
|
||||
ircd::http2::error::error(const enum code &code,
|
||||
const string_view &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
code, fmt, va_rtti{std::forward<args>(a)...}
|
||||
}
|
||||
{}
|
51
include/ircd/http2/frame.h
Normal file
51
include/ircd/http2/frame.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_HTTP2_FRAME_H
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
struct frame;
|
||||
}
|
||||
|
||||
struct ircd::http2::frame
|
||||
{
|
||||
struct header;
|
||||
struct settings;
|
||||
enum type :uint8_t;
|
||||
|
||||
static string_view reflect(const type &);
|
||||
};
|
||||
|
||||
struct ircd::http2::frame::header
|
||||
{
|
||||
uint32_t len : 24;
|
||||
enum type type;
|
||||
uint8_t flags;
|
||||
uint32_t : 1;
|
||||
uint32_t stream_id : 31;
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
enum ircd::http2::frame::type
|
||||
:uint8_t
|
||||
{
|
||||
DATA = 0x0,
|
||||
HEADERS = 0x1,
|
||||
PRIORITY = 0x2,
|
||||
RST_STREAM = 0x3,
|
||||
SETTINGS = 0x4,
|
||||
PUSH_PROMISE = 0x5,
|
||||
PING = 0x6,
|
||||
GOAWAY = 0x7,
|
||||
WINDOW_UPDATE = 0x8,
|
||||
CONTINUATION = 0x9,
|
||||
};
|
23
include/ircd/http2/http2.h
Normal file
23
include/ircd/http2/http2.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_HTTP2_H
|
||||
|
||||
/// HyperText TransPort / 2.x
|
||||
namespace ircd::http2
|
||||
{
|
||||
extern const string_view connection_preface;
|
||||
}
|
||||
|
||||
#include "error.h"
|
||||
#include "frame.h"
|
||||
#include "settings.h"
|
||||
#include "stream.h"
|
66
include/ircd/http2/settings.h
Normal file
66
include/ircd/http2/settings.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_HTTP2_SETTINGS_H
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
struct settings;
|
||||
}
|
||||
|
||||
struct ircd::http2::frame::settings
|
||||
{
|
||||
enum code :uint16_t;
|
||||
enum flag :decltype(frame::header::flags);
|
||||
struct param;
|
||||
|
||||
vector_view<const struct param> param;
|
||||
};
|
||||
|
||||
struct ircd::http2::frame::settings::param
|
||||
{
|
||||
uint16_t id {0};
|
||||
uint32_t value {0};
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
string_view reflect(const frame::settings::code &);
|
||||
}
|
||||
|
||||
enum ircd::http2::frame::settings::code
|
||||
:uint16_t
|
||||
{
|
||||
HEADER_TABLE_SIZE = 0x1,
|
||||
ENABLE_PUSH = 0x2,
|
||||
MAX_CONCURRENT_STREAMS = 0x3,
|
||||
INITIAL_WINDOW_SIZE = 0x4,
|
||||
MAX_FRAME_SIZE = 0x5,
|
||||
MAX_HEADER_LIST_SIZE = 0x6,
|
||||
|
||||
_NUM_
|
||||
};
|
||||
|
||||
enum ircd::http2::frame::settings::flag
|
||||
:std::underlying_type<ircd::http2::frame::settings::flag>::type
|
||||
{
|
||||
ACK = (1 << 0),
|
||||
};
|
||||
|
||||
struct ircd::http2::settings
|
||||
:std::array<uint32_t, num_of<frame::settings::code>()>
|
||||
{
|
||||
using code = frame::settings::code;
|
||||
using array_type = std::array<uint32_t, num_of<code>()>;
|
||||
|
||||
settings();
|
||||
};
|
43
include/ircd/http2/stream.h
Normal file
43
include/ircd/http2/stream.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_HTTP2_STREAM_H
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
struct stream;
|
||||
}
|
||||
|
||||
struct ircd::http2::stream
|
||||
{
|
||||
enum class state :uint8_t;
|
||||
|
||||
enum state state;
|
||||
|
||||
stream();
|
||||
};
|
||||
|
||||
namespace ircd::http2
|
||||
{
|
||||
string_view reflect(const enum stream::state &);
|
||||
}
|
||||
|
||||
enum class ircd::http2::stream::state
|
||||
:uint8_t
|
||||
{
|
||||
IDLE,
|
||||
RESERVED_LOCAL,
|
||||
RESERVED_REMOTE,
|
||||
OPEN,
|
||||
HALF_CLOSED_LOCAL,
|
||||
HALF_CLOSED_REMOTE,
|
||||
CLOSED,
|
||||
};
|
|
@ -45,6 +45,7 @@
|
|||
#include "openssl.h"
|
||||
#include "fmt.h"
|
||||
#include "http.h"
|
||||
#include "http2/http2.h"
|
||||
#include "magics.h"
|
||||
#include "conf.h"
|
||||
#include "stats.h"
|
||||
|
|
|
@ -124,6 +124,7 @@ libircd_la_SOURCES += rfc1459.cc
|
|||
libircd_la_SOURCES += rfc3986.cc
|
||||
libircd_la_SOURCES += rfc1035.cc
|
||||
libircd_la_SOURCES += http.cc
|
||||
libircd_la_SOURCES += http2.cc
|
||||
libircd_la_SOURCES += stats.cc
|
||||
libircd_la_SOURCES += prof.cc
|
||||
libircd_la_SOURCES += fs.cc
|
||||
|
|
169
ircd/http2.cc
Normal file
169
ircd/http2.cc
Normal file
|
@ -0,0 +1,169 @@
|
|||
// 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
|
||||
{
|
||||
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 "??????";
|
||||
}
|
Loading…
Reference in a new issue