Compare commits

..

No commits in common. "9d80aaa1e96317d53ab005ddf442fe3db058803e" and "ab73516ae14373b279314879caf2b6841c266d52" have entirely different histories.

5 changed files with 392 additions and 806 deletions

View File

@ -13,7 +13,7 @@ Drogon is a cross-platform framework, It supports Linux, macOS, FreeBSD, OpenBSD
* Use a non-blocking I/O network lib based on epoll (kqueue under macOS/FreeBSD) to provide high-concurrency, high-performance network IO, please visit the [TFB Tests Results](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite) for more details;
* Provide a completely asynchronous programming mode;
* Support HTTP/2 (and 1.0/1.1) client and HTTP 1.1/1.0 server
* Support Http1.0/1.1 (server side and client side);
* Based on template, a simple reflection mechanism is implemented to completely decouple the main program framework, controllers and views.
* Support cookies and built-in sessions;
* Support back-end rendering, the controller generates the data to the view to generate the Html page. Views are described by CSP template files, C++ codes are embedded into Html pages through CSP tags. And the drogon command-line tool automatically generates the C++ code files for compilation;

View File

@ -16,7 +16,7 @@ int main()
{
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
{
auto client = HttpClient::newHttpClient("https://clehaxze.tw",
auto client = HttpClient::newHttpClient("https://clehaxze.tw:8844",
nullptr,
false,
false);
@ -48,7 +48,7 @@ int main()
req->setParameter("wd", "wx");
req->setParameter("oq", "wx");
for (int i = 0; i < 2; ++i)
for (int i = 0; i < 1; ++i)
{
client->sendRequest(
req, [](ReqResult result, const HttpResponsePtr &response) {
@ -76,6 +76,7 @@ int main()
});
LOG_INFO << "send request";
}
app().run();
}
app().run();
}

File diff suppressed because it is too large Load Diff

View File

@ -5,93 +5,11 @@
// TOOD: Write our own HPACK implementation
#include "hpack/HPacker.h"
#include <variant>
namespace drogon
{
namespace internal
{
struct ByteStream;
struct OByteStream;
struct SettingsFrame
{
bool ack = false;
std::vector<std::pair<uint16_t, uint32_t>> settings;
static std::optional<SettingsFrame> parse(ByteStream &payload,
uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
struct WindowUpdateFrame
{
uint32_t windowSizeIncrement = 0;
static std::optional<WindowUpdateFrame> parse(ByteStream &payload,
uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
struct HeadersFrame
{
uint8_t padLength = 0;
bool exclusive = false;
uint32_t streamDependency = 0;
uint8_t weight = 0;
std::vector<uint8_t> headerBlockFragment;
bool endHeaders = false;
bool endStream = false;
static std::optional<HeadersFrame> parse(ByteStream &payload,
uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
struct GoAwayFrame
{
uint32_t lastStreamId = 0;
uint32_t errorCode = 0;
std::vector<uint8_t> additionalDebugData;
static std::optional<GoAwayFrame> parse(ByteStream &payload, uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
struct DataFrame
{
uint8_t padLength = 0;
std::vector<uint8_t> data;
bool endStream = false;
static std::optional<DataFrame> parse(ByteStream &payload, uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
struct PingFrame
{
std::array<uint8_t, 8> opaqueData;
bool ack = false;
static std::optional<PingFrame> parse(ByteStream &payload, uint8_t flags);
bool serialize(OByteStream &stream, uint8_t &flags) const;
};
using H2Frame = std::variant<SettingsFrame,
WindowUpdateFrame,
HeadersFrame,
GoAwayFrame,
DataFrame,
PingFrame>;
enum class StreamState
{
ExpectingHeaders,
ExpectingContinuation,
ExpectingData,
Finished,
};
// Virtual stream that holds properties for the HTTP/2 stream
// Defaults to stream 0 global properties
@ -99,31 +17,10 @@ struct H2Stream
{
HttpReqCallback callback;
HttpResponseImplPtr response;
HttpRequestPtr request;
trantor::MsgBuffer body;
std::optional<size_t> contentLength;
int32_t streamId = 0;
StreamState state = StreamState::ExpectingHeaders;
};
} // namespace internal
enum class StreamCloseErrorCode
{
NoError = 0x0,
ProtocolError = 0x1,
InternalError = 0x2,
FlowControlError = 0x3,
SettingsTimeout = 0x4,
StreamClosed = 0x5,
FrameSizeError = 0x6,
RefusedStream = 0x7,
Cancel = 0x8,
CompressionError = 0x9,
ConnectError = 0xa,
EnhanceYourCalm = 0xb,
InadequateSecurity = 0xc,
Http11Required = 0xd,
};
} // namespace internal
class Http2Transport : public HttpTransport
{
@ -145,21 +42,9 @@ class Http2Transport : public HttpTransport
size_t maxFrameSize = 16384;
size_t avaliableWindowSize = 0;
// Configuration settings
const size_t windowIncreaseThreshold = 32768;
const size_t windowIncreaseSize = 10 * 1024 * 1024; // 10 MiB
// Set after server settings are received
bool serverSettingsReceived = false;
std::queue<std::pair<HttpRequestPtr, HttpReqCallback>> bufferedRequests;
size_t avaliableWindow = 10 * 1024 * 1024; // 10 MiB
internal::H2Stream &createStream(int32_t streamId);
void streamFinished(internal::H2Stream &stream);
void streamFinished(int32_t streamId,
ReqResult result,
StreamCloseErrorCode errorCode,
std::string errorMsg = "");
std::vector<std::pair<HttpRequestPtr, HttpReqCallback>> bufferedRequests;
int32_t nextStreamId()
{
@ -193,10 +78,6 @@ class Http2Transport : public HttpTransport
}
}
void handleFrameForStream(const internal::H2Frame &frame,
int32_t streamId,
uint8_t flags);
public:
Http2Transport(trantor::TcpConnectionPtr connPtr,
size_t *bytesSent,
@ -218,7 +99,10 @@ class Http2Transport : public HttpTransport
"HTTP/2 handleConnectionClose not implemented");
}
void onError(ReqResult result) override;
void onError(ReqResult result) override
{
throw std::runtime_error("HTTP/2 onError not implemented");
}
protected:
void onServerSettingsReceived(){};

View File

@ -109,9 +109,6 @@ const char *HttpResponseImpl::versionString() const
case Version::kHttp11:
result = "HTTP/1.1";
break;
case Version::kHttp2:
result = "HTTP/2";
break;
default:
break;