diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-09 13:13:35 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-09 13:13:35 +0200 |
commit | 08447f7f7463dc3838b239790f647129e7f01629 (patch) | |
tree | 0d16c7bb6c22cacb2f20b7e837dc5df62d442e35 /web/module | |
parent | cf1ebc11bc8377e176caaa053f5f735ac6dd7dce (diff) |
Initial take on web module interface
Diffstat (limited to 'web/module')
-rw-r--r-- | web/module | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/web/module b/web/module new file mode 100644 index 0000000..9b7f426 --- /dev/null +++ b/web/module @@ -0,0 +1,103 @@ +// file : web/module -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef WEB_MODULE +#define WEB_MODULE + +#include <string> +#include <vector> +#include <iosfwd> +#include <cstdint> // uint16_t +#include <utility> // move() +#include <stdexcept> // runtime_error + +namespace web +{ + // Exception indicating HTTP request/response sequencing error. + // For example, trying to change the status code after some + // content has already been written. + // + struct sequence_error: std::runtime_error {}; + + // HTTP status code. + // + using status_code = uint16_t; + + struct name_value + { + // These should eventually become string_view's. + // + std::string name; + std::string value; + + name_value () {} + name_value (std::string n, std::string v) + : name (std::move (n)), value (std::move (v)) {} + }; + + using name_values = std::vector<name_value>; + + class request + { + public: + //@@ Why not pass parameters directly? Lazy parsing? + //@@ Why not have something like operator[] for lookup? Probably + // in name_values. + //@@ Maybe parameter_list() and parameter_map()? + // + virtual const name_values& + parameters () = 0; + }; + + class response + { + public: + // Set status code, content type, and get the stream to write + // the content to. If the buffer argument is true (default), + // then buffer the entire content before sending it as a + // response. This allows us to change the status code in + // case of an error. + // + // Specifically, if there is already content in the buffer + // and the status code is changed, then the old content is + // discarded. If the content was not buffered and the status + // is changed, then the sequence_error exception is thrown. + // If this exception leaves module::handle(), then the + // implementation shall terminate the response in a suitable + // but unspecified manner. In particular, there is no guarantee + // that the user will be notified of an error or observe the + // new status. + // + virtual std::ostream& + content (status_code, const std::string& type, bool buffer = true) = 0; + + // Set status code without writing any content. + // + virtual void + status (status_code) = 0; + }; + + // A web server logging backend. The module can use it to log + // diagnostics that is meant for the web server operator rather + // than the user. + // + // The module can cast this basic interface to the web server's + // specific implementation that may provide a richer interface. + // + class log + { + public: + virtual void + write (const char* msg); + }; + + class module + { + public: + virtual status_code + handle (request&, response&, log&) = 0; + }; +} + +#endif // WEB_MODULE |