aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdutils
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2024-05-20 13:46:32 +0300
committerlevlam <levlam@telegram.org>2024-05-20 13:46:32 +0300
commit53c3e791976c20fdc835c4c196ee78fc812f321a (patch)
tree49f0f56c3e5f7c8561650636aa06365b408c73c8 /tdutils
parent699707a09bdcd37a3ef1739d512fe03d5f186b30 (diff)
Move class HttpDate to tdutils.
Diffstat (limited to 'tdutils')
-rw-r--r--tdutils/CMakeLists.txt2
-rw-r--r--tdutils/td/utils/HttpDate.cpp92
-rw-r--r--tdutils/td/utils/HttpDate.h34
3 files changed, 128 insertions, 0 deletions
diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt
index 1240682fc..f63bd90e5 100644
--- a/tdutils/CMakeLists.txt
+++ b/tdutils/CMakeLists.txt
@@ -107,6 +107,7 @@ set(TDUTILS_SOURCE
td/utils/Gzip.cpp
td/utils/GzipByteFlow.cpp
td/utils/Hints.cpp
+ td/utils/HttpDate.cpp
td/utils/HttpUrl.cpp
td/utils/JsonBuilder.cpp
td/utils/logging.cpp
@@ -231,6 +232,7 @@ set(TDUTILS_SOURCE
td/utils/HazardPointers.h
td/utils/Heap.h
td/utils/Hints.h
+ td/utils/HttpDate.h
td/utils/HttpUrl.h
td/utils/int_types.h
td/utils/invoke.h
diff --git a/tdutils/td/utils/HttpDate.cpp b/tdutils/td/utils/HttpDate.cpp
new file mode 100644
index 000000000..da290ae3a
--- /dev/null
+++ b/tdutils/td/utils/HttpDate.cpp
@@ -0,0 +1,92 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
+//
+// 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/utils/HttpDate.h"
+
+#include "td/utils/misc.h"
+#include "td/utils/Parser.h"
+#include "td/utils/Slice.h"
+
+namespace td {
+
+Result<int32> HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) {
+ if (year < 1970 || year > 2037) {
+ return Status::Error("Invalid year");
+ }
+ if (month < 1 || month > 12) {
+ return Status::Error("Invalid month");
+ }
+ if (day < 1 || day > days_in_month(year, month)) {
+ return Status::Error("Invalid day");
+ }
+ if (hour < 0 || hour >= 24) {
+ return Status::Error("Invalid hour");
+ }
+ if (minute < 0 || minute >= 60) {
+ return Status::Error("Invalid minute");
+ }
+ if (second < 0 || second > 60) {
+ return Status::Error("Invalid second");
+ }
+
+ int32 res = 0;
+ for (int32 y = 1970; y < year; y++) {
+ res += (is_leap(y) + 365) * seconds_in_day();
+ }
+ for (int32 m = 1; m < month; m++) {
+ res += days_in_month(year, m) * seconds_in_day();
+ }
+ res += (day - 1) * seconds_in_day();
+ res += hour * 60 * 60;
+ res += minute * 60;
+ res += second;
+ return res;
+}
+
+Result<int32> HttpDate::parse_http_date(string slice) {
+ Parser p(slice);
+ p.read_till(','); // ignore week day
+ p.skip(',');
+ p.skip_whitespaces();
+ p.skip_nofail('0');
+ TRY_RESULT(day, to_integer_safe<int32>(p.read_word()));
+ auto month_name = p.read_word();
+ to_lower_inplace(month_name);
+ TRY_RESULT(year, to_integer_safe<int32>(p.read_word()));
+ p.skip_whitespaces();
+ p.skip_nofail('0');
+ TRY_RESULT(hour, to_integer_safe<int32>(p.read_till(':')));
+ p.skip(':');
+ p.skip_nofail('0');
+ TRY_RESULT(minute, to_integer_safe<int32>(p.read_till(':')));
+ p.skip(':');
+ p.skip_nofail('0');
+ TRY_RESULT(second, to_integer_safe<int32>(p.read_word()));
+ auto gmt = p.read_word();
+ TRY_STATUS(std::move(p.status()));
+ if (gmt != "GMT") {
+ return Status::Error("Timezone must be GMT");
+ }
+
+ static Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
+
+ int month = 0;
+
+ for (int m = 1; m <= 12; m++) {
+ if (month_names[m - 1] == month_name) {
+ month = m;
+ break;
+ }
+ }
+
+ if (month == 0) {
+ return Status::Error("Unknown month name");
+ }
+
+ return to_unix_time(year, month, day, hour, minute, second);
+}
+
+} // namespace td
diff --git a/tdutils/td/utils/HttpDate.h b/tdutils/td/utils/HttpDate.h
new file mode 100644
index 000000000..a2daf0784
--- /dev/null
+++ b/tdutils/td/utils/HttpDate.h
@@ -0,0 +1,34 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
+//
+// 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)
+//
+#pragma once
+
+#include "td/utils/common.h"
+#include "td/utils/Status.h"
+
+namespace td {
+
+class HttpDate {
+ static bool is_leap(int32 year) {
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+ }
+
+ static int32 seconds_in_day() {
+ return 24 * 60 * 60;
+ }
+
+ public:
+ static int32 days_in_month(int32 year, int32 month) {
+ static int cnt[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ return cnt[month - 1] + (month == 2 && is_leap(year));
+ }
+
+ static Result<int32> to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second);
+
+ static Result<int32> parse_http_date(string slice);
+};
+
+} // namespace td