代码拉取完成,页面将自动刷新
#include "http2/transport.h"
#include <string.h>
#include "src/http2/connection.h"
#include "src/http2/errors.h"
#include "src/hpack/static_metadata.h"
#include "src/utils/log.h"
namespace {
std::mutex global_init_mutex;
int32_t global_init_counter = 0;
} // namespace
static void internal_init_library() {
std::lock_guard<std::mutex> lck(global_init_mutex);
if (global_init_counter == 0) {
init_static_metadata_context();
}
global_init_counter++;
}
static void internal_cleanup_library() {
std::lock_guard<std::mutex> lck(global_init_mutex);
if (global_init_counter == 1) {
destroy_static_metadata_context();
}
global_init_counter--;
}
struct InternalTag {};
class LibraryInitlizer {
public:
explicit LibraryInitlizer(InternalTag) {
internal_init_library();
}
~LibraryInitlizer() {
internal_cleanup_library();
}
int temp() {
return 42;
}
};
namespace http2 {
class TransportAdaptor : public Transport {
public:
TransportAdaptor(SendService *service, uint64_t cid, bool client_side);
~TransportAdaptor();
uint64_t GetConnectionId() override;
bool IsClientSide() override;
void SetFlowControlHandler(FlowControlHandler *handler) override;
void SetFrameEventHandler(FrameEventHandler *handler) override;
bool SendPing(uint64_t info) override;
bool SendSettings(const std::vector<std::pair<uint16_t, uint32_t>> &settings) override;
bool SendPriority(uint32_t stream_id, uint8_t weight, uint32_t depend_stream_id) override;
bool SendRSTStream(uint32_t stream_id, uint32_t error_code) override;
void SendGoAway(uint32_t last_stream_id, uint32_t error_code, const std::string &debug) override;
bool SendWindowUpdate(uint32_t stream_id, WindowUpdate *wu) override;
bool SendRequest(Request *req) override;
bool SendResponse(Response *rsp) override;
// if initlize_headers not null, send PUSH_PROMISE
// else just allocate local stream id
uint32_t CreateStream(std::vector<std::pair<std::string, std::string>> *initlize_headers) override;
/*
* Return -1 means an error occurred, return 0 means still need to provide
* data, other values greater than 0 means the length of a complete http2
* packet. When calling the ReceivedData function, at least one complete
* http2 package must be provided.
*/
int CheckPackageLength(const uint8_t *data, uint32_t len) override;
/*
* Need to provide one or more complete http2 data package. To get the
* complete http2 package, please check CheckHttp2PackageLength function.
*/
void ReceivedData(const uint8_t *buf, uint32_t len) override;
// Call this function to notify a connection to be disconnected.
void Shutdown() override;
private:
LibraryInitlizer _internal;
http2_connection _impl;
};
TransportAdaptor::TransportAdaptor(SendService *service, uint64_t cid, bool client_side)
: _internal(InternalTag())
, _impl(service, cid, client_side) {}
TransportAdaptor::~TransportAdaptor() {}
uint64_t TransportAdaptor::GetConnectionId() {
return _impl.connection_id();
}
bool TransportAdaptor::IsClientSide() {
return _impl.is_client_side();
}
void TransportAdaptor::SetFlowControlHandler(FlowControlHandler *handler) {
_impl.set_flow_control_handler(handler);
}
void TransportAdaptor::SetFrameEventHandler(FrameEventHandler *handler) {
_impl.set_frame_event_handler(handler);
}
bool TransportAdaptor::SendPing(uint64_t info) {
return _impl.send_ping(info);
}
bool TransportAdaptor::SendSettings(const std::vector<std::pair<uint16_t, uint32_t>> &settings) {
return _impl.send_settings(settings);
}
bool TransportAdaptor::SendPriority(uint32_t stream_id, uint8_t weight, uint32_t depend_stream_id) {
return _impl.send_priority(stream_id, weight, depend_stream_id);
}
bool TransportAdaptor::SendRSTStream(uint32_t stream_id, uint32_t error_code) {
return _impl.send_rst_stream(stream_id, error_code);
}
void TransportAdaptor::SendGoAway(uint32_t last_stream_id, uint32_t error_code, const std::string &debug) {
_impl.send_goaway(error_code, last_stream_id, debug);
}
bool TransportAdaptor::SendWindowUpdate(uint32_t stream_id, WindowUpdate *wu) {
if (!wu) return false;
return _impl.send_window_update(stream_id, wu);
}
bool TransportAdaptor::SendRequest(Request *req) {
if (!req) return false;
return _impl.send_request(req);
}
bool TransportAdaptor::SendResponse(Response *rsp) {
if (!rsp) return false;
return _impl.send_response(rsp);
}
uint32_t TransportAdaptor::CreateStream(std::vector<std::pair<std::string, std::string>> *headers) {
if (headers && !headers->empty()) {
return _impl.send_push_promise(headers);
}
return _impl.create_stream();
}
/*
* Return -1 means an error occurred, return 0 means still need to provide
* data, other values greater than 0 means the length of a complete http2
* packet. When calling the ReceivedData function, at least one complete
* http2 package must be provided.
*/
int TransportAdaptor::CheckPackageLength(const uint8_t *data, uint32_t data_size) {
if (data_size < HTTP2_FRAME_HEADER_SIZE) return 0;
int64_t total_pack_len = 0;
if (_impl.need_verify_preface() && memcmp(data, http2_connection::PREFACE, 4) == 0) {
if (data_size < http2_connection::PREFACE_SIZE) {
return http2_connection::PREFACE_SIZE;
}
total_pack_len += http2_connection::PREFACE_SIZE;
data_size -= http2_connection::PREFACE_SIZE;
data += http2_connection::PREFACE_SIZE;
}
while (data_size >= HTTP2_FRAME_HEADER_SIZE) {
http2_frame_hdr hdr;
http2_frame_header_unpack(&hdr, data);
if (hdr.length > _impl.local_max_frame_size()) {
_impl.send_goaway(HTTP2_FRAME_SIZE_ERROR);
log_warn("TransportAdaptor: hdr.length(%lu) > max_frame_size(%lu)", hdr.length,
_impl.local_max_frame_size());
return -1;
}
uint32_t pack_len = hdr.length + HTTP2_FRAME_HEADER_SIZE;
if (total_pack_len + pack_len > INT32_MAX) {
break;
}
total_pack_len += pack_len;
if (pack_len > data_size) {
break;
}
data_size -= pack_len;
data += pack_len;
}
return static_cast<int>(total_pack_len);
}
/*
* Need to provide one or more complete http2 data package. To get the
* complete http2 package, please check CheckHttp2PackageLength function.
*/
void TransportAdaptor::ReceivedData(const uint8_t *package, uint32_t package_length) {
if (_impl.need_verify_preface()) {
if (package_length < http2_connection::PREFACE_SIZE ||
memcmp(package, http2_connection::PREFACE, http2_connection::PREFACE_SIZE) != 0) {
_impl.send_goaway(HTTP2_PROTOCOL_ERROR);
return;
}
_impl.verify_preface_done();
package_length -= http2_connection::PREFACE_SIZE;
package += http2_connection::PREFACE_SIZE;
}
while (package_length > 0) {
int result = _impl.package_process(package, package_length);
if (result == -1) {
break;
}
package_length -= result;
package += result;
}
}
// Call this function to notify a connection to be disconnected.
void TransportAdaptor::Shutdown() {
// TODO(SHADOW): cleanup
}
Transport *CreateTransport(uint64_t connection_id, bool client_side, SendService *service) {
auto transport = new TransportAdaptor(service, connection_id, client_side);
return transport;
}
void DestroyTransport(Transport *transport) {
delete transport;
}
void SetLogPrintFunction(void (*print_func)(const char *file, int line, int level, const char *message)) {
LogSetPrintFunction(print_func);
}
void SetLogLevel(int level) {
LogSetLevel(level);
}
Request::Request()
: stream_id_(0)
, finish_(false) {}
Request::~Request() {}
void Request::SetStreamId(uint32_t sid) {
stream_id_ = sid;
}
void Request::AddMetadata(const std::string &key, const std::string &value) {
headers_.push_back({key, value});
}
void Request::AppendData(const uint8_t *data, uint32_t size) {
data_.push_back(std::string(reinterpret_cast<const char *>(data), size));
}
void Request::Finish() {
finish_ = true;
}
void Request::Reset() {
stream_id_ = 0;
headers_.clear();
data_.clear();
finish_ = false;
}
Response::Response()
: stream_id_(0)
, finish_(false) {}
Response::~Response() {}
void Response::SetStreamId(uint32_t sid) {
stream_id_ = sid;
}
void Response::AddInitlizeMetadata(const std::string &key, const std::string &value) {
initlize_headers_.push_back({key, value});
}
void Response::AddTrailingMetadata(const std::string &key, const std::string &value) {
trailing_headers_.push_back({key, value});
}
void Response::AppendData(const uint8_t *data, uint32_t size) {
data_.push_back(std::string(reinterpret_cast<const char *>(data), size));
}
void Response::Finish() {
finish_ = true;
}
void Response::Reset() {
stream_id_ = 0;
initlize_headers_.clear();
trailing_headers_.clear();
data_.clear();
finish_ = false;
}
} // namespace http2
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。