Commit Diff


commit - ba3876885b731531ccfb33f786e2e9957bb197d3
commit + 59d5920624133077e335a537038eca69788aed94
blob - /dev/null
blob + ac1dcb2ed0c78c1415494b53d0518659100a06fb (mode 644)
--- /dev/null
+++ shared/gemini.cc
@@ -0,0 +1,23 @@
+/** Gemini protocol specifications */
+
+#include "gemini.h"
+
+namespace vostok
+{
+namespace gemini
+{
+
+
+const std::array<char, 2> CRLF{'\r', '\n'};
+
+const std::array<char, 1> SPACE{' '};
+
+const status_t STATUS_20_SUCCESS{'2', '0'};
+
+const status_t STATUS_53_PROXY_REQUEST_REFUSED{'5', '3'};
+
+const status_t STATUS_59_BAD_REQUEST{'5', '9'};
+
+
+}   // namespace gemini
+}   // namespace vostok
blob - /dev/null
blob + 350150182502bef33d71ddafd969c9b088bfc363 (mode 644)
--- /dev/null
+++ shared/gemini.h
@@ -0,0 +1,29 @@
+/** Gemini protocol specifications */
+
+#include <array>
+
+#pragma once
+
+
+namespace vostok
+{
+namespace gemini
+{
+
+
+constexpr auto MAX_URL_LENGTH = 1024;
+constexpr auto MAX_META_LENGTH = 1024;
+
+extern const std::array<char, 2> CRLF;
+extern const std::array<char, 1> SPACE;
+
+using status_t = std::array<char, 2>;
+extern const status_t STATUS_20_SUCCESS;
+extern const status_t STATUS_53_PROXY_REQUEST_REFUSED;
+extern const status_t STATUS_59_BAD_REQUEST;
+
+constexpr auto MAX_REQUEST_LENGTH = MAX_URL_LENGTH + CRLF.size();
+
+
+}   // namespace gemini
+}   // namespace vostok
blob - 4cf61e35947eddbbc156541b9b6168a7f7027c61
blob + 4f075e2d60ec499d9d3872b8bc76526e840a77b8
--- shared/transport.cc
+++ shared/transport.cc
@@ -46,13 +46,6 @@ bool read(not_null<struct tls *> ctx, span<char> &buff
 }   // namespace <unnamed>
 
 
