Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make CSGI::Application an object instead of a function pointer. Adjus…

…t everything accordingly
  • Loading branch information...
commit 6183a3e78ea96d2353b90acb7285edda62dce961 1 parent 251d933
@tadzik authored
View
46 app.cpp
@@ -1,37 +1,41 @@
#include "csgi.hpp"
#include <iostream>
-CSGI::Response app(CSGI::Env& env)
-{
- CSGI::Response resp;
+class MyApp : public CSGI::Application {
+public:
+ virtual CSGI::Response operator()(CSGI::Env& env)
+ {
+ CSGI::Response resp;
- CSGI::Env::iterator it;
+ CSGI::Env::iterator it;
- std::cerr << "=================================================="
- << std::endl
- << "CAN HAS REQUEST FOR " << env["REQUEST_URI"]
- << std::endl
- << "=================================================="
- << std::endl;
+ std::cerr << "=================================================="
+ << std::endl
+ << "CAN HAS REQUEST FOR " << env["REQUEST_URI"]
+ << std::endl
+ << "=================================================="
+ << std::endl;
- for (it = env.begin(); it != env.end(); it++) {
- std::cerr << it->first << " => " << it->second << std::endl;
- }
+ for (it = env.begin(); it != env.end(); it++) {
+ std::cerr << it->first << " => " << it->second << std::endl;
+ }
- resp.content = "Hello, world!";
+ resp.content = "Hello, world!";
- std::stringstream len;
- len << resp.content.length();
+ std::stringstream len;
+ len << resp.content.length();
- resp.status = 200;
- resp.headers["Content-Type"] = "text/plain";
- resp.headers["Content-Length"] = len.str().c_str();
+ resp.status = 200;
+ resp.headers["Content-Type"] = "text/plain";
+ resp.headers["Content-Length"] = len.str().c_str();
- return resp;
-}
+ return resp;
+ }
+};
int main()
{
+ CSGI::Application *app = new MyApp;
CSGI::Server srv(app, 8080);
try {
srv.run(false);
View
2  csgi.cpp
@@ -76,7 +76,7 @@ void CSGI::Server::serve()
close(newfd);
continue;
}
- Response resp = app_(env);
+ Response resp = (*app_)(env);
send_response(resp, newfd);
close(newfd);
}
View
10 csgi.hpp
@@ -31,7 +31,11 @@ struct Response {
Body content;
};
-typedef Response(*Application)(Env&);
+class Application {
+public:
+ virtual CSGI::Response operator()(CSGI::Env&) = 0;
+ virtual ~Application() { }
+};
class Exception : public std::exception {
public:
@@ -50,7 +54,7 @@ class InvalidRequest : public std::exception { };
class Server {
public:
- Server(Application app, int port) : app_(app), port_(port)
+ Server(Application * app, int port) : app_(app), port_(port)
{
backlog_ = 10;
}
@@ -60,7 +64,7 @@ class Server {
void serve();
Env parse_request(int fd);
void send_response(Response& resp, int fd);
- Application app_;
+ Application *app_;
struct addrinfo hints_, *res_;
int sockfd_;
int port_;
View
50 dispatcher.cpp
@@ -9,42 +9,46 @@ std::string stripslashes(std::string s)
return s;
}
-CSGI::Response not_found_handler(CSGI::Env& env)
-{
- CSGI::Response ret;
-
- std::string body = "Not found";
- std::stringstream len;
- len << body.length();
-
- ret.status = 404;
- ret.headers["Content-Type"] = "text/plain";
- ret.headers["Content-Length"] = len.str();
- ret.content = body;
-
- return ret;
- (void)env;
-}
+class NotFoundHandler : public CSGI::Application {
+ virtual CSGI::Response operator()(CSGI::Env& env)
+ {
+ CSGI::Response ret;
+
+ std::string body = "Not found";
+ std::stringstream len;
+ len << body.length();
+
+ ret.status = 404;
+ ret.headers["Content-Type"] = "text/plain";
+ ret.headers["Content-Length"] = len.str();
+ ret.content = body;
+
+ return ret;
+ (void)env;
+ }
+};
-Dispatcher::Dispatcher(CSGI::Application default_app)
+Dispatcher::Dispatcher(CSGI::Application * default_app)
{
if (default_app != NULL) {
- default_handler_ = default_app;
+ default_handler_ = default_app;
+ freedefaulthandler = false;
} else {
- default_handler_ = not_found_handler;
+ default_handler_ = new NotFoundHandler();
+ freedefaulthandler = true;
}
}
-void Dispatcher::add_handler(std::string s, CSGI::Application a)
+void Dispatcher::add_handler(std::string s, CSGI::Application * a)
{
handlers_[stripslashes(s)] = a;
}
CSGI::Response Dispatcher::dispatch(CSGI::Env& env)
{
- CSGI::Application y = handlers_[stripslashes(env["REQUEST_URI"])];
+ CSGI::Application *y = handlers_[stripslashes(env["REQUEST_URI"])];
if (y != NULL) {
- return y(env);
+ return (*y)(env);
}
- return default_handler_(env);
+ return (*default_handler_)(env);
}
View
14 dispatcher.hpp
@@ -8,13 +8,19 @@
class Dispatcher {
public:
- Dispatcher(CSGI::Application a);
+ Dispatcher(CSGI::Application *);
// dispatch() is a CSGI application itself. Cool, eh?
CSGI::Response dispatch(CSGI::Env&);
- void add_handler(std::string, CSGI::Application);
+ void add_handler(std::string, CSGI::Application *);
+ ~Dispatcher()
+ {
+ if (freedefaulthandler)
+ delete default_handler_;
+ }
private:
- std::map<std::string, CSGI::Application> handlers_;
- CSGI::Application default_handler_;
+ std::map<std::string, CSGI::Application*> handlers_;
+ CSGI::Application * default_handler_;
+ bool freedefaulthandler;
};
#endif
View
73 dispatcher_test.cpp
@@ -10,42 +10,25 @@ std::string itoa(int i)
return out.str();
}
-CSGI::Response make_response(std::string body)
-{
- CSGI::Response ret;
-
- ret.status = 200;
- ret.headers["Content-Type"] = "text/plain";
- ret.headers["Content-Length"] = itoa(body.length());
- ret.content = body;
-
- return ret;
-}
-
-CSGI::Response hello_handler(CSGI::Env& e)
-{
- return make_response("Hello, world!");
- (void)e;
-}
-
-CSGI::Response aboot_handler(CSGI::Env& e)
-{
- return make_response("Could you tell us again what your argument "
- "is all ABOUT?");
- (void)e;
-}
-
-CSGI::Response placki_handler(CSGI::Env& e)
-{
- return make_response("Lubię placki!");
- (void)e;
-}
-
-CSGI::Response another_handler(CSGI::Env& e)
-{
- return make_response("Another prick in the wall");
- (void)e;
-}
+class SimpleResponder : public CSGI::Application {
+public:
+ SimpleResponder(std::string msg) : msg_(msg) { }
+
+ virtual CSGI::Response operator()(CSGI::Env& e)
+ {
+ CSGI::Response ret;
+
+ ret.status = 200;
+ ret.headers["Content-Type"] = "text/plain";
+ ret.headers["Content-Length"] = itoa(msg_.length());
+ ret.content = msg_;
+
+ return ret;
+ (void)e;
+ }
+private:
+ std::string msg_;
+};
void assert_status(Dispatcher& d, const char * uri, int status)
{
@@ -61,12 +44,18 @@ void assert_found(Dispatcher& d, const char * uri)
int main()
{
- Dispatcher dispatcher(NULL);
-
- dispatcher.add_handler("/hello", hello_handler);
- dispatcher.add_handler("aboot/", aboot_handler);
- dispatcher.add_handler("/placki/", placki_handler);
- dispatcher.add_handler("another", another_handler);
+ Dispatcher dispatcher((CSGI::Application *)NULL);
+
+ SimpleResponder hello("Hello, world!");
+ SimpleResponder aboot("Could you tell us again what your argument "
+ "is all ABOUT?");
+ SimpleResponder placki("Lubię placki!");
+ SimpleResponder another("Another prick in the wall");
+
+ dispatcher.add_handler("/hello", &hello);
+ dispatcher.add_handler("aboot/", &aboot);
+ dispatcher.add_handler("/placki/", &placki);
+ dispatcher.add_handler("another", &another);
assert_found(dispatcher, "/hello");
assert_found(dispatcher, "/hello/");
Please sign in to comment.
Something went wrong with that request. Please try again.