summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Buffer.cc2
-rw-r--r--lib/CopyJob.cc35
-rw-r--r--lib/Exceptions.cc20
-rw-r--r--lib/Handle.cc4
-rw-r--r--lib/HttpServ.cc43
-rw-r--r--lib/ReadJob.cc31
-rw-r--r--lib/Task.cc19
7 files changed, 112 insertions, 42 deletions
diff --git a/lib/Buffer.cc b/lib/Buffer.cc
index 164c961..57b1bf8 100644
--- a/lib/Buffer.cc
+++ b/lib/Buffer.cc
@@ -32,7 +32,7 @@ ssize_t Buffer::read(void *buf, size_t count) {
ptr += count;
if (ptr >= realloc_threshold) {
- int numblocks = (ptr / realloc_threshold) - (bufsiz / realloc_threshold);
+ int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
memmove(buffer, buffer + numblocks * realloc_threshold, numblocks * realloc_threshold);
buffer = (char *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
ptr -= numblocks * realloc_threshold;
diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc
index 7dccbc5..73864bb 100644
--- a/lib/CopyJob.cc
+++ b/lib/CopyJob.cc
@@ -1,15 +1,38 @@
#include "CopyJob.h"
+#include "General.h"
-CopyJob::CopyJob(Handle & as, Handle & ad) : s(as), d(ad) { }
+CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz) : s(as), d(ad), siz(asiz), cursiz(0), current(0) { }
CopyJob::~CopyJob() { }
int CopyJob::Do() {
- int r;
- char buffer[4096];
+ int r, tr;
- while (!s.IsClosed()) {
- r = s.read(buffer, 4096);
- d.write(buffer, r);
+ cerr << "CopyJob running...\n";
+
+ while (!s->IsClosed() || (siz != cursiz)) {
+ if (!current) {
+ tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ;
+ try {
+ r = s->read(buffer, MIN(COPY_BUFSIZ, tr));
+ }
+ catch (IOAgain) {
+ return TASK_WAITING_HANDLE;
+ }
+ current = 0;
+ }
+ try {
+ d->write(buffer, r);
+ }
+ catch (IOAgain) {
+ current = 1;
+ return TASK_WAITING_HANDLE;
+ }
+ cursiz += r;
}
}
+
+String CopyJob::GetName() {
+ return (String("CopyJob from ") + s->GetName() + " to " + d->GetName());
+}
+
diff --git a/lib/Exceptions.cc b/lib/Exceptions.cc
index eed138a..a4fca0f 100644
--- a/lib/Exceptions.cc
+++ b/lib/Exceptions.cc
@@ -32,14 +32,12 @@ IOException::IOException(String fn, op_t op, ssize_t s) {
msg = strdup(t);
}
-IOInternal::IOInternal(String fn, op_t op) {
- sprintf(t, _("Internal error: has occured while %s from %s: open for %s."), op == IO_WRITE ? _("writing") : _("reading"),
- fn.to_charp(), op == IO_WRITE ? _("reading") : _("writing"));
- msg = strdup(t);
-}
-
IOGeneral::IOGeneral(String fn) : GeneralException(fn) { }
+IOGeneral::IOGeneral() { }
+
+IOAgain::IOAgain() : IOGeneral(_("No more bytes for reading or writing.")) { }
+
char * xstrdup(const char * s) throw (MemoryException) {
char * r;
@@ -62,6 +60,16 @@ void * xmalloc(ssize_t s) throw (MemoryException) {
return r;
}
+void * xrealloc(void * ptr, size_t s) throw (MemoryException) {
+ void * r;
+
+ if (!(r = ::realloc(ptr, s))) {
+ throw MemoryException(s);
+ }
+
+ return r;
+}
+
#ifdef OVER_FREE
#undef free
#endif
diff --git a/lib/Handle.cc b/lib/Handle.cc
index 0f1791e..8ef2408 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -40,7 +40,7 @@ ssize_t Handle::write(const void *buf, size_t count) throw (IOException) {
done = false;
full = true;
if (nonblock) {
- return 0;
+ throw IOAgain();
} else {
sleep(1);
}
@@ -66,7 +66,7 @@ ssize_t Handle::read(void *buf, size_t count) throw (IOException) {
if ((!errno) || (errno = EAGAIN)) {
// Avant de déclarer une erreur, on vérifie si ce n'est pas un
// problème lié au fait qu'il n'y a plus d'octets.
- return 0;
+ throw IOAgain();
} else {
throw IOException(GetName(), IO_READ, count);
}
diff --git a/lib/HttpServ.cc b/lib/HttpServ.cc
index 69dff1e..9ec6ba3 100644
--- a/lib/HttpServ.cc
+++ b/lib/HttpServ.cc
@@ -22,11 +22,12 @@ void HttpServ::MainLoop(Action * p) {
void HttpServ::ProcessRequest(Action * p, Socket s) {
String file, domain, t;
Buffer b;
- ReadJob c(s, b);
+ Task * c = new ReadJob(&s, &b);
Action * f;
int len;
- c.Do();
+ c->Run();
+ delete c;
bad = false;
@@ -34,7 +35,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
cerr << "Got a request\n----\n";
- bool post = ParseUri(file, domain, b);
+ bool post = ParseUri(file, domain, &b);
len = -1;
do {
@@ -45,7 +46,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
len = t.extract(16).to_int();
}
} while (t.strlen());
-
+
if (post) {
// On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST.
// Cela est une erreur.
@@ -55,7 +56,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
} else {
cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n";
// Les variables seront initialisées ici.
- ParseVars(s, len);
+ ParseVars(&s, len);
}
} else {
Vars = new Variables(0);
@@ -78,19 +79,19 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
}
if (bad) {
- ShowError(s);
+ ShowError(&s);
} else {
if (((domain == "") || (domain == "/")) && (file == "")) {
// Si le navigateur a demandé l'URL '/', alors on renvoie une notification
// de redirection.
- SendRedirect(s);
+ SendRedirect(&s);
} else if (domain == "/bin") {
// Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer.
if ((f = p->Look4URL(file))) {
- SendHeads(s, "text/html");
+ SendHeads(&s, "text/html");
f->Do(Vars, &s);
} else {
- ShowError(s);
+ ShowError(&s);
}
} else {
// Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas.
@@ -98,12 +99,12 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
// d'input renvoie une erreur.
try {
Input i(String("datas/") + file);
- SendHeads(s, GetMime(file));
+ SendHeads(&s, GetMime(file));
s.ReadFile(i);
cerr << "File found, dumped.\n";
}
catch (IOGeneral e) {
- ShowError(s);
+ ShowError(&s);
cerr << "File not found, error showed.\n";
}
}
@@ -114,7 +115,7 @@ void HttpServ::ProcessRequest(Action * p, Socket s) {
cerr << "----\n";
}
-void HttpServ::ParseVars(Handle & s, int len) {
+void HttpServ::ParseVars(Handle * s, int len) {
String t, v;
char conv[3], l;
int hconv, nbvars;
@@ -122,7 +123,7 @@ void HttpServ::ParseVars(Handle & s, int len) {
t = "";
for (int i = 0; i < len; i++) {
- s.read(&l, 1);
+ s->read(&l, 1);
t += l;
}
cerr << "Post variables line: '" <<t << "'\n";
@@ -174,13 +175,13 @@ void HttpServ::ParseVars(Handle & s, int len) {
* c'est à dire la méthode demandée par le client.
*/
-bool HttpServ::ParseUri(String & file, String & domain, Handle & s) {
+bool HttpServ::ParseUri(String & file, String & domain, Handle * s) {
String t, Uri;
bool post = false;
char * p = NULL;
ssize_t sppos;
- s >> t;
+ *s >> t;
cerr << t << endl;
bad = false;
@@ -233,8 +234,8 @@ bool HttpServ::ParseUri(String & file, String & domain, Handle & s) {
/*
* Ceci sert à rediriger le navigateur vers l'url de démarrage.
*/
-void HttpServ::SendRedirect(Handle & s) {
- s << "HTTP/1.1 301 Moved Permanently" << endhl <<
+void HttpServ::SendRedirect(Handle * s) {
+ *s << "HTTP/1.1 301 Moved Permanently" << endhl <<
"Server: " << name << endhl <<
"Location: http://127.0.0.1:" << localport << "/bin/start" << endhl <<
"Cache-Control: no-cache" << endhl <<
@@ -250,8 +251,8 @@ void HttpServ::SendRedirect(Handle & s) {
* Nous envoyons les entetes de réponse HTTP.
*/
-void HttpServ::SendHeads(Handle & s, const String & mime) {
- s << "HTTP/1.1 200 OK" << endhl <<
+void HttpServ::SendHeads(Handle * s, const String & mime) {
+ *s << "HTTP/1.1 200 OK" << endhl <<
"Server: " << name << endhl <<
"Cache-Control: no-cache" << endhl <<
"Connection-Type: closed" << endhl <<
@@ -262,8 +263,8 @@ void HttpServ::SendHeads(Handle & s, const String & mime) {
* Affichage d'une erreur 404.
*/
-void HttpServ::ShowError(Handle & s) {
- s << "HTTP/1.1 404 Not Found" << endhl <<
+void HttpServ::ShowError(Handle * s) {
+ *s << "HTTP/1.1 404 Not Found" << endhl <<
"Server: " << name << endhl <<
"Cache-Control: no-cache" << endhl <<
"Connection-Type: closed" << endhl <<
diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc
index bd63377..d5b3212 100644
--- a/lib/ReadJob.cc
+++ b/lib/ReadJob.cc
@@ -1,6 +1,7 @@
#include "ReadJob.h"
+#include "HttpServ.h"
-ReadJob::ReadJob(Handle & as, Handle & ad) : s(as), d(ad) { }
+ReadJob::ReadJob(Handle * as, Handle * ad, String regex, int flags) : s(as), d(ad), current(0) { }
ReadJob::~ReadJob() { }
@@ -8,9 +9,31 @@ int ReadJob::Do() {
int r;
String buff;
- while (!s.IsClosed()) {
- s >> buff;
- d << buff;
+ cerr << "ReadJob running...\n";
+
+ while (!s->IsClosed()) {
+ if (!current) {
+ try {
+ *s >> buff;
+ }
+ catch (IOAgain) {
+ return TASK_WAITING_HANDLE;
+ }
+ current = 0;
+ }
+ try {
+ *d << buff << endnl;
+ }
+ catch (IOAgain) {
+ current = 1;
+ return TASK_WAITING_HANDLE;
+ }
if (buff == "") return TASK_DONE;
}
+
+ return TASK_DONE;
+}
+
+String ReadJob::GetName() {
+ return (String("ReadJob from ") + s->GetName() + " to " + d->GetName());
}
diff --git a/lib/Task.cc b/lib/Task.cc
index 79c39e1..27d2a24 100644
--- a/lib/Task.cc
+++ b/lib/Task.cc
@@ -1,6 +1,8 @@
+#include <iostream.h>
#include "Task.h"
+#include "String.h"
-Task::Task() {}
+Task::Task() : state(TASK_ON_HOLD) {}
Task::~Task() {}
int Task::Do() {
@@ -8,9 +10,22 @@ int Task::Do() {
}
int Task::Run() {
- return (state = Do());
+ cerr << "Running task '" << GetName() << "'...\n";
+ try {
+ while ((state = Do()) != TASK_DONE);
+ }
+ catch (GeneralException e) {
+ cerr << "Task " << GetName() << " caused an unexpected exception: '" << e.GetMsg() << "', closing it.\n";
+ return TASK_DONE;
+ }
+
+ return state;
}
int Task::GetState() {
return state;
}
+
+String Task::GetName() {
+ return "Unknow Task";
+}