summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--includes/HttpActionStatic.h16
-rw-r--r--src/HttpActionStatic.cc47
3 files changed, 64 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 3b10442..5a59dc1 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,7 @@ HelperTasks.cc \
\
Http.cc \
HttpServer.cc \
+HttpActionStatic.cc \
SimpleMustache.cc \
BWebSocket.cc \
\
diff --git a/includes/HttpActionStatic.h b/includes/HttpActionStatic.h
new file mode 100644
index 0000000..76be287
--- /dev/null
+++ b/includes/HttpActionStatic.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <HttpServer.h>
+
+namespace Balau {
+
+class HttpActionStatic : public HttpServer::Action {
+ public:
+ // the regex needs a capture on the file name.
+ HttpActionStatic(const String & base, Regex & url) : Action(url), m_base(base) { }
+ private:
+ virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException);
+ String m_base;
+};
+
+};
diff --git a/src/HttpActionStatic.cc b/src/HttpActionStatic.cc
new file mode 100644
index 0000000..d340bfa
--- /dev/null
+++ b/src/HttpActionStatic.cc
@@ -0,0 +1,47 @@
+#include "HttpActionStatic.h"
+#include "Input.h"
+#include "TaskMan.h"
+#include "HelperTasks.h"
+
+bool Balau::HttpActionStatic::Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException) {
+ HttpServer::Response response(server, req, out);
+ String & fname = match.uri[1];
+ String extension;
+
+ ssize_t dot = fname.strrchr('.');
+
+ if (dot > 0)
+ extension = fname.extract(dot + 1);
+
+ bool error = false;
+
+ if (fname.strstr("/../") > 0)
+ error = true;
+
+ IO<Input> file(new Input(m_base + fname));
+
+ if (!error) {
+ try {
+ file->open();
+ }
+ catch (ENoEnt & e) {
+ error = true;
+ }
+ }
+
+ if (error) {
+ response.get()->writeString("Static file not found.");
+ response.SetResponseCode(404);
+ response.SetContentType("text/plain");
+ }
+ else {
+ Events::TaskEvent evt;
+ Task * copy = TaskMan::registerTask(new CopyTask(file, response.get()), &evt);
+ Task::operationYield(&evt);
+ file->close();
+ response.SetContentType(Http::getContentType(extension));
+ }
+ response.Flush();
+ return true;
+}
+