diff options
Diffstat (limited to 'src/transport.hh')
| -rw-r--r-- | src/transport.hh | 147 |
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 |
