summaryrefslogtreecommitdiff
path: root/src/fcgi_protocol.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/fcgi_protocol.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/fcgi_protocol.hh')
-rw-r--r--src/fcgi_protocol.hh191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/fcgi_protocol.hh b/src/fcgi_protocol.hh
new file mode 100644
index 0000000..f41c4a8
--- /dev/null
+++ b/src/fcgi_protocol.hh
@@ -0,0 +1,191 @@
+#ifndef FCGI_PROTOCOL_HH
+#define FCGI_PROTOCOL_HH
+
+#include <memory>
+#include <stdint.h>
+#include <string>
+
+class Buffer;
+class RoBuffer;
+
+namespace fcgi {
+
+enum RecordType {
+ BeginRequest = 1,
+ AbortRequest = 2,
+ EndRequest = 3,
+ Params = 4,
+ Stdin = 5,
+ Stdout = 6,
+ Stderr = 7,
+ Data = 8,
+ GetValues = 9,
+ GetValuesResult = 10,
+ UnknownType = 11,
+};
+
+enum Role {
+ Responder = 1,
+ Authorizer = 2,
+ Filter = 3,
+};
+
+enum Flags {
+ KeepConn = 1,
+};
+
+enum ProtocolStatus {
+ RequestComplete = 0,
+ CantMpxConn = 1,
+ Overloaded = 2,
+ UnknownRole = 3,
+};
+
+class Record {
+public:
+ virtual ~Record() = default;
+
+ virtual bool good() const = 0;
+
+ virtual uint8_t type() const = 0;
+ virtual uint16_t request_id() const = 0;
+ virtual uint16_t content_length() const = 0;
+ virtual uint8_t padding_length() const = 0;
+
+ static std::unique_ptr<Record> parse(RoBuffer* buffer);
+
+protected:
+ Record() = default;
+ Record(Record const&) = delete;
+ Record& operator=(Record const&) = delete;
+};
+
+class BeginRequestBody {
+public:
+ virtual ~BeginRequestBody() = default;
+
+ virtual bool good() const = 0;
+
+ virtual uint16_t role() const = 0;
+ virtual uint8_t flags() const = 0;
+
+ static std::unique_ptr<BeginRequestBody> parse(Record const* record,
+ RoBuffer* buffer);
+
+protected:
+ BeginRequestBody() = default;
+ BeginRequestBody(BeginRequestBody const&) = delete;
+ BeginRequestBody& operator=(BeginRequestBody const&) = delete;
+};
+
+class RecordStream {
+public:
+ virtual ~RecordStream() = default;
+
+ // True if all data has been read from stream.
+ virtual bool end_of_stream() const = 0;
+ // True if all data from last added record has been read.
+ virtual bool end_of_record() const = 0;
+ // True if no more data is coming, ie. what rbuf() returned last is all
+ // there will ever be.
+ virtual bool all_available() = 0;
+
+ virtual char const* rbuf(RoBuffer* buf, size_t want, size_t& avail) = 0;
+ virtual void rcommit(RoBuffer* buf, size_t bytes) = 0;
+
+ // Call when next package for stream arrives.
+ virtual void add(Record const* record) = 0;
+
+ // Create stream with record as the first package in stream.
+ static std::unique_ptr<RecordStream> create_stream(Record const* record);
+
+ // Create stream with record as the only package in stream.
+ static std::unique_ptr<RecordStream> create_single(Record const* record);
+
+protected:
+ RecordStream() = default;
+ RecordStream(RecordStream const&) = delete;
+ RecordStream& operator=(RecordStream const&) = delete;
+};
+
+class Pair {
+public:
+ virtual ~Pair() = default;
+
+ // Returns false if bad encoding or an invalid stream was found.
+ // Calling next() will NOT change a false value back to true.
+ virtual bool good() const = 0;
+ virtual std::string const& name() const = 0;
+ virtual std::string const& value() const = 0;
+
+ // Returns nullptr if stream and buf needs more data.
+ static std::unique_ptr<Pair> start(
+ RecordStream* stream, RoBuffer* buf);
+
+ // Returns false if stream and buf needs more data. In that case Pair
+ // is not modified.
+ virtual bool next(RecordStream* stream, RoBuffer* buf) = 0;
+
+protected:
+ Pair() = default;
+ Pair(Pair const&) = delete;
+ Pair& operator=(Pair const&) = delete;
+};
+
+class RecordBuilder {
+public:
+ virtual ~RecordBuilder() = default;
+
+ virtual bool build(Buffer* dst) const = 0;
+ virtual bool build(char* dst, size_t avail) const = 0;
+ virtual bool padding(Buffer* dst) const = 0;
+ virtual bool padding(char* dst, size_t avail) const = 0;
+ virtual size_t size() const = 0;
+
+ static std::unique_ptr<RecordBuilder> create(
+ RecordType type,
+ uint16_t request_id,
+ uint16_t content_length,
+ int16_t padding_length = -1);
+
+ static std::unique_ptr<RecordBuilder> create(
+ RecordType type,
+ uint16_t request_id,
+ std::string body);
+
+ static std::unique_ptr<RecordBuilder> create_unknown_type(
+ uint8_t unknown_type);
+
+ static std::unique_ptr<RecordBuilder> create_begin_request(
+ uint16_t request_id, Role role, uint8_t flags);
+
+ static std::unique_ptr<RecordBuilder> create_end_request(
+ uint16_t request_id, uint32_t app_status, ProtocolStatus protocol_status);
+
+protected:
+ RecordBuilder() = default;
+ RecordBuilder(RecordBuilder const&) = delete;
+ RecordBuilder& operator=(RecordBuilder const&) = delete;
+};
+
+class PairBuilder {
+public:
+ virtual ~PairBuilder() = default;
+
+ virtual void add(std::string name, std::string value) = 0;
+
+ virtual size_t size() const = 0;
+
+ virtual bool build(Buffer* buf) const = 0;
+
+ static std::unique_ptr<PairBuilder> create();
+
+protected:
+ PairBuilder() = default;
+ PairBuilder(PairBuilder const&) = delete;
+ PairBuilder& operator=(PairBuilder const&) = delete;
+};
+
+} // namespace fcgi
+
+#endif // FCGI_PROTOCOL_HH