summaryrefslogtreecommitdiff
path: root/src/transport.hh
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
committerJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
commit6232d13f5321b87ddf12a1aa36b4545da45f173d (patch)
tree23f3316470a14136debd9d02f9e920ca2b06f4cc /src/transport.hh
Travel3: Simple image and video display site
Reads the images and videos from filesystem and builds a site in memroy.
Diffstat (limited to 'src/transport.hh')
-rw-r--r--src/transport.hh147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/transport.hh b/src/transport.hh
new file mode 100644
index 0000000..5e6733f
--- /dev/null
+++ b/src/transport.hh
@@ -0,0 +1,147 @@
+#ifndef TRANSPORT_HH
+#define TRANSPORT_HH
+
+#include "unique_fd.hh"
+
+#include <filesystem>
+#include <functional>
+#include <memory>
+#include <optional>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+class Buffer;
+class Config;
+class Logger;
+class Looper;
+class TaskRunner;
+
+class Transport {
+public:
+ class Request {
+ public:
+ virtual ~Request() = default;
+
+ virtual std::string_view method() const = 0;
+ virtual std::string_view path() const = 0;
+ virtual std::string_view query(std::string_view name) const = 0;
+ virtual std::optional<std::string> header_one(
+ std::string_view name) const = 0;
+ virtual std::vector<std::string> header_all(
+ std::string_view name) const = 0;
+ };
+
+ class Input {
+ public:
+ virtual ~Input() = default;
+
+ enum class Return {
+ OK, // At least one byte was added to buffer.
+ FULL, // Zero bytes added to buffer as it is full.
+ END, // Zero or more bytes added to buffer but there are no more bytes
+ // available because input has ended.
+ ERR, // No bytes added to buffer and there was an fatal error reading
+ // any more bytes.
+ WAIT, // Zero or more bytes added to buffer but wait before calling
+ // fill again (see wait_once).
+ };
+
+ virtual Return fill(Buffer* buffer, size_t buf_request_size = 1) = 0;
+
+ // Setup callback to be called when Input is ready to be read again using
+ // looper. Callback will only be called once. Callback might be called
+ // before wait returns if Input is already ready. If Input is destroyed
+ // before getting ready the callback will never be called.
+ virtual void wait_once(std::shared_ptr<Looper> looper,
+ std::function<void()> callback) = 0;
+
+ protected:
+ Input() = default;
+ };
+
+ class Response {
+ public:
+ virtual ~Response() = default;
+
+ virtual uint16_t code() const = 0;
+ virtual std::vector<std::pair<std::string, std::string>> const&
+ headers() const = 0;
+ // Only call this once. If it returns null, call open_content_async instead.
+ virtual std::unique_ptr<Input> open_content() = 0;
+ // Only call this once and only if open_content() first returned nullptr.
+ // If response is destroyed before callback is posted the callback will
+ // never be posted. But if callback is already posted then it will run,
+ // and the input will still be valid.
+ virtual void open_content_async(
+ std::shared_ptr<TaskRunner> runner,
+ std::function<void(std::unique_ptr<Input>)> callback);
+
+ virtual void add_header(std::string name, std::string value) = 0;
+
+ protected:
+ Response() = default;
+ };
+
+ std::unique_ptr<Response> create_ok_data(std::string data);
+ std::unique_ptr<Response> create_ok_file(std::filesystem::path path);
+ std::unique_ptr<Response> create_ok_exif_thumbnail(
+ std::filesystem::path path);
+ std::unique_ptr<Response> create_not_found();
+ std::unique_ptr<Response> create_redirect(std::string target,
+ bool temporary = true);
+ virtual std::unique_ptr<Response> create_data(
+ uint16_t code, std::string data) = 0;
+ virtual std::unique_ptr<Response> create_file(
+ uint16_t code, std::filesystem::path data) = 0;
+ virtual std::unique_ptr<Response> create_exif_thumbnail(
+ uint16_t code, std::filesystem::path data) = 0;
+
+ class Handler {
+ public:
+ virtual ~Handler() = default;
+
+ virtual std::unique_ptr<Response> request(Transport* transport,
+ Request const* request) = 0;
+
+ protected:
+ Handler() = default;
+ };
+
+ // Takes care of GET/HEAD, optional cache headers and general housekeeping.
+ // Also removes // and similar from paths.
+ static std::unique_ptr<Handler> create_default_handler(
+ std::shared_ptr<Logger> logger,
+ Handler* handler);
+
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+
+ virtual std::unique_ptr<Transport> create(
+ std::shared_ptr<Logger> logger,
+ std::shared_ptr<Looper> looper,
+ std::shared_ptr<TaskRunner> runner,
+ // config_logger is used to write any errors during create
+ // when reading the config. No reference kept as with logger.
+ Logger* config_logger,
+ Config const* config,
+ Handler* handler) = 0;
+
+ protected:
+ Factory() = default;
+ Factory(Factory const&) = delete;
+ Factory& operator=(Factory const&) = delete;
+ };
+
+ virtual ~Transport() = default;
+
+ virtual void add_client(unique_fd&& fd) = 0;
+
+protected:
+ Transport() = default;
+ Transport(Transport const&) = delete;
+ Transport& operator=(Transport const&) = delete;
+};
+
+#endif // TRANSPORT_HH