speedy: first let say usefull implementation, GET, POST, PUT, DELETE methods are implemented

This commit is contained in:
buda 2015-09-24 01:00:02 +02:00
parent 62e67c2e1f
commit 474492ddad
6 changed files with 138 additions and 24 deletions

3
speedy/.gitignore vendored
View File

@ -1 +1,4 @@
*.out
*.dSYM/
*.gdb
.gdb_history

View File

@ -1,7 +1,8 @@
CXX=clang++
CFLAGS=-std=c++11 -Wall
LDFLAGS=-luv -lhttp_parser -lr3
INC=-I../
# debug only
INC=-I../ -g -O0 -fno-inline-functions
SOURCES=$(wildcard *.cpp)
EXECUTABLE=test.out
# OBJECTS=$(SOURCES:.cpp=.o)

View File

@ -10,15 +10,22 @@
namespace speedy
{
typedef unsigned int uint;
class Speedy
{
private:
http::HttpServer server;
http::Ipv4 ip;
node *n;
std::vector<http::request_cb_t> callbacks;
void store_index(int method, const std::string &path);
public:
Speedy(uv::UvLoop& loop, const http::Ipv4& ip);
void get(const std::string &path, http::request_cb_t callback);
void get(const std::string &path, http::request_cb_t callback);
void post(const std::string &path, http::request_cb_t callback);
void put(const std::string &path, http::request_cb_t callback);
void del(const std::string &path, http::request_cb_t callback);
void listen();
};

View File

@ -2,23 +2,64 @@
#define MEMGRAPH_SPEEDY_INL
#include "speedy.hpp"
#include <http_parser.h>
namespace speedy
{
int r3_request_method(http::Method method)
{
switch (method) {
case http::Method::GET: return METHOD_GET;
case http::Method::POST: return METHOD_POST;
case http::Method::PUT: return METHOD_PUT;
case http::Method::DELETE: return METHOD_DELETE;
case http::Method::HEAD: return METHOD_HEAD;
}
}
// TODO: better implementation
Speedy::Speedy(uv::UvLoop& loop, const http::Ipv4& ip) : server(loop), ip(ip)
{
n = r3_tree_create(100);
}
void Speedy::store_index(int method, const std::string &path)
{
void *ptr = malloc(sizeof(uint));
*((uint *)ptr) = callbacks.size() - 1;
r3_tree_insert_routel(n, method, path.c_str(), path.size(), ptr);
}
void Speedy::get(const std::string &path, http::request_cb_t callback)
{
// this->callbacks.push_back(callback);
// r3_tree_insert_pathl(n, path.c_str(), path.size(), &callbacks[callbacks.size() - 1]);
r3_tree_insert_pathl(n, path.c_str(), path.size(), &callback);
callbacks.push_back(callback);
store_index(METHOD_GET, path);
// TODO: something like this
// this solution doesn't work, currenlty I don't know why
// r3_tree_insert_pathl(n, path.c_str(), path.size(), &callbacks.back());
}
void Speedy::post(const std::string &path, http::request_cb_t callback)
{
callbacks.push_back(callback);
store_index(METHOD_POST, path);
}
void Speedy::put(const std::string &path, http::request_cb_t callback)
{
callbacks.push_back(callback);
store_index(METHOD_PUT, path);
}
void Speedy::del(const std::string &path, http::request_cb_t callback)
{
callbacks.push_back(callback);
store_index(METHOD_DELETE, path);
}
void Speedy::listen()
{
char *errstr = NULL;
@ -29,10 +70,18 @@ void Speedy::listen()
server.listen(ip, [this](http::Request& req, http::Response& res) {
auto url = req.url;
node *n = r3_tree_matchl(this->n, url.c_str(), url.size(), NULL);
if (n) {
auto callback = *reinterpret_cast<http::request_cb_t*>(n->data);
callback(req, res);
auto c_url = url.c_str();
match_entry *entry = match_entry_create(c_url);
entry->request_method = r3_request_method(req.method);
route *r = r3_tree_match_route(this->n, entry);
match_entry_free(entry);
if (r) {
int index = *((int *)r->data);
auto callback = this->callbacks[index];
callback(req, res);
// TODO: and something like this
// auto callback = *reinterpret_cast<http::request_cb_t*>(n->data);
// callback(req, res);
} else {
res.send("Not found");
}

View File

@ -2,33 +2,65 @@
#include "speedy.hpp"
// TODO: still doesn't work
// debug the whole thing
void test(http::request_cb_t callback, speedy::Speedy &app) {
app.get("/test", callback);
const char *test_url_1 = "/test1";
const char *test_url_2 = "/test2";
const char *test_url_3 = "/test3";
const char *test_response = "test";
void test_get(const http::request_cb_t &&callback, speedy::Speedy &app) {
app.get(test_url_3, callback);
}
auto foo = [](http::Request& req, http::Response& res) {
res.send("foo");
void test_post(const http::request_cb_t &&callback, speedy::Speedy &app) {
app.post(test_url_3, callback);
}
void test_put(const http::request_cb_t &&callback, speedy::Speedy &app) {
app.put(test_url_3, callback);
}
void test_delete(const http::request_cb_t &&callback, speedy::Speedy &app) {
app.del(test_url_3, callback);
}
auto test_callback = [](http::Request& req, http::Response& res) {
res.send(test_response);
};
int main(void)
{
// speedy init
uv::UvLoop loop;
http::Ipv4 ip("0.0.0.0", 3400);
speedy::Speedy app(loop, ip);
app.get("/foo", foo);
app.get("/bar", [](http::Request& req, http::Response& res) {
res.send("bar");
// GET methods
app.get(test_url_1, test_callback);
app.get(test_url_2, [](http::Request& req, http::Response& res) {
res.send(test_response);
});
auto cb = [](http::Request& req, http::Response& res) {
res.send("test");
};
test(http::request_cb_t(cb), app);
test_get(test_callback, app);
// POST examples
app.post(test_url_1, test_callback);
app.post(test_url_2, [](http::Request& req, http::Response& res) {
res.send(test_response);
});
test_post(test_callback, app);
// PUT examples
app.put(test_url_1, test_callback);
app.put(test_url_2, [](http::Request& req, http::Response& res) {
res.send(test_response);
});
test_put(test_callback, app);
// DELETE examples
app.del(test_url_1, test_callback);
app.del(test_url_2, [](http::Request& req, http::Response& res) {
res.send(test_response);
});
test_delete(test_callback, app);
// app run
app.listen();
loop.run(uv::UvLoop::Mode::Default);
return 0;

22
speedy/test.py Normal file
View File

@ -0,0 +1,22 @@
import requests
endpoint = 'http://localhost:3400/test%s'
methods = [('GET', requests.get), ('POST', requests.post), ('PUT', requests.put), ('DELETE', requests.delete)]
print ''
isAllFine = True
for index in range(1, 4):
for name, method in methods:
url = endpoint % index
r = method(url)
if r.status_code == 200 and r.text == 'test':
print name, url, 'PASS'
else:
print name, url, 'FAIL'
isAllFine = False
print ''
if isAllFine:
print 'Great. All tests have passed :)'
else:
print 'Fuckup. Something went wrong!'
print ''