aboutsummaryrefslogtreecommitdiff
path: root/web/module
diff options
context:
space:
mode:
Diffstat (limited to 'web/module')
-rw-r--r--web/module267
1 files changed, 0 insertions, 267 deletions
diff --git a/web/module b/web/module
deleted file mode 100644
index 1e588a4..0000000
--- a/web/module
+++ /dev/null
@@ -1,267 +0,0 @@
-// file : web/module -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef WEB_MODULE
-#define WEB_MODULE
-
-#include <map>
-#include <string>
-#include <vector>
-#include <iosfwd>
-#include <chrono>
-#include <cstdint> // uint16_t
-#include <cstddef> // size_t
-#include <utility> // move()
-#include <stdexcept> // runtime_error
-
-#include <butl/path>
-#include <butl/optional>
-
-namespace web
-{
- using butl::optional;
-
- // HTTP status code.
- //
- // @@ Define some commonly used constants?
- //
- using status_code = std::uint16_t;
-
- // This exception is used to signal that the request is invalid
- // (4XX codes) rather than that it could not be processed (5XX).
- // By default 400 is returned, which means the request is malformed.
- //
- // If caught by the web server implementation, it will try to return
- // the specified status and content to the client, if possible.
- // It is, however, may not be possible if some unbuffered content has
- // already been written. The behavior in this case is implementation-
- // specific and may result in no indication of an error being sent to
- // the client.
- //
- struct invalid_request
- {
- status_code status;
- std::string content;
- std::string type;
-
- //@@ Maybe optional "try again" link?
- //
- invalid_request (status_code s = 400,
- std::string c = "",
- std::string t = "text/plain;charset=utf-8")
- : status (s), content (std::move (c)), type (std::move (t)) {}
- };
-
- // 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
- {
- sequence_error (std::string d): std::runtime_error (std::move (d)) {}
- };
-
- // Map of module configuration option names to the boolean flag indicating
- // whether the value is expected for the option.
- //
- using option_descriptions = std::map<std::string, bool>;
-
- struct name_value
- {
- // These should eventually become string_view's.
- //
- std::string name;
- optional<std::string> value;
-
- name_value () {}
- name_value (std::string n, optional<std::string> v)
- : name (std::move (n)), value (std::move (v)) {}
- };
-
- using name_values = std::vector<name_value>;
- using butl::path;
-
- class request
- {
- public:
- using path_type = web::path;
-
- virtual
- ~request () = default;
-
- // Corresponds to abs_path portion of HTTP URL as described in
- // "3.2.2 HTTP URL" of http://tools.ietf.org/html/rfc2616.
- // Returns '/' if no abs_path is present in URL.
- //
- virtual const path_type&
- path () = 0;
-
- //@@ 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()?
- //
- // Throw invalid_request if decoding of any name or value fails.
- //
- virtual const name_values&
- parameters () = 0;
-
- // Throw invalid_request if cookies are malformed.
- //
- virtual const name_values&
- cookies () = 0;
-
- // Get the stream to read the request content from. If the limit argument
- // is zero, then the content limit is left unchanged (unlimited initially).
- // Otherwise the requested limit is set, and the invalid_request exception
- // with the code 413 (payload too large) will be thrown when the specified
- // limit is reached while reading from the stream. If the buffer argument
- // is zero, then the buffer size is left unchanged (zero initially). If it
- // is impossible to increase the buffer size (because, for example, some
- // content is already read unbuffered), then the sequence_error is thrown.
- //
- // Note that unread input content is discarded when any unbuffered content
- // is written, and any attempt to read it will result in the
- // sequence_error exception being thrown.
- //
- virtual std::istream&
- content (size_t limit = 0, size_t buffer = 0) = 0;
- };
-
- class response
- {
- public:
- virtual
- ~response () = default;
-
- // 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 code = 200,
- const std::string& type = "application/xhtml+xml;charset=utf-8",
- bool buffer = true) = 0;
-
- // Set status code without writing any content. On status change,
- // discard buffered content or throw sequence_error if content was
- // not buffered.
- //
- virtual void
- status (status_code) = 0;
-
- // Throw sequence_error if some unbuffered content has already
- // been written.
- //
- virtual void
- cookie (const char* name,
- const char* value,
- const std::chrono::seconds* max_age = nullptr,
- const char* path = nullptr,
- const char* domain = nullptr,
- bool secure = false,
- bool buffer = true) = 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
- ~log () = default;
-
- virtual void
- write (const char* msg) = 0;
- };
-
- // The web server creates a new module instance for each request
- // by copy-initializing it with the module exemplar. This way we
- // achieve two things: we can freely use module data members
- // without worrying about multi-threading issues and we
- // automatically get started with the initial state for each
- // request. If you really need to share some rw-data between
- // all the modules, use static data members with appropriate
- // locking. See the <service> header in one of the web server
- // directories (e.g., apache/) if you need to see the code that
- // does this.
- //
- class module
- {
- public:
- virtual
- ~module () = default;
-
- // Description of configuration options supported by this module. Note:
- // should be callable during static initialization.
- //
- virtual option_descriptions
- options () = 0;
-
- // During startup the web server calls this function on the module
- // exemplar to log the module version information. It is up to the web
- // server whether to call this function once per module implementation
- // type. Therefore, it is expected that this function will log the same
- // information for all the module exemplars.
- //
- virtual void
- version (log&) = 0;
-
- // During startup the web server calls this function on the module
- // exemplar passing a list of configuration options. The place these
- // configuration options come from is implementation-specific (normally
- // a configuration file). The web server guarantees that only options
- // listed in the map returned by the options() function above can be
- // present. Any exception thrown by this function terminates the web
- // server.
- //
- virtual void
- init (const name_values&, log&) = 0;
-
- // Return false if decline to handle the request. If handling have been
- // declined after any unbuffered content has been written, then the
- // implementation shall terminate the response in a suitable but
- // unspecified manner.
- //
- // Throw retry if need to retry handling the request. The retry will
- // happen on the same instance of the module and the implementation is
- // expected to "rewind" the request and response objects to their initial
- // state. This is only guaranteed to be possible if the relevant functions
- // in the request and response objects were called in buffered mode (the
- // buffer argument was true).
- //
- // Any exception other than retry and invalid_request described above that
- // leaves this function is treated by the web server implementation as an
- // internal server error (500). Similar to invalid_request, it will try to
- // return the status and description (obtained by calling what() on
- // std::exception) to the client, if possible. The description is assume
- // to be encoded in UTF-8. The implementation may provide a configuration
- // option to omit the description from the response, for security/privacy
- // reasons.
- //
- struct retry {};
-
- virtual bool
- handle (request&, response&, log&) = 0;
- };
-}
-
-#endif // WEB_MODULE