aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdnet
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2026-01-11 23:06:33 +0300
committerlevlam <levlam@telegram.org>2026-01-11 23:06:33 +0300
commit751f8514c5783b2af541dc2ad8bce310ea6b8b9a (patch)
treee12d31833ed3c92448fc8a90b5a1ffd68fff2999 /tdnet
parentcf002f46848e52304b2e897b8cd469298e11806e (diff)
Add HttpHeaderCreator.cpp.
Diffstat (limited to 'tdnet')
-rw-r--r--tdnet/CMakeLists.txt1
-rw-r--r--tdnet/td/net/HttpHeaderCreator.cpp116
-rw-r--r--tdnet/td/net/HttpHeaderCreator.h107
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_;