aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/http/fetch/httpheader.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/http/fetch/httpheader.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/http/fetch/httpheader.h')
-rw-r--r--library/cpp/http/fetch/httpheader.h287
1 files changed, 287 insertions, 0 deletions
diff --git a/library/cpp/http/fetch/httpheader.h b/library/cpp/http/fetch/httpheader.h
new file mode 100644
index 00000000000..b2810bbd413
--- /dev/null
+++ b/library/cpp/http/fetch/httpheader.h
@@ -0,0 +1,287 @@
+#pragma once
+
+#include "exthttpcodes.h"
+
+#include <library/cpp/mime/types/mime.h>
+
+#include <util/system/defaults.h>
+#include <util/system/compat.h>
+#include <util/generic/string.h>
+#include <util/generic/ylimits.h>
+#include <util/system/maxlen.h>
+
+#include <ctime>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+// This is ugly solution but here a lot of work to do it the right way.
+#define FETCHER_URL_MAX 8192
+
+extern const i64 DEFAULT_RETRY_AFTER; /// == -1
+extern const i64 DEFAULT_IF_MODIFIED_SINCE; /// == -1
+extern const i32 DEFAULT_MAX_AGE; /// == -1
+extern const i8 DEFAULT_REQUEST_PRIORITY; /// == -1
+extern const i32 DEFAULT_RESPONSE_TIMEOUT; /// == -1
+
+#define HTTP_PREFIX "http://"
+#define MAX_LANGREGION_LEN 4
+#define MAXWORD_LEN 55
+
+enum HTTP_COMPRESSION {
+ HTTP_COMPRESSION_UNSET = 0,
+ HTTP_COMPRESSION_ERROR = 1,
+ HTTP_COMPRESSION_IDENTITY = 2,
+ HTTP_COMPRESSION_GZIP = 3,
+ HTTP_COMPRESSION_DEFLATE = 4,
+ HTTP_COMPRESSION_COMPRESS = 5,
+ HTTP_COMPRESSION_MAX = 6
+};
+
+enum HTTP_METHOD {
+ HTTP_METHOD_UNDEFINED = -1,
+ HTTP_METHOD_OPTIONS,
+ HTTP_METHOD_GET,
+ HTTP_METHOD_HEAD,
+ HTTP_METHOD_POST,
+ HTTP_METHOD_PUT,
+ HTTP_METHOD_DELETE,
+ HTTP_METHOD_TRACE,
+ HTTP_METHOD_CONNECT,
+ HTTP_METHOD_EXTENSION
+};
+
+enum HTTP_CONNECTION {
+ HTTP_CONNECTION_UNDEFINED = -1,
+ HTTP_CONNECTION_KEEP_ALIVE = 0,
+ HTTP_CONNECTION_CLOSE = 1
+};
+
+/// Class represents general http header fields.
+struct THttpBaseHeader {
+public:
+ i16 error;
+ i32 header_size;
+ i32 entity_size;
+ i64 content_length;
+ i64 http_time; // seconds since epoch
+ i64 content_range_start; // Content-Range: first-byte-pos
+ i64 content_range_end; // Content-Range: last-byte-pos
+ i64 content_range_entity_length; // Content-Range: entity-length
+ i8 http_minor;
+ i8 mime_type;
+ i8 charset;
+ i8 compression_method;
+ i8 transfer_chunked;
+ i8 connection_closed;
+ TString base;
+
+public:
+ void Init() {
+ error = 0;
+ header_size = 0;
+ entity_size = 0;
+ content_length = -1;
+ http_time = -1;
+ http_minor = -1;
+ mime_type = -1;
+ charset = -1;
+ compression_method = HTTP_COMPRESSION_UNSET;
+ transfer_chunked = -1;
+ connection_closed = HTTP_CONNECTION_UNDEFINED;
+ content_range_start = -1;
+ content_range_end = -1;
+ content_range_entity_length = -1;
+ base.clear();
+ }
+
+ void Print() const {
+ printf("content_length: %" PRIi64 "\n", content_length);
+ printf("http_time: %" PRIi64 "\n", http_time);
+ printf("http_minor: %" PRIi8 "\n", http_minor);
+ printf("mime_type: %" PRIi8 "\n", mime_type);
+ printf("charset: %" PRIi8 "\n", charset);
+ printf("compression_method: %" PRIi8 "\n", compression_method);
+ printf("transfer_chunked: %" PRIi8 "\n", transfer_chunked);
+ printf("connection_closed: %" PRIi8 "\n", connection_closed);
+ printf("content_range_start: %" PRIi64 "\n", content_range_start);
+ printf("content_range_end: %" PRIi64 "\n", content_range_end);
+ printf("content_range_entity_length: %" PRIi64 "\n", content_range_entity_length);
+ printf("base: \"%s\"\n", base.c_str());
+ printf("error: %" PRIi16 "\n", error);
+ }
+
+ int SetBase(const char* path,
+ const char* hostNamePtr = nullptr,
+ int hostNameLength = 0) {
+ if (*path == '/') {
+ base = "http://";
+ base += TStringBuf(hostNamePtr, hostNameLength);
+ base += path;
+ } else {
+ base = path;
+ }
+ return error;
+ }
+};
+
+enum { HREFLANG_MAX = FETCHER_URL_MAX * 2 };
+/// Class represents Http Response Header.
+struct THttpHeader: public THttpBaseHeader {
+public:
+ i8 accept_ranges;
+ i8 squid_error;
+ i8 x_robots_tag; // deprecated, use x_robots_state instead
+ i16 http_status;
+ TString location;
+ TString rel_canonical;
+ char hreflangs[HREFLANG_MAX];
+ i64 retry_after;
+ TString x_robots_state; // 'xxxxx' format, see `library/html/zoneconf/parsefunc.cpp`
+
+public:
+ void Init() {
+ THttpBaseHeader::Init();
+ accept_ranges = -1;
+ squid_error = 0;
+ x_robots_tag = 0;
+ rel_canonical.clear();
+ http_status = -1;
+ location.clear();
+ hreflangs[0] = 0;
+ retry_after = DEFAULT_RETRY_AFTER;
+ x_robots_state = "xxxxx";
+ }
+
+ void Print() const {
+ THttpBaseHeader::Print();
+ printf("http_status: %" PRIi16 "\n", http_status);
+ printf("squid_error: %" PRIi8 "\n", squid_error);
+ printf("accept_ranges: %" PRIi8 "\n", accept_ranges);
+ printf("location: \"%s\"\n", location.c_str());
+ printf("retry_after: %" PRIi64 "\n", retry_after);
+ }
+};
+
+struct THttpRequestHeader: public THttpBaseHeader {
+public:
+ TString request_uri;
+ char host[HOST_MAX];
+ char from[MAXWORD_LEN];
+ char user_agent[MAXWORD_LEN];
+ char x_yandex_langregion[MAX_LANGREGION_LEN];
+ char x_yandex_sourcename[MAXWORD_LEN];
+ char x_yandex_requesttype[MAXWORD_LEN];
+ char x_yandex_fetchoptions[MAXWORD_LEN];
+ i8 http_method;
+ i8 x_yandex_request_priority;
+ i32 x_yandex_response_timeout;
+ i32 max_age;
+ i64 if_modified_since;
+
+public:
+ THttpRequestHeader() {
+ Init();
+ }
+
+ void Init() {
+ request_uri.clear();
+ host[0] = 0;
+ from[0] = 0;
+ user_agent[0] = 0;
+ x_yandex_langregion[0] = 0;
+ x_yandex_sourcename[0] = 0;
+ x_yandex_requesttype[0] = 0;
+ x_yandex_fetchoptions[0] = 0;
+ http_method = HTTP_METHOD_UNDEFINED;
+ x_yandex_request_priority = DEFAULT_REQUEST_PRIORITY;
+ x_yandex_response_timeout = DEFAULT_RESPONSE_TIMEOUT;
+ max_age = DEFAULT_MAX_AGE;
+ if_modified_since = DEFAULT_IF_MODIFIED_SINCE;
+ THttpBaseHeader::Init();
+ }
+
+ void Print() const {
+ THttpBaseHeader::Print();
+ printf("request_uri: \"%s\"\n", request_uri.c_str());
+ printf("host: \"%s\"\n", host);
+ printf("from: \"%s\"\n", from);
+ printf("user_agent: \"%s\"\n", user_agent);
+ printf("http_method: %" PRIi8 "\n", http_method);
+ printf("response_timeout: %" PRIi32 "\n", x_yandex_response_timeout);
+ printf("max_age: %" PRIi32 "\n", max_age);
+ printf("if_modified_since: %" PRIi64 "\n", if_modified_since);
+ }
+
+ /// It doesn't care about errors in request or headers, where
+ /// request_uri equals to '*'.
+ /// This returns copy of the string, which you have to delete.
+ TString GetUrl() {
+ TString url;
+ if (host[0] == 0 || !strcmp(host, "")) {
+ url = request_uri;
+ } else {
+ url = HTTP_PREFIX;
+ url += host;
+ url += request_uri;
+ }
+ return url;
+ }
+
+ char* GetUrl(char* buffer, size_t size) {
+ if (host[0] == 0 || !strcmp(host, "")) {
+ strlcpy(buffer, request_uri.c_str(), size);
+ } else {
+ snprintf(buffer, size, "http://%s%s", host, request_uri.c_str());
+ }
+ return buffer;
+ }
+};
+
+class THttpAuthHeader: public THttpHeader {
+public:
+ char* realm;
+ char* nonce;
+ char* opaque;
+ bool stale;
+ int algorithm;
+ bool qop_auth;
+ bool use_auth;
+
+ //we do not provide auth-int variant as too heavy
+ //bool qop_auth_int;
+
+ THttpAuthHeader()
+ : realm(nullptr)
+ , nonce(nullptr)
+ , opaque(nullptr)
+ , stale(false)
+ , algorithm(0)
+ , qop_auth(false)
+ , use_auth(true)
+ {
+ THttpHeader::Init();
+ }
+
+ ~THttpAuthHeader() {
+ free(realm);
+ free(nonce);
+ free(opaque);
+ }
+
+ void Print() {
+ THttpHeader::Print();
+ if (use_auth) {
+ if (realm)
+ printf("realm: \"%s\"\n", realm);
+ if (nonce)
+ printf("nonce: \"%s\"\n", nonce);
+ if (opaque)
+ printf("opaque: \"%s\"\n", opaque);
+ printf("stale: %d\n", stale);
+ printf("algorithm: %d\n", algorithm);
+ printf("qop_auth: %d\n", qop_auth);
+ }
+ }
+};