aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--brep/module43
-rw-r--r--brep/module.cxx39
-rw-r--r--services.cxx17
-rw-r--r--web/apache/service46
-rw-r--r--web/module13
5 files changed, 158 insertions, 0 deletions
diff --git a/brep/module b/brep/module
new file mode 100644
index 0000000..6687a31
--- /dev/null
+++ b/brep/module
@@ -0,0 +1,43 @@
+// file : brep/module -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BREP_MODULE
+#define BREP_MODULE
+
+namespace brep
+{
+ // This exception is used to signal that the request is invalid
+ // (4XX codes) rather than that it could not be processed (5XX).
+ // By default 422 is returned, which means the request was
+ // semantically invalid.
+ //
+ struct invalid_request
+ {
+ web::status_code status {422};
+ std::string description;
+
+ //@@ Maybe optional "try again" link?
+ //
+ };
+
+ // Adaptation of the web::module to our needs.
+ //
+ class module: public web::module
+ {
+ public:
+ virtual void
+ handle (request&, response&) = 0;
+
+ // Implementation details.
+ //
+ protected:
+ virtual void
+ handle (request&, response&, log&);
+
+ protected:
+ log* log_;
+ };
+}
+
+#endif // BREP_MODULE
diff --git a/brep/module.cxx b/brep/module.cxx
new file mode 100644
index 0000000..1837ccd
--- /dev/null
+++ b/brep/module.cxx
@@ -0,0 +1,39 @@
+// file : brep/module.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <brep/module>
+
+using namespace std;
+
+namespace brep
+{
+ void module::
+ handle (request& rq, response& rs, log& l)
+ {
+ log_ = &l;
+
+ try
+ {
+ handle (rq, rs);
+ }
+ catch (const invalid_request& e)
+ {
+ // @@ Format as HTML in proper style.
+ //
+ rs.content (e.status, "text/html;charset=utf-8") << e.description;
+ }
+ catch (const exception& e)
+ {
+ // @@ Exception: log e.what () & 505.
+ //
+ rs.status (505);
+ }
+ catch (...)
+ {
+ // @@ Unknown exception: log & 505.
+ //
+ rs.status (505);
+ }
+ }
+}
diff --git a/services.cxx b/services.cxx
new file mode 100644
index 0000000..746aefa
--- /dev/null
+++ b/services.cxx
@@ -0,0 +1,17 @@
+// file : services.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <web/apache/service>
+
+#include <brep/search>
+#include <brep/view>
+
+using namespace brep;
+using web::apache::service;
+
+static const search search_mod;
+service<search> AP_MODULE_DECLARE_DATA search_srv ("search", search_mod);
+
+static const view view_mod;
+service<view> AP_MODULE_DECLARE_DATA view_srv ("view", view_mod);
diff --git a/web/apache/service b/web/apache/service
new file mode 100644
index 0000000..3c7a398
--- /dev/null
+++ b/web/apache/service
@@ -0,0 +1,46 @@
+// file : web/apache/service -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef WEB_APACHE_SERVICE
+#define WEB_APACHE_SERVICE
+
+#include <string>
+
+#include <web/module>
+
+namespace web
+{
+ namespace apache
+ {
+ class service_common
+ {
+ //@@ Implementation that calls handle() below goes here.
+ //
+
+ virtual void
+ handle (request&, response&, log&) = 0;
+ };
+
+ template <typename M>
+ class service: public service_common
+ {
+ public:
+ // Note that the module exemplar is stored by-reference.
+ //
+ service (const std::string& name, const M& exemplar);
+
+ virtual void
+ handle (request& rq, response& rs, log& l)
+ {
+ M m (exemplar_);
+ m.handle (rq, rs, l);
+ }
+
+ private:
+ const M& exemplar_;
+ };
+ }
+}
+
+#endif // WEB_APACHE_SERVICE
diff --git a/web/module b/web/module
index d36bb26..e9787a4 100644
--- a/web/module
+++ b/web/module
@@ -22,6 +22,8 @@ namespace web
// HTTP status code.
//
+ // @@ Define some commonly used constants?
+ //
using status_code = uint16_t;
struct name_value
@@ -92,6 +94,17 @@ namespace web
write (const char* msg);
};
+ // 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: