diff options
| author | levlam <levlam@telegram.org> | 2026-01-11 23:06:33 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2026-01-11 23:06:33 +0300 |
| commit | 751f8514c5783b2af541dc2ad8bce310ea6b8b9a (patch) | |
| tree | e12d31833ed3c92448fc8a90b5a1ffd68fff2999 /tdnet | |
| parent | cf002f46848e52304b2e897b8cd469298e11806e (diff) | |
Add HttpHeaderCreator.cpp.
Diffstat (limited to 'tdnet')
| -rw-r--r-- | tdnet/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tdnet/td/net/HttpHeaderCreator.cpp | 116 | ||||
| -rw-r--r-- | tdnet/td/net/HttpHeaderCreator.h | 107 |
3 files changed, 130 insertions, 94 deletions
diff --git a/tdnet/CMakeLists.txt b/tdnet/CMakeLists.txt index ad4e8f575..ae5bab3c7 100644 --- a/tdnet/CMakeLists.txt +++ b/tdnet/CMakeLists.txt @@ -19,6 +19,7 @@ set(TDNET_SOURCE td/net/HttpConnectionBase.cpp td/net/HttpContentLengthByteFlow.cpp td/net/HttpFile.cpp + td/net/HttpHeaderCreator.cpp td/net/HttpInboundConnection.cpp td/net/HttpOutboundConnection.cpp td/net/HttpProxy.cpp diff --git a/tdnet/td/net/HttpHeaderCreator.cpp b/tdnet/td/net/HttpHeaderCreator.cpp new file mode 100644 index 000000000..ddeea558d --- /dev/null +++ b/tdnet/td/net/HttpHeaderCreator.cpp @@ -0,0 +1,116 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2026 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/net/HttpHeaderCreator.h" + +#include "td/utils/logging.h" + +namespace td { + +string HttpHeaderCreator::get_host_header(HttpUrl::Protocol protocol, Slice host, int32 port); + if ((protocol == HttpUrl::Protocol::Https && port == 443) || + (protocol == HttpUrl::Protocol::Http && port == 80)) { + return host; + } else { + return PSTRING() << host << ':' << port; + } +} + +Result<Slice> HttpHeaderCreator::finish(Slice content) { + sb_ << "\r\n"; + if (!content.empty()) { + sb_ << content; + } + if (sb_.is_error()) { + return Status::Error("Too many headers"); + } + return sb_.as_cslice(); +} + +CSlice HttpHeaderCreator::get_status_line(int http_status_code) { + if (http_status_code == 200) { + return CSlice("OK"); + } + switch (http_status_code) { + case 201: + return CSlice("Created"); + case 202: + return CSlice("Accepted"); + case 204: + return CSlice("No Content"); + case 206: + return CSlice("Partial Content"); + case 301: + return CSlice("Moved Permanently"); + case 302: + return CSlice("Found"); + case 303: + return CSlice("See Other"); + case 304: + return CSlice("Not Modified"); + case 307: + return CSlice("Temporary Redirect"); + case 308: + return CSlice("Permanent Redirect"); + case 400: + return CSlice("Bad Request"); + case 401: + return CSlice("Unauthorized"); + case 403: + return CSlice("Forbidden"); + case 404: + return CSlice("Not Found"); + case 405: + return CSlice("Method Not Allowed"); + case 406: + return CSlice("Not Acceptable"); + case 408: + return CSlice("Request Timeout"); + case 409: + return CSlice("Conflict"); + case 410: + return CSlice("Gone"); + case 411: + return CSlice("Length Required"); + case 412: + return CSlice("Precondition Failed"); + case 413: + return CSlice("Request Entity Too Large"); + case 414: + return CSlice("Request-URI Too Long"); + case 415: + return CSlice("Unsupported Media Type"); + case 416: + return CSlice("Range Not Satisfiable"); + case 417: + return CSlice("Expectation Failed"); + case 418: + return CSlice("I'm a teapot"); + case 421: + return CSlice("Misdirected Request"); + case 426: + return CSlice("Upgrade Required"); + case 429: + return CSlice("Too Many Requests"); + case 431: + return CSlice("Request Header Fields Too Large"); + case 480: + return CSlice("Temporarily Unavailable"); + case 501: + return CSlice("Not Implemented"); + case 502: + return CSlice("Bad Gateway"); + case 503: + return CSlice("Service Unavailable"); + case 505: + return CSlice("HTTP Version Not Supported"); + default: + LOG_IF(ERROR, http_status_code != 500) << "Unsupported status code " << http_status_code << " returned"; + return CSlice("Internal Server Error"); + } +} + +} // namespace td diff --git a/tdnet/td/net/HttpHeaderCreator.h b/tdnet/td/net/HttpHeaderCreator.h index 0799b2a8d..3ce3743df 100644 --- a/tdnet/td/net/HttpHeaderCreator.h +++ b/tdnet/td/net/HttpHeaderCreator.h @@ -6,7 +6,6 @@ // #pragma once -#include "td/utils/logging.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" @@ -15,136 +14,56 @@ namespace td { class HttpHeaderCreator { - public: static constexpr size_t MAX_HEADER = 4096; + + public: HttpHeaderCreator() : sb_(MutableSlice{header_, MAX_HEADER}) { } + void init_ok() { sb_ = StringBuilder(MutableSlice{header_, MAX_HEADER}); sb_ << "HTTP/1.1 200 OK\r\n"; } + void init_get(Slice url) { sb_ = StringBuilder(MutableSlice{header_, MAX_HEADER}); sb_ << "GET " << url << " HTTP/1.1\r\n"; } + void init_post(Slice url) { sb_ = StringBuilder(MutableSlice{header_, MAX_HEADER}); sb_ << "POST " << url << " HTTP/1.1\r\n"; } + void init_error(int code, Slice reason) { sb_ = StringBuilder(MutableSlice{header_, MAX_HEADER}); sb_ << "HTTP/1.1 " << code << " " << reason << "\r\n"; } + void init_status_line(int http_status_code) { init_error(http_status_code, get_status_line(http_status_code)); } + void add_header(Slice key, Slice value) { sb_ << key << ": " << value << "\r\n"; } + void set_content_type(Slice type) { add_header("Content-Type", type); } + void set_content_size(size_t size) { add_header("Content-Length", PSLICE() << size); } + void set_keep_alive() { add_header("Connection", "keep-alive"); } - Result<Slice> finish(Slice content = {}) TD_WARN_UNUSED_RESULT { - sb_ << "\r\n"; - if (!content.empty()) { - sb_ << content; - } - if (sb_.is_error()) { - return Status::Error("Too many headers"); - } - return sb_.as_cslice(); - } + Result<Slice> finish(Slice content = {}) TD_WARN_UNUSED_RESULT; private: - static CSlice get_status_line(int http_status_code) { - if (http_status_code == 200) { - return CSlice("OK"); - } - switch (http_status_code) { - case 201: - return CSlice("Created"); - case 202: - return CSlice("Accepted"); - case 204: - return CSlice("No Content"); - case 206: - return CSlice("Partial Content"); - case 301: - return CSlice("Moved Permanently"); - case 302: - return CSlice("Found"); - case 303: - return CSlice("See Other"); - case 304: - return CSlice("Not Modified"); - case 307: - return CSlice("Temporary Redirect"); - case 308: - return CSlice("Permanent Redirect"); - case 400: - return CSlice("Bad Request"); - case 401: - return CSlice("Unauthorized"); - case 403: - return CSlice("Forbidden"); - case 404: - return CSlice("Not Found"); - case 405: - return CSlice("Method Not Allowed"); - case 406: - return CSlice("Not Acceptable"); - case 408: - return CSlice("Request Timeout"); - case 409: - return CSlice("Conflict"); - case 410: - return CSlice("Gone"); - case 411: - return CSlice("Length Required"); - case 412: - return CSlice("Precondition Failed"); - case 413: - return CSlice("Request Entity Too Large"); - case 414: - return CSlice("Request-URI Too Long"); - case 415: - return CSlice("Unsupported Media Type"); - case 416: - return CSlice("Range Not Satisfiable"); - case 417: - return CSlice("Expectation Failed"); - case 418: - return CSlice("I'm a teapot"); - case 421: - return CSlice("Misdirected Request"); - case 426: - return CSlice("Upgrade Required"); - case 429: - return CSlice("Too Many Requests"); - case 431: - return CSlice("Request Header Fields Too Large"); - case 480: - return CSlice("Temporarily Unavailable"); - case 501: - return CSlice("Not Implemented"); - case 502: - return CSlice("Bad Gateway"); - case 503: - return CSlice("Service Unavailable"); - case 505: - return CSlice("HTTP Version Not Supported"); - default: - LOG_IF(ERROR, http_status_code != 500) << "Unsupported status code " << http_status_code << " returned"; - return CSlice("Internal Server Error"); - } - } + static CSlice get_status_line(int http_status_code); char header_[MAX_HEADER]; StringBuilder sb_; |