-const std::array<char, 2> CRLF{'\r', '\n'};
-const std::array<char, 1> SPACE{' '};
-const status_t STATUS_20_SUCCESS{'2', '0'};
-const status_t STATUS_53_PROXY_REQUEST_REFUSED{'5', '3'};
-const status_t STATUS_59_BAD_REQUEST{'5', '9'};
-
-
 bool init()
 {
     if (tls_init() == -1)
@@ -144,7 +137,7 @@ void accept(
 }
 
 
-span<char> read_request(not_null<struct tls *> ctx, std::array<char, MAX_REQUEST_LENGTH> &buffer)
+span<char> read_request(not_null<struct tls *> ctx, std::array<char, gemini::MAX_REQUEST_LENGTH> &buffer)
 {
     span<char> request{buffer};
     if (!read(ctx, request))
@@ -156,7 +149,7 @@ span<char> read_request(not_null<struct tls *> ctx, st
         if (next == request.end())
             break;
 
-        if (*current == CRLF[0] && *next == CRLF[1])
+        if (*current == gemini::CRLF[0] && *next == gemini::CRLF[1])
         {
             // > servers MUST ignore anything sent after the first occurrence of a <CR><LF>.
             return request.first(current - request.begin());
@@ -167,16 +160,16 @@ span<char> read_request(not_null<struct tls *> ctx, st
 }
 
 
-bool send_response(not_null<struct tls *> ctx, status_t status, span<const char> meta)
+bool send_response(not_null<struct tls *> ctx, gemini::status_t status, span<const char> meta)
 {
     // > <STATUS><SPACE><META><CR><LF>
-    std::array<char, status.size() + SPACE.size() + MAX_META_LENGTH + CRLF.size()> buff;
+    std::array<char, status.size() + gemini::SPACE.size() + gemini::MAX_META_LENGTH + gemini::CRLF.size()> buff;
     auto current = buff.begin();
     current = std::copy(status.cbegin(), status.cend(), current);
-    current = std::copy(SPACE.cbegin(), SPACE.cend(), current);
-    assert(meta.size() <= MAX_META_LENGTH);
+    current = std::copy(gemini::SPACE.cbegin(), gemini::SPACE.cend(), current);
+    assert(meta.size() <= gemini::MAX_META_LENGTH);
     current = std::copy(meta.begin(), meta.end(), current);
-    current = std::copy(CRLF.cbegin(), CRLF.cend(), current);
+    current = std::copy(gemini::CRLF.cbegin(), gemini::CRLF.cend(), current);
 
     return send(ctx, span<char const>{&buff[0], static_cast<size_t>(current - buff.begin())});
 }
blob - df192b248ee3733f9ec9c3728ae77d6d18f9fbe8
blob + 9f0cf3c93d468653b56bbdb97def9bd47655f70a
--- shared/transport.h
+++ shared/transport.h
@@ -6,7 +6,7 @@
 #include <unique_fd>
 #include <span>
 
-#include <array>
+#include "gemini.h"
 
 #include <tls.h>
 
@@ -19,18 +19,6 @@ namespace transport
 {
 
 
-constexpr auto MAX_URL_LENGTH = 1024;
-constexpr auto MAX_META_LENGTH = 1024;
-
-extern const std::array<char, 2> CRLF;
-using status_t = std::array<char, 2>;
-extern const status_t STATUS_20_SUCCESS;
-extern const status_t STATUS_53_PROXY_REQUEST_REFUSED;
-extern const status_t STATUS_59_BAD_REQUEST;
-
-
-constexpr auto MAX_REQUEST_LENGTH = MAX_URL_LENGTH + CRLF.size();
-
 /** `struct tls *` smart pointer */
 typedef std::unique_ptr<struct tls, decltype(&tls_free)> context_t;
 
@@ -85,11 +73,11 @@ void accept(
 
 
 /** Read genimi request and return url (empty url - error) */
-span<char> read_request(not_null<struct tls *> ctx, std::array<char, MAX_REQUEST_LENGTH> &buffer);
+span<char> read_request(not_null<struct tls *> ctx, std::array<char, gemini::MAX_REQUEST_LENGTH> &buffer);
 
 
 /** Write gemini response */
-bool send_response(not_null<struct tls *> ctx, status_t status, span<const char> meta);
+bool send_response(not_null<struct tls *> ctx, gemini::status_t status, span<const char> meta);
 
 
 /** Send raw bytes */
blob - 8c37ddf4527c26aaa85a1c838d97f429b1423e38
blob + 9d3cb21091bc3851c1517677466510156fa16d9a
--- vostokd/Makefile
+++ vostokd/Makefile
@@ -15,6 +15,8 @@ CXXFILES	+= ${.PATH}../shared/error.cc
 HXXFILES	+= ${.PATH}../shared/error.h
 CXXFILES	+= command_line_arguments.cc
 HXXFILES	+= command_line_arguments.h
+CXXFILES	+= ${.PATH}../shared/gemini.cc
+HXXFILES	+= ${.PATH}../shared/gemini.h
 
 vostokd: ${CXXFILES} ${HXXFILES}
 	${CXX} ${CXXFLAGS} ${CXXFILES} -o vostokd
blob - 0ad5894657e7261427d7baf9bded82d9f3501c19
blob + 2b52c558ec36360add80c7d61fc57b7506b75a58
--- vostokd/vostokd.cc
+++ vostokd/vostokd.cc
@@ -43,23 +43,23 @@ void client_thread(transport::accepted_context::value 
     const transport::accepted_context ctx{raw_value};
     assert(ctx);
 
-    std::array<char, transport::MAX_REQUEST_LENGTH> buffer;
+    std::array<char, gemini::MAX_REQUEST_LENGTH> buffer;
     auto url = transport::read_request(ctx.get_ctx(), buffer);
     if (!url.size())
     {
-        transport::send_response(ctx.get_ctx(), transport::STATUS_59_BAD_REQUEST, meta::bad_request);
+        transport::send_response(ctx.get_ctx(), gemini::STATUS_59_BAD_REQUEST, meta::bad_request);
         return;
     }
 
     // check and skip scheme
     if (url.size() < gemini_scheme.size())
     {
-        transport::send_response(ctx.get_ctx(), transport::STATUS_59_BAD_REQUEST, meta::url_too_short);
+        transport::send_response(ctx.get_ctx(), gemini::STATUS_59_BAD_REQUEST, meta::url_too_short);
         return;
     }
     if (!std::equal(gemini_scheme.begin(), gemini_scheme.end(), url.begin()))
     {
-        transport::send_response(ctx.get_ctx(), transport::STATUS_53_PROXY_REQUEST_REFUSED, meta::non_gemini);
+        transport::send_response(ctx.get_ctx(), gemini::STATUS_53_PROXY_REQUEST_REFUSED, meta::non_gemini);
         return;
     }
     url = url.subspan(gemini_scheme.size());
@@ -85,7 +85,7 @@ void client_thread(transport::accepted_context::value 
 
 
     // > If <META> is an empty string, the MIME type MUST default to "text/gemini; charset=utf-8".
-    transport::send_response(ctx.get_ctx(), transport::STATUS_20_SUCCESS, {});
+    transport::send_response(ctx.get_ctx(), gemini::STATUS_20_SUCCESS, {});
     static const char content[] = "# Vostok server\r\n\r\n...work-in-progress...";
     transport::send(ctx.get_ctx(), cut_null(content));
 }