commit - ba3876885b731531ccfb33f786e2e9957bb197d3
commit + 59d5920624133077e335a537038eca69788aed94
blob - /dev/null
blob + ac1dcb2ed0c78c1415494b53d0518659100a06fb (mode 644)
--- /dev/null
+++ shared/gemini.cc
+/** 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
+/** 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
} // 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)
}
-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))
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());
}
-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
#include <unique_fd>
#include <span>
-#include <array>
+#include "gemini.h"
#include <tls.h>
{
-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;
/** 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
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
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());
// > 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));
}