diff options
-rw-r--r-- | include/Domain.h | 21 | ||||
-rw-r--r-- | include/HttpServ.h | 45 | ||||
-rw-r--r-- | lib/Domain.cc | 50 | ||||
-rw-r--r-- | lib/HttpServ.cc | 33 |
4 files changed, 120 insertions, 29 deletions
diff --git a/include/Domain.h b/include/Domain.h new file mode 100644 index 0000000..ef103c2 --- /dev/null +++ b/include/Domain.h @@ -0,0 +1,21 @@ +#ifndef __DOMAIN_H__ +#define __DOMAIN_H__ + +#include <BRegex.h> +#include <HttpServ.h> + +class Domain : public Base { + public: + Domain(const Regex &); + virtual ~Domain(); + static Domain * find_domain(const String & url); + void OnTop(); + virtual void Do(const HttpRequest &) = 0; + private: + Domain * find_domain_r(const String & url); + static Domain * head; + Domain * next, * prev; + Regex pattern; +}; + +#endif diff --git a/include/HttpServ.h b/include/HttpServ.h index db454e0..aec3aad 100644 --- a/include/HttpServ.h +++ b/include/HttpServ.h @@ -9,23 +9,6 @@ #include <Handle.h> #include <Exceptions.h> -class Action; -class HttpServ : public Task { - public: - HttpServ(Action *, int = 1500, const String & = String("GruiK Server v0.2")) throw (GeneralException); - virtual ~HttpServ(); - virtual String GetName(); - - protected: - virtual int Do() throw (GeneralException); - - private: - Socket Listener; - Action * p; - String name; - int localport; -}; - class HttpResponse : public Base { public: typedef enum { @@ -51,10 +34,36 @@ class HttpResponse : public Base { Buffer contents; bool cache; - public: + private: String code_to_string(); }; +class HttpRequest : public Base { + public: + Variables * vars, * headers; + String url; +}; + +class Action; +class HttpServ : public Task { + public: + HttpServ(Action *, int = 1500, const String & = String("GruiK Server v0.2")) throw (GeneralException); + virtual ~HttpServ(); + virtual String GetName(); + void SetRoot(const String &); + + protected: + virtual int Do() throw (GeneralException); + + private: + Socket Listener; + Action * p; + String name; + int localport; + String root; + HttpResponse response; +}; + extern String endhl, endnl; #include <Action.h> diff --git a/lib/Domain.cc b/lib/Domain.cc new file mode 100644 index 0000000..8b06bdd --- /dev/null +++ b/lib/Domain.cc @@ -0,0 +1,50 @@ +#include "Domain.h" + +Domain * Domain::head = 0; + +Domain::Domain(const Regex & _pattern) : pattern(_pattern) { + prev = 0; + next = head; + head = this; + next->prev = this; +} + +Domain::~Domain() { + if (head == this) + head = next; + if (next) + next->prev = prev; + if (prev) + prev->next = next; +} + +void Domain::OnTop() { + if (next) + next->prev = prev; + if (prev) + prev->next = next; + + prev = 0; + next = head; + head = this; + next->prev = this; +} + +Domain * Domain::find_domain(const String & url) { + Domain * r = 0; + + if (head) + r = head->find_domain_r(url); + + return r; +} + +Domain * Domain::find_domain_r(const String & url) { + if (pattern.Match(url)) + return this; + + if (next) + return next->find_domain_r(url); + + return 0; +} diff --git a/lib/HttpServ.cc b/lib/HttpServ.cc index 5c9a8aa..69d4b2f 100644 --- a/lib/HttpServ.cc +++ b/lib/HttpServ.cc @@ -9,13 +9,14 @@ #include "CopyJob.h" #include "Task.h" #include "Base64.h" +#include "Domain.h" #include "gettext.h" String endhl = "\r\n", endnl = "\n"; class ProcessRequest : public Task { public: - ProcessRequest(Action *, const Socket &, const String &, int); + ProcessRequest(Action * action, const Socket & out, const String & server_name, int server_port, const String & root = "/bin/start"); virtual ~ProcessRequest() {} virtual String GetName(); protected: @@ -28,20 +29,21 @@ class ProcessRequest : public Task { void SendHeads(Handle *, const String &, const String & = "", time_t = -1); void SendRedirect(Handle *); - String file, domain, t; + String file, domain, t, Uri; Buffer b; Task * c, * a; Action * f; int len, localport; Action * p; Socket s; + Domain * d; - String name, host, gvars, login, password; + String name, host, gvars, login, password, root; Variables * Vars, * Heads; bool bad, hasvars, post; }; -ProcessRequest::ProcessRequest(Action * ap, const Socket & as, const String & aname, int aport) : localport(aport), p(ap), s(as), name(aname) { +ProcessRequest::ProcessRequest(Action * ap, const Socket & as, const String & aname, int aport, const String & aroot) : localport(aport), p(ap), s(as), name(aname), root(aroot) { SetBurst(); } @@ -151,6 +153,7 @@ int ProcessRequest::Do() throw(GeneralException) { if (domain == "/image") bad = false; if (domain == "/bin") bad = false; if (domain == "/") bad = false; + if ((d = Domain::find_domain(Uri))) bad = false; if (bad) { std::cerr << _("Error: bad domain.\n"); } @@ -177,7 +180,7 @@ int ProcessRequest::Do() throw(GeneralException) { } else { ShowError(&b); } - } else { + } else if (domain == "/image") { // Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire data. // On utilise try au cas où le fichier n'existe pas et donc que le constructeur // d'input renvoie une erreur. @@ -192,7 +195,11 @@ int ProcessRequest::Do() throw(GeneralException) { ShowError(&b); std::cerr << _("File not found, error shown.\n"); } - } + } else if (d) { +// d->Do(&response); + } else { + ShowError(&b); + } } if (a) a->Stop(); @@ -284,7 +291,7 @@ void ProcessRequest::ParseVars(Handle * s, int len) { */ bool ProcessRequest::ParseUri(String & file, String & domain, String & gvars, Handle * s) { - String t, Uri; + String t; bool post = false; const char * p = 0; ssize_t sppos; @@ -368,11 +375,11 @@ bool ProcessRequest::ParseUri(String & file, String & domain, String & gvars, Ha void ProcessRequest::SendRedirect(Handle * s) { *s << "HTTP/1.1 301 Moved Permanently" << endhl << "Server: " << name << endhl << - "Location: http://" << host << "/bin/start" << endhl << + "Location: http://" << host << root << endhl << "Cache-Control: no-cache" << endhl << "Connection: closed" << endhl << "Content-Type: text/html" << endhl << endhl << - p->GetSkinner()->Redirect("http://" + host + "/bin/start"); + p->GetSkinner()->Redirect("http://" + host + root); } /* @@ -434,7 +441,7 @@ String ProcessRequest::GetMime(const String & f) { return "text/plain"; } -HttpServ::HttpServ(Action * ap, int port, const String & nname) throw (GeneralException) { +HttpServ::HttpServ(Action * ap, int port, const String & nname) throw (GeneralException) : root("/bin/start") { bool r = true; p = ap; @@ -464,11 +471,15 @@ HttpServ::~HttpServ(void) { Listener.close(); } +void HttpServ::SetRoot(const String & _root) { + root = _root; +} + int HttpServ::Do() throw (GeneralException) { try { Socket s = Listener.Accept(); s.SetNonBlock(); - new ProcessRequest(p, s, name, localport); + new ProcessRequest(p, s, name, localport, root); } catch (GeneralException) { } |