From 88ee692f783caa404199f3569cf929b4801e6672 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Thu, 4 May 2017 20:23:41 -0300 Subject: [PATCH 01/12] Create play controller Fetches song from filesystem and sends it to client --- src/api/controllers/Controller.cpp | 14 +++++++ src/api/controllers/Controller.h | 6 +++ src/api/controllers/PlayController.cpp | 37 +++++++++++++++++ src/api/controllers/PlayController.h | 52 ++++++++++++++++++++++++ src/api/controllers/TracksController.cpp | 7 +--- src/api/networking/Request.cpp | 19 ++++++++- src/api/networking/Request.h | 28 ++++++++++++- src/api/networking/Server.cpp | 3 ++ tests/integration/MongoDaoTest.h | 18 ++++---- 9 files changed, 167 insertions(+), 17 deletions(-) create mode 100644 src/api/controllers/PlayController.cpp create mode 100644 src/api/controllers/PlayController.h diff --git a/src/api/controllers/Controller.cpp b/src/api/controllers/Controller.cpp index 7546475..e27fb82 100644 --- a/src/api/controllers/Controller.cpp +++ b/src/api/controllers/Controller.cpp @@ -48,3 +48,17 @@ bool Controller::handles(std::string method, std::string url) { std::string key = method + ":" + url; return routes.find(key) != routes.end(); } + +void Controller::setElementId(Request &request) { + std::string elementIdString; + std::size_t found = request.getUrl().rfind("/"); + if (found != std::string::npos) { + elementIdString = request.getUrl().substr(found + 1); + try { + request.setElementId(std::stoi(elementIdString)); + } catch (...) { + spdlog::get("console")->warn("Couldn't set {} as int element id", elementIdString); + } + request.setElementIdString(elementIdString); + } +} diff --git a/src/api/controllers/Controller.h b/src/api/controllers/Controller.h index f463b10..fbe94a4 100644 --- a/src/api/controllers/Controller.h +++ b/src/api/controllers/Controller.h @@ -57,6 +57,12 @@ class Controller { protected: std::map routes; std::vector urls; + + /** + * Set the element id of the request + * @param request to set it's element id + */ + void setElementId(Request &request); }; diff --git a/src/api/controllers/PlayController.cpp b/src/api/controllers/PlayController.cpp new file mode 100644 index 0000000..88755e2 --- /dev/null +++ b/src/api/controllers/PlayController.cpp @@ -0,0 +1,37 @@ + + +#include "PlayController.h" +#include "../config/Constants.h" + +PlayController::PlayController() { + playRegex = "/play/.*\\.mp3$"; + addRoute(HTTP_GET, "/play/", new RequestHandler(this, &PlayController::get)); +} + +PlayController::~PlayController() { + +} + +bool PlayController::handles(std::string method, std::string url) { + return method == HTTP_GET && std::regex_match(url, playRegex); +} + +Response *PlayController::process(Request &request) { + Response *response = NULL; + + response = Controller::process(request); + if (!response && request.getHttpVerb() == HTTP_GET) { + // It's a play track + setElementId(request); + request.setUrl("/play/"); + response = Controller::process(request); + } + + return response; +} + +void PlayController::get(Request &request, JSONResponse &response) { + std::string fileLocation = "../music/" + request.getElementIdString(); + mg_http_serve_file(request.getConnection(), request.getHttpMessage(), fileLocation.c_str(), + mg_mk_str("audio/mpeg3"), mg_mk_str("")); +} diff --git a/src/api/controllers/PlayController.h b/src/api/controllers/PlayController.h new file mode 100644 index 0000000..a73afaf --- /dev/null +++ b/src/api/controllers/PlayController.h @@ -0,0 +1,52 @@ + + +#ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H +#define FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H + +#include +#include "Controller.h" +#include "../networking/JSONResponse.h" + +/** + * @file PlayController.h + */ +class PlayController : public Controller { +public: + /** + * Constructor + */ + PlayController(); + + /** + * Destructor + */ + virtual ~PlayController(); + + /** + * Returns if current controller handles the given method and url + * @param method the http method of the request + * @param url of the request + * @return true if handles, false otherwise + */ + bool handles(std::string method, std::string url); + + /** + * Process the given request and respond accordingly + * @param request to process + * @return the corresponding response + */ + Response *process(Request &request); + + /** + * Get the static file *.mp3 + * @param request request with the song to play + * @param response with the static file if file exists, 404 otherwise + */ + void get(Request &request, JSONResponse &response); + +private: + std::regex playRegex; +}; + + +#endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H diff --git a/src/api/controllers/TracksController.cpp b/src/api/controllers/TracksController.cpp index 10eab12..47a7d29 100644 --- a/src/api/controllers/TracksController.cpp +++ b/src/api/controllers/TracksController.cpp @@ -29,12 +29,7 @@ Response *TracksController::process(Request &request) { response = Controller::process(request); if (!response && request.getHttpVerb() == HTTP_GET) { // It's a GET /tracks/$id - std::string elementIdString; - std::size_t found = request.getUrl().rfind("/"); - if (found != std::string::npos) { - elementIdString = request.getUrl().substr(found + 1); - request.setElementId(std::stoi(elementIdString)); - } + setElementId(request); request.setUrl("/tracks/"); response = Controller::process(request); } diff --git a/src/api/networking/Request.cpp b/src/api/networking/Request.cpp index cd48cc4..c19c2e1 100644 --- a/src/api/networking/Request.cpp +++ b/src/api/networking/Request.cpp @@ -3,7 +3,8 @@ #include "Request.h" #include "spdlog/spdlog.h" -Request::Request(mg_connection *connection, http_message *httpMessage) : connection(connection), url(""), body(""), +Request::Request(mg_connection *connection, http_message *httpMessage) : connection(connection), + httpMessage(httpMessage), url(""), body(""), httpVerb(""), elementId(-1) { parseMessage(httpMessage); spdlog::get("console")->info("Processing request {0} {1}", httpVerb, url); @@ -55,3 +56,19 @@ void Request::setElementId(int elementId) { void Request::setUrl(const std::string &url) { Request::url = url; } + +mg_connection *Request::getConnection() const { + return connection; +} + +http_message *Request::getHttpMessage() const { + return httpMessage; +} + +const std::string &Request::getElementIdString() const { + return elementIdString; +} + +void Request::setElementIdString(const std::string &elementIdString) { + Request::elementIdString = elementIdString; +} diff --git a/src/api/networking/Request.h b/src/api/networking/Request.h index ba3f749..0249e37 100644 --- a/src/api/networking/Request.h +++ b/src/api/networking/Request.h @@ -68,13 +68,39 @@ class Request { */ void setUrl(const std::string &url); + /** + * Get the associated connection + * @return the connection + */ + mg_connection *getConnection() const; + + /** + * Get the original http message + * @return the http message + */ + http_message *getHttpMessage() const; + + /** + * Get the element id as string + * @return element id as string + */ + const std::string &getElementIdString() const; + + /** + * Set the elementId as a string + * @param elementIdString to set + */ + void setElementIdString(const std::string &elementIdString); + + private: mg_connection *connection; + http_message *httpMessage; std::string url; std::string body; std::string httpVerb; int elementId; -private: + std::string elementIdString; void parseMessage(http_message *httpMessage); }; diff --git a/src/api/networking/Server.cpp b/src/api/networking/Server.cpp index 3b3c89e..6aba414 100644 --- a/src/api/networking/Server.cpp +++ b/src/api/networking/Server.cpp @@ -4,6 +4,7 @@ #include "../controllers/PingController.h" #include "../config/Constants.h" #include "../controllers/TracksController.h" +#include "../controllers/PlayController.h" #include void event_handler(struct mg_connection *c, int ev, void *p) { @@ -19,8 +20,10 @@ Server::Server(int port, std::string ip) : server(NULL), connection(NULL), port( // Initialize controllers PingController *pingController = new PingController(); TracksController *tracksController = new TracksController(); + PlayController *playController = new PlayController(); registerController(pingController); registerController(tracksController); + registerController(playController); } Server::~Server() { diff --git a/tests/integration/MongoDaoTest.h b/tests/integration/MongoDaoTest.h index 409c889..d84b83b 100644 --- a/tests/integration/MongoDaoTest.h +++ b/tests/integration/MongoDaoTest.h @@ -16,15 +16,15 @@ class MongoDaoTest : public testing::Test { void testSaving(); }; -// TEST_F(MongoDaoTest, testGetting) { -// MongoDaoTest tester; -// tester.testGetting(); -// } -// -// TEST_F(MongoDaoTest, testSaving) { -// MongoDaoTest tester; -// tester.testSaving(); -// } + TEST_F(MongoDaoTest, testGetting) { + MongoDaoTest tester; + tester.testGetting(); + } + + TEST_F(MongoDaoTest, testSaving) { + MongoDaoTest tester; + tester.testSaving(); + } #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_MONGODAOTEST_H From ff8c8e10d0c2f679a162c2fa58d5f9255a98287d Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Thu, 4 May 2017 20:25:24 -0300 Subject: [PATCH 02/12] Add file location note --- src/api/controllers/PlayController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/controllers/PlayController.cpp b/src/api/controllers/PlayController.cpp index 88755e2..206fd74 100644 --- a/src/api/controllers/PlayController.cpp +++ b/src/api/controllers/PlayController.cpp @@ -31,7 +31,7 @@ Response *PlayController::process(Request &request) { } void PlayController::get(Request &request, JSONResponse &response) { - std::string fileLocation = "../music/" + request.getElementIdString(); + std::string fileLocation = "../music/" + request.getElementIdString(); // TODO: Check in compose the location mg_http_serve_file(request.getConnection(), request.getHttpMessage(), fileLocation.c_str(), mg_mk_str("audio/mpeg3"), mg_mk_str("")); } From f2dec95ac87e7a3546a2438efb927cf8d1580b23 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Sat, 6 May 2017 14:21:57 -0300 Subject: [PATCH 03/12] Ok receiving multipart files --- CMakeLists.txt | 1 + src/api/networking/Server.cpp | 29 +++++++++++++++++++++++------ src/api/networking/Server.h | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f80b4e7..133582f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(PythonInterp REQUIRED) if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-Wall -ansi -Wno-deprecated -pthread) endif () +add_definitions(-DMG_ENABLE_HTTP_STREAMING_MULTIPART) #------------------- # set common include folder for module diff --git a/src/api/networking/Server.cpp b/src/api/networking/Server.cpp index 6aba414..e0ac89e 100644 --- a/src/api/networking/Server.cpp +++ b/src/api/networking/Server.cpp @@ -7,12 +7,29 @@ #include "../controllers/PlayController.h" #include -void event_handler(struct mg_connection *c, int ev, void *p) { - if (ev == MG_EV_HTTP_REQUEST) { - Server *self = (Server *) c->user_data; - if (self != NULL) { - self->handleRequest(c, (http_message *) p); - } +struct mg_str upload_fname(struct mg_connection *c, struct mg_str file_name) { + // Return the same filename. Do not actually do this except in test! + // fname is user-controlled and needs to be sanitized. + std::string *final = new std::string("../music/" + std::string(file_name.p)); + return mg_mk_str(final->c_str()); +} + +void event_handler(struct mg_connection *new_connection, int event, void *event_data) { + Server *self = NULL; + switch (event) { + case MG_EV_HTTP_REQUEST: + self = (Server *) new_connection->user_data; + if (self != NULL) { + self->handleRequest(new_connection, (http_message *) event_data); + } + break; + case MG_EV_HTTP_PART_BEGIN: + case MG_EV_HTTP_PART_DATA: + case MG_EV_HTTP_PART_END: + mg_file_upload_handler(new_connection, event, event_data, upload_fname); + break; + default: + break; } } diff --git a/src/api/networking/Server.h b/src/api/networking/Server.h index c9b7674..02c074b 100644 --- a/src/api/networking/Server.h +++ b/src/api/networking/Server.h @@ -49,7 +49,7 @@ class Server { void handleRequest(mg_connection *connection, http_message *message); - friend void event_handler(mg_connection *c, int ev, void *p); + friend void event_handler(mg_connection *new_connection, int event, void *event_data); Response *handleRequest(Request &request); From 42c7a59d22f3386f2ceeaf1fbfd12313fa432797 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Tue, 9 May 2017 14:40:07 -0300 Subject: [PATCH 04/12] Adapt request and server to process multipart requests --- Dockerfile | 2 +- src/api/controllers/TracksController.cpp | 8 +++++++- src/api/networking/Request.cpp | 10 +++++++++- src/api/networking/Request.h | 10 ++++++++++ src/api/networking/Server.cpp | 13 ++++++++++++- src/api/networking/Server.h | 2 ++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 26c1183..a3b651b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV COVERALLS_SERVICE_NAME=$travis_service WORKDIR fiuba-taller2-tallerify-app-server WORKDIR build -RUN $HOME/usr/bin/cmake -DCOVERALLS=ON -DCMAKE_BUILD_TYPE=Debug .. +RUN $HOME/usr/bin/cmake -DCOVERALLS=OFF -DCMAKE_BUILD_TYPE=Debug .. RUN make CMD ["./fiuba_taller2_tallerify_app_server", "0.0.0.0"] diff --git a/src/api/controllers/TracksController.cpp b/src/api/controllers/TracksController.cpp index 47a7d29..5c2a31f 100644 --- a/src/api/controllers/TracksController.cpp +++ b/src/api/controllers/TracksController.cpp @@ -9,6 +9,8 @@ TracksController::TracksController() { tracksRegex = "/tracks/.*"; addRoute(HTTP_GET, "/tracks/", new RequestHandler(this, &TracksController::get)); + addRoute(HTTP_POST, "/tracks", + new RequestHandler(this, &TracksController::post)); } TracksController::~TracksController() { @@ -46,7 +48,11 @@ void TracksController::get(Request &request, JSONResponse &response) { response.getCode()); return; } - response["songId"] = track->getId(); + response["trackId"] = track->getId(); response["url"] = BASE_URL + track->getFileLocation(); // TODO: Get the real one delete track; } + +void TracksController::post(Request &request, JSONResponse &response) { + spdlog::get("console")->info("Inside tracks post"); +} diff --git a/src/api/networking/Request.cpp b/src/api/networking/Request.cpp index c19c2e1..064a479 100644 --- a/src/api/networking/Request.cpp +++ b/src/api/networking/Request.cpp @@ -2,10 +2,12 @@ #include "Request.h" #include "spdlog/spdlog.h" +#include "../config/Constants.h" Request::Request(mg_connection *connection, http_message *httpMessage) : connection(connection), httpMessage(httpMessage), url(""), body(""), - httpVerb(""), elementId(-1) { + httpVerb(""), elementId(-1), event(-1), + eventData(NULL) { parseMessage(httpMessage); spdlog::get("console")->info("Processing request {0} {1}", httpVerb, url); } @@ -72,3 +74,9 @@ const std::string &Request::getElementIdString() const { void Request::setElementIdString(const std::string &elementIdString) { Request::elementIdString = elementIdString; } + +Request::Request(mg_connection *connection, int event, void *eventData) : connection(connection), httpMessage(NULL), + url("/tracks"), body(""), httpVerb(HTTP_POST), + elementId(-1), event(event), + eventData(eventData) { +} diff --git a/src/api/networking/Request.h b/src/api/networking/Request.h index 0249e37..7968acf 100644 --- a/src/api/networking/Request.h +++ b/src/api/networking/Request.h @@ -21,6 +21,14 @@ class Request { */ Request(mg_connection *connection, http_message *httpMessage); + /** + * Request constructor for multipart requests + * @param connection + * @param event + * @param eventData + */ + Request(mg_connection *connection, int event, void *eventData); + /** * Request destroyer */ @@ -101,6 +109,8 @@ class Request { std::string httpVerb; int elementId; std::string elementIdString; + int event; + void *eventData; void parseMessage(http_message *httpMessage); }; diff --git a/src/api/networking/Server.cpp b/src/api/networking/Server.cpp index e0ac89e..1635643 100644 --- a/src/api/networking/Server.cpp +++ b/src/api/networking/Server.cpp @@ -18,6 +18,7 @@ void event_handler(struct mg_connection *new_connection, int event, void *event_ Server *self = NULL; switch (event) { case MG_EV_HTTP_REQUEST: + spdlog::get("console")->info("Got new request"); self = (Server *) new_connection->user_data; if (self != NULL) { self->handleRequest(new_connection, (http_message *) event_data); @@ -26,7 +27,13 @@ void event_handler(struct mg_connection *new_connection, int event, void *event_ case MG_EV_HTTP_PART_BEGIN: case MG_EV_HTTP_PART_DATA: case MG_EV_HTTP_PART_END: - mg_file_upload_handler(new_connection, event, event_data, upload_fname); + self = (Server *) new_connection->user_data; + if (self != NULL) { + self->handleRequest(new_connection, event, event_data); + } + //TracksController tracksController; + //tracksController.post(NULL, ); + //mg_file_upload_handler(new_connection, event, event_data, upload_fname); break; default: break; @@ -78,6 +85,10 @@ void Server::stop() { } } +void Server::handleRequest(mg_connection *connection, int event, void *event_data) { + Request request(connection, event, event_data); +} + void Server::handleRequest(mg_connection *connection, http_message *message) { Request request(connection, message); diff --git a/src/api/networking/Server.h b/src/api/networking/Server.h index 02c074b..436e8f7 100644 --- a/src/api/networking/Server.h +++ b/src/api/networking/Server.h @@ -49,6 +49,8 @@ class Server { void handleRequest(mg_connection *connection, http_message *message); + void handleRequest(mg_connection *connection, int event, void *event_data); + friend void event_handler(mg_connection *new_connection, int event, void *event_data); Response *handleRequest(Request &request); From 5d281b9ac27e7d05c940540a8b6fcef4c8975893 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Tue, 9 May 2017 15:20:24 -0300 Subject: [PATCH 05/12] Refactor handleRequest, create dispatchRequest method --- src/api/networking/Server.cpp | 20 +++++++++++--------- src/api/networking/Server.h | 3 +++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/api/networking/Server.cpp b/src/api/networking/Server.cpp index 1635643..ff52c17 100644 --- a/src/api/networking/Server.cpp +++ b/src/api/networking/Server.cpp @@ -31,8 +31,6 @@ void event_handler(struct mg_connection *new_connection, int event, void *event_ if (self != NULL) { self->handleRequest(new_connection, event, event_data); } - //TracksController tracksController; - //tracksController.post(NULL, ); //mg_file_upload_handler(new_connection, event, event_data, upload_fname); break; default: @@ -85,13 +83,7 @@ void Server::stop() { } } -void Server::handleRequest(mg_connection *connection, int event, void *event_data) { - Request request(connection, event, event_data); -} - -void Server::handleRequest(mg_connection *connection, http_message *message) { - Request request(connection, message); - +void Server::dispatchRequest(Request &request) { Response *response = handleRequest(request); if (response != NULL) { @@ -100,6 +92,16 @@ void Server::handleRequest(mg_connection *connection, http_message *message) { } } +void Server::handleRequest(mg_connection *connection, int event, void *event_data) { + Request request(connection, event, event_data); + dispatchRequest(request); +} + +void Server::handleRequest(mg_connection *connection, http_message *message) { + Request request(connection, message); + dispatchRequest(request); +} + Response *Server::handleRequest(Request &request) { Response *response; Controller *handler = NULL; diff --git a/src/api/networking/Server.h b/src/api/networking/Server.h index 436e8f7..ad106d5 100644 --- a/src/api/networking/Server.h +++ b/src/api/networking/Server.h @@ -56,6 +56,9 @@ class Server { Response *handleRequest(Request &request); void registerController(Controller *controller); + + void dispatchRequest(Request &request); + }; From 0c660a63f7b9ce3879d0cc9e09921d46940143cc Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Tue, 9 May 2017 15:22:01 -0300 Subject: [PATCH 06/12] Add todo --- src/api/controllers/TracksController.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/controllers/TracksController.cpp b/src/api/controllers/TracksController.cpp index 5c2a31f..d48d6c3 100644 --- a/src/api/controllers/TracksController.cpp +++ b/src/api/controllers/TracksController.cpp @@ -55,4 +55,5 @@ void TracksController::get(Request &request, JSONResponse &response) { void TracksController::post(Request &request, JSONResponse &response) { spdlog::get("console")->info("Inside tracks post"); + // TODO: Alter mongoose upload_handler to not close connection and return json response } From c4fc3e1631b90daff79319369d76a54e8ebd9172 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Tue, 9 May 2017 15:31:52 -0300 Subject: [PATCH 07/12] Fix get track json is now trackId, not songId --- tests/integration/TracksControllerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/TracksControllerTest.cpp b/tests/integration/TracksControllerTest.cpp index d9373cc..b912ac9 100644 --- a/tests/integration/TracksControllerTest.cpp +++ b/tests/integration/TracksControllerTest.cpp @@ -26,7 +26,7 @@ void TracksControllerTest::testTrackFound() { Request request(&connection, &message); response = controller.process(request); - ASSERT_EQ(response->getBody(), "{\"songId\":" + std::to_string(id) + ",\"url\":\"" + BASE_URL + songLocation + "\"}\n"); + ASSERT_EQ(response->getBody(), "{\"trackId\":" + std::to_string(id) + ",\"url\":\"" + BASE_URL + songLocation + "\"}\n"); delete response; } From 10833e8c2700ae52aa1b17ea998a40dfe1f0850a Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Fri, 12 May 2017 20:51:13 -0300 Subject: [PATCH 08/12] Upload file and return json with saved trackId --- include/mongoose/mongoose.c | 20 ++++++++++------ include/mongoose/mongoose.h | 4 +++- src/api/controllers/TracksController.cpp | 29 +++++++++++++++++------- src/api/controllers/TracksController.h | 16 ++++++++++--- src/api/domain/returnType.h | 4 ++++ src/api/networking/Request.cpp | 8 +++++++ src/api/networking/Request.h | 12 ++++++++++ src/api/networking/Server.cpp | 21 ++++++++--------- src/api/networking/Server.h | 2 +- 9 files changed, 84 insertions(+), 32 deletions(-) create mode 100644 src/api/domain/returnType.h diff --git a/include/mongoose/mongoose.c b/include/mongoose/mongoose.c index 7e55896..1808132 100644 --- a/include/mongoose/mongoose.c +++ b/include/mongoose/mongoose.c @@ -7497,9 +7497,10 @@ void mg_serve_http(struct mg_connection *nc, struct http_message *hm, } #if MG_ENABLE_HTTP_STREAMING_MULTIPART -void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, +struct returnType* mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, mg_fu_fname_fn local_name_fn) { - switch (ev) { + int trackId; + switch (ev) { case MG_EV_HTTP_PART_BEGIN: { struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) ev_data; @@ -7517,7 +7518,7 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, "Not allowed to upload %s\r\n", mp->file_name); nc->flags |= MG_F_SEND_AND_CLOSE; - return; + return NULL; } fus->lfn = (char *) malloc(lfn.len + 1); memcpy(fus->lfn, lfn.p, lfn.len); @@ -7574,7 +7575,7 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, /* Do not close the connection just yet, discard remainder of the data. * This is because at the time of writing some browsers (Chrome) fail to * render response before all the data is sent. */ - return; + return NULL; } fus->num_recd += mp->data.len; LOG(LL_DEBUG, ("%p rec'd %d bytes, %d total", nc, (int) mp->data.len, @@ -7590,12 +7591,12 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, if (mp->status >= 0 && fus->fp != NULL) { LOG(LL_DEBUG, ("%p Uploaded %s (%s), %d bytes", nc, mp->file_name, fus->lfn, (int) fus->num_recd)); + trackId = rand(); mg_printf(nc, "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain\r\n" + "Content-Type: application/json\r\n" "Connection: close\r\n\r\n" - "Ok, %s - %d bytes.\r\n", - mp->file_name, (int) fus->num_recd); + "{\"trackId\": %d}\r\n", trackId); } else { LOG(LL_ERROR, ("Failed to store %s (%s)", mp->file_name, fus->lfn)); /* @@ -7608,9 +7609,14 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, free(fus); mp->user_data = NULL; nc->flags |= MG_F_SEND_AND_CLOSE; + struct returnType *ret = malloc(sizeof(struct returnType)); + ret->trackId = trackId; + ret->filename = mp->file_name; + return ret; break; } } + return NULL; } #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */ diff --git a/include/mongoose/mongoose.h b/include/mongoose/mongoose.h index 1dbec85..9399d7c 100644 --- a/include/mongoose/mongoose.h +++ b/include/mongoose/mongoose.h @@ -23,6 +23,8 @@ #ifndef CS_MONGOOSE_SRC_COMMON_H_ #define CS_MONGOOSE_SRC_COMMON_H_ +#include "../../src/api/domain/returnType.h" + #define MG_VERSION "6.7" /* Local tweaks, applied before any of Mongoose's own headers. */ @@ -4722,7 +4724,7 @@ typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc, * } * ``` */ -void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, +struct returnType* mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, mg_fu_fname_fn local_name_fn); #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */ #endif /* MG_ENABLE_FILESYSTEM */ diff --git a/src/api/controllers/TracksController.cpp b/src/api/controllers/TracksController.cpp index d48d6c3..b78e811 100644 --- a/src/api/controllers/TracksController.cpp +++ b/src/api/controllers/TracksController.cpp @@ -5,12 +5,18 @@ #include "../config/Constants.h" #include "../dao/MongoDao.h" -TracksController::TracksController() { - tracksRegex = "/tracks/.*"; +struct mg_str TracksController::upload_fname(struct mg_connection *c, struct mg_str file_name) { + // Return the same filename. Do not actually do this except in test! + // fname is user-controlled and needs to be sanitized. + std::string *final = new std::string("../music/" + std::string(file_name.p)); + return mg_mk_str(final->c_str()); +} + +TracksController::TracksController() : tracksRegex("/tracks/.*"), fileName(""){ addRoute(HTTP_GET, "/tracks/", new RequestHandler(this, &TracksController::get)); - addRoute(HTTP_POST, "/tracks", - new RequestHandler(this, &TracksController::post)); + /*addRoute(HTTP_POST, "/tracks", + new RequestHandler(this, &TracksController::post));*/ } TracksController::~TracksController() { @@ -49,11 +55,18 @@ void TracksController::get(Request &request, JSONResponse &response) { return; } response["trackId"] = track->getId(); - response["url"] = BASE_URL + track->getFileLocation(); // TODO: Get the real one + response["url"] = BASE_URL + track->getFileLocation(); delete track; } -void TracksController::post(Request &request, JSONResponse &response) { - spdlog::get("console")->info("Inside tracks post"); - // TODO: Alter mongoose upload_handler to not close connection and return json response +void TracksController::post(int trackId, const char* filename) { + setFileName(filename); + MongoDao dao; + Track *track = new Track(trackId, fileName); + dao.saveTrack(track); + delete track; +} + +void TracksController::setFileName(const char *fileName) { + TracksController::fileName = "/music/" + std::string(fileName); } diff --git a/src/api/controllers/TracksController.h b/src/api/controllers/TracksController.h index 3c9128c..8f07757 100644 --- a/src/api/controllers/TracksController.h +++ b/src/api/controllers/TracksController.h @@ -47,13 +47,23 @@ class TracksController : public Controller { /** * Post a track to create it - * @param request with the song - * @param response ok if track was saved, 500 otherwise + * @param trackId + * @param filename */ - void post(Request &request, JSONResponse &response); + void post(int trackId, const char* filename); + + /** + * Sets the filename of the file being uploaded + * @param fileName + */ + void setFileName(const char *fileName); + + static struct mg_str upload_fname(struct mg_connection *c, struct mg_str file_name); + private: std::regex tracksRegex; + std::string fileName; }; diff --git a/src/api/domain/returnType.h b/src/api/domain/returnType.h new file mode 100644 index 0000000..28aac9f --- /dev/null +++ b/src/api/domain/returnType.h @@ -0,0 +1,4 @@ +struct returnType { + int trackId; + const char *filename; +}; \ No newline at end of file diff --git a/src/api/networking/Request.cpp b/src/api/networking/Request.cpp index 064a479..e1bbe4e 100644 --- a/src/api/networking/Request.cpp +++ b/src/api/networking/Request.cpp @@ -80,3 +80,11 @@ Request::Request(mg_connection *connection, int event, void *eventData) : connec elementId(-1), event(event), eventData(eventData) { } + +int Request::getEvent() const { + return event; +} + +void *Request::getEventData() const { + return eventData; +} diff --git a/src/api/networking/Request.h b/src/api/networking/Request.h index 7968acf..7967481 100644 --- a/src/api/networking/Request.h +++ b/src/api/networking/Request.h @@ -100,6 +100,18 @@ class Request { */ void setElementIdString(const std::string &elementIdString); + /** + * Event getter + * @return the event code + */ + int getEvent() const; + + /** + * Event data getter + * @return the event data as void* + */ + void *getEventData() const; + private: mg_connection *connection; diff --git a/src/api/networking/Server.cpp b/src/api/networking/Server.cpp index ff52c17..8cb1011 100644 --- a/src/api/networking/Server.cpp +++ b/src/api/networking/Server.cpp @@ -7,15 +7,9 @@ #include "../controllers/PlayController.h" #include -struct mg_str upload_fname(struct mg_connection *c, struct mg_str file_name) { - // Return the same filename. Do not actually do this except in test! - // fname is user-controlled and needs to be sanitized. - std::string *final = new std::string("../music/" + std::string(file_name.p)); - return mg_mk_str(final->c_str()); -} - void event_handler(struct mg_connection *new_connection, int event, void *event_data) { Server *self = NULL; + struct returnType* ret; switch (event) { case MG_EV_HTTP_REQUEST: spdlog::get("console")->info("Got new request"); @@ -26,12 +20,15 @@ void event_handler(struct mg_connection *new_connection, int event, void *event_ break; case MG_EV_HTTP_PART_BEGIN: case MG_EV_HTTP_PART_DATA: + mg_file_upload_handler(new_connection, event, event_data, TracksController::upload_fname); + break; case MG_EV_HTTP_PART_END: self = (Server *) new_connection->user_data; + ret = mg_file_upload_handler(new_connection, event, event_data, TracksController::upload_fname); if (self != NULL) { - self->handleRequest(new_connection, event, event_data); + ((TracksController*)self->controllers.back())->post(ret->trackId, ret->filename); } - //mg_file_upload_handler(new_connection, event, event_data, upload_fname); + free(ret); break; default: break; @@ -41,8 +38,8 @@ void event_handler(struct mg_connection *new_connection, int event, void *event_ Server::Server(int port, std::string ip) : server(NULL), connection(NULL), port(port), localIp(ip), running(false) { // Initialize controllers PingController *pingController = new PingController(); - TracksController *tracksController = new TracksController(); PlayController *playController = new PlayController(); + TracksController *tracksController = new TracksController(); registerController(pingController); registerController(tracksController); registerController(playController); @@ -92,10 +89,10 @@ void Server::dispatchRequest(Request &request) { } } -void Server::handleRequest(mg_connection *connection, int event, void *event_data) { +/*void Server::handleRequest(mg_connection *connection, int event, void *event_data) { Request request(connection, event, event_data); dispatchRequest(request); -} +}*/ void Server::handleRequest(mg_connection *connection, http_message *message) { Request request(connection, message); diff --git a/src/api/networking/Server.h b/src/api/networking/Server.h index ad106d5..326509d 100644 --- a/src/api/networking/Server.h +++ b/src/api/networking/Server.h @@ -49,7 +49,7 @@ class Server { void handleRequest(mg_connection *connection, http_message *message); - void handleRequest(mg_connection *connection, int event, void *event_data); + //void handleRequest(mg_connection *connection, int event, void *event_data); friend void event_handler(mg_connection *new_connection, int event, void *event_data); From f28cf8a0a013c9b212c350922617d158c8430d0a Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Fri, 12 May 2017 21:00:50 -0300 Subject: [PATCH 09/12] Track post test --- tests/integration/TracksControllerTest.cpp | 10 ++++++++++ tests/integration/TracksControllerTest.h | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/tests/integration/TracksControllerTest.cpp b/tests/integration/TracksControllerTest.cpp index b912ac9..7293a1e 100644 --- a/tests/integration/TracksControllerTest.cpp +++ b/tests/integration/TracksControllerTest.cpp @@ -48,3 +48,13 @@ void TracksControllerTest::testTrackNotFound() { delete response; delete request; } + +void TracksControllerTest::testPostTrack() { + TracksController controller; + std::string filename = "asd"; + controller.post(124, filename.c_str()); + MongoDao dao; + Track *track = dao.getTrack(124); + ASSERT_EQ(track->getId(), 124); + delete(track); +} diff --git a/tests/integration/TracksControllerTest.h b/tests/integration/TracksControllerTest.h index fcd7e72..dd9dbe2 100644 --- a/tests/integration/TracksControllerTest.h +++ b/tests/integration/TracksControllerTest.h @@ -15,6 +15,8 @@ class TracksControllerTest : public testing::Test { void testTrackNotFound(); void testTrackFound(); + + void testPostTrack(); }; TEST_F(TracksControllerTest, testTrackNotFound @@ -35,5 +37,14 @@ testTrackFound(); } +TEST_F(TracksControllerTest, testPostTrack +) { +TracksControllerTest tester; +tester. + +testPostTrack(); + +} + #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLERTEST_H From 22eb421769df6cff00a2eeb2c695b72a3d42a8f3 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Fri, 12 May 2017 21:07:04 -0300 Subject: [PATCH 10/12] More testing --- tests/integration/TracksControllerTest.cpp | 7 ++++--- tests/unit/RequestTest.cpp | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/integration/TracksControllerTest.cpp b/tests/integration/TracksControllerTest.cpp index 7293a1e..6959301 100644 --- a/tests/integration/TracksControllerTest.cpp +++ b/tests/integration/TracksControllerTest.cpp @@ -52,9 +52,10 @@ void TracksControllerTest::testTrackNotFound() { void TracksControllerTest::testPostTrack() { TracksController controller; std::string filename = "asd"; - controller.post(124, filename.c_str()); + int id = rand(); + controller.post(id, filename.c_str()); MongoDao dao; - Track *track = dao.getTrack(124); - ASSERT_EQ(track->getId(), 124); + Track *track = dao.getTrack(id); + ASSERT_EQ(track->getId(), id); delete(track); } diff --git a/tests/unit/RequestTest.cpp b/tests/unit/RequestTest.cpp index 08c86f8..a2ed7ce 100644 --- a/tests/unit/RequestTest.cpp +++ b/tests/unit/RequestTest.cpp @@ -16,7 +16,10 @@ void RequestTest::testHttpInitialization() { message.uri = mg_mk_str(uri.c_str()); Request request(NULL, &message); + request.getEventData(); ASSERT_EQ(request.getBody(), body); ASSERT_EQ(request.getHttpVerb(), method); ASSERT_EQ(request.getUrl(), uri); + ASSERT_EQ(request.getEvent(), -1); + ASSERT_EQ(request.getElementIdString(), ""); } From c7cfb2b128269d67ed81f9b25848f5624aa72b13 Mon Sep 17 00:00:00 2001 From: Martin Stancanelli Date: Sat, 13 May 2017 15:01:26 -0300 Subject: [PATCH 11/12] Update docs --- conf.py | 4 +- doc/.buildinfo | 2 +- doc/.doctrees/doc/rst/controller.doctree | Bin 30089 -> 30333 bytes doc/.doctrees/doc/rst/json_response.doctree | Bin 12166 -> 12161 bytes doc/.doctrees/doc/rst/request.doctree | Bin 33919 -> 56365 bytes .../doc/rst/tracks_controller.doctree | Bin 27467 -> 29924 bytes doc/.doctrees/environment.pickle | Bin 75434 -> 86061 bytes doc/.doctrees/index.doctree | Bin 4907 -> 4912 bytes doc/doc/rst/controller.html | 10 +- doc/doc/rst/json_response.html | 8 +- doc/doc/rst/mongo_dao.html | 8 +- doc/doc/rst/ping_controller.html | 8 +- doc/doc/rst/request.html | 86 ++++- doc/doc/rst/response.html | 8 +- doc/doc/rst/server.html | 8 +- doc/doc/rst/track.html | 8 +- doc/doc/rst/tracks_controller.html | 29 +- doc/genindex.html | 30 +- doc/html/_controller_8h_source.html | 3 +- doc/html/_play_controller_8h.html | 90 +++++ doc/html/_play_controller_8h_source.html | 87 +++++ doc/html/_request_8h_source.html | 24 +- doc/html/_server_8h_source.html | 10 +- doc/html/_tracks_controller_8h_source.html | 11 +- doc/html/annotated.html | 12 +- doc/html/class_controller-members.html | 5 +- doc/html/class_controller.html | 45 ++- doc/html/class_controller.png | Bin 673 -> 843 bytes doc/html/class_ping_controller-members.html | 7 +- doc/html/class_ping_controller.html | 3 + doc/html/class_play_controller-members.html | 88 +++++ doc/html/class_play_controller.html | 287 ++++++++++++++++ doc/html/class_play_controller.png | Bin 0 -> 452 bytes doc/html/class_request-members.html | 21 +- doc/html/class_request.html | 172 +++++++++- doc/html/class_server.html | 6 +- doc/html/class_tracks_controller-members.html | 11 +- doc/html/class_tracks_controller.html | 56 +++- doc/html/classes.html | 20 +- .../dir_eeb391a24df1216ed709bbe6155a8e7d.html | 2 + doc/html/files.html | 12 +- doc/html/functions.html | 35 +- doc/html/functions_func.html | 35 +- doc/html/hierarchy.html | 20 +- doc/html/return_type_8h_source.html | 78 +++++ doc/html/search/all_2.js | 7 +- doc/html/search/all_3.js | 2 +- doc/html/search/all_6.js | 6 +- doc/html/search/all_7.js | 5 +- doc/html/search/all_8.js | 4 +- doc/html/search/all_b.js | 1 + doc/html/search/classes_3.js | 3 +- doc/html/search/classes_4.js | 3 +- doc/html/search/files_3.js | 3 +- doc/html/search/functions_2.js | 7 +- doc/html/search/functions_3.js | 2 +- doc/html/search/functions_6.js | 5 +- doc/html/search/functions_7.js | 2 +- doc/html/search/functions_8.js | 4 +- doc/html/search/functions_b.js | 1 + doc/html/structreturn_type-members.html | 78 +++++ doc/html/structreturn_type.html | 89 +++++ doc/index.html | 8 +- doc/objects.inv | Bin 2230 -> 2494 bytes doc/search.html | 8 +- doc/searchindex.js | 2 +- doc/xml/_constants_8h.xml | 2 + doc/xml/_controller_8cpp.xml | 14 + doc/xml/_controller_8h.xml | 21 +- doc/xml/_j_s_o_n_response_8cpp.xml | 22 +- doc/xml/_j_s_o_n_response_8h.xml | 35 +- doc/xml/_mongo_dao_8cpp.xml | 36 +- doc/xml/_mongo_dao_8h.xml | 18 +- doc/xml/_ping_controller_8cpp.xml | 52 +-- doc/xml/_ping_controller_8h.xml | 44 +-- doc/xml/_play_controller_8cpp.xml | 131 ++++++++ doc/xml/_play_controller_8h.xml | 113 +++++++ doc/xml/_request_8cpp.xml | 172 ++++++---- doc/xml/_request_8h.xml | 116 ++++--- doc/xml/_response_8cpp.xml | 22 +- doc/xml/_response_8h.xml | 48 +-- doc/xml/_server_8cpp.xml | 311 ++++++++++-------- doc/xml/_server_8h.xml | 55 ++-- doc/xml/_track_8cpp.xml | 14 +- doc/xml/_track_8h.xml | 12 +- doc/xml/_tracks_controller_8cpp.xml | 187 ++++++----- doc/xml/_tracks_controller_8h.xml | 68 ++-- doc/xml/class_controller.xml | 41 ++- doc/xml/class_j_s_o_n_response.xml | 20 +- doc/xml/class_ping_controller.xml | 13 +- doc/xml/class_play_controller.xml | 195 +++++++++++ doc/xml/class_request.xml | 237 ++++++++++++- doc/xml/class_response.xml | 6 +- doc/xml/class_server.xml | 48 ++- doc/xml/class_tracks_controller.xml | 115 +++++-- .../dir_042ed6d28a050727846a19dfd1c505f7.xml | 1 + .../dir_eeb391a24df1216ed709bbe6155a8e7d.xml | 2 + doc/xml/index.xml | 40 ++- doc/xml/main_8cpp.xml | 50 +-- doc/xml/return_type_8h.xml | 18 + doc/xml/structreturn_type.xml | 43 +++ 101 files changed, 3105 insertions(+), 806 deletions(-) create mode 100644 doc/html/_play_controller_8h.html create mode 100644 doc/html/_play_controller_8h_source.html create mode 100644 doc/html/class_play_controller-members.html create mode 100644 doc/html/class_play_controller.html create mode 100644 doc/html/class_play_controller.png create mode 100644 doc/html/return_type_8h_source.html create mode 100644 doc/html/structreturn_type-members.html create mode 100644 doc/html/structreturn_type.html create mode 100644 doc/xml/_play_controller_8cpp.xml create mode 100644 doc/xml/_play_controller_8h.xml create mode 100644 doc/xml/class_play_controller.xml create mode 100644 doc/xml/return_type_8h.xml create mode 100644 doc/xml/structreturn_type.xml diff --git a/conf.py b/conf.py index e50864c..e767274 100644 --- a/conf.py +++ b/conf.py @@ -54,9 +54,9 @@ # built documents. # # The short X.Y version. -version = u'0.2.0' +version = u'0.2.1' # The full version, including alpha/beta/rc tags. -release = u'0.2.0' +release = u'0.2.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/.buildinfo b/doc/.buildinfo index 1a8911c..a5df127 100644 --- a/doc/.buildinfo +++ b/doc/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: b4f4b76259434676a5e1fbaf29f24dde +config: 5d2bb56954f7653c3522193763a0cb8f tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/.doctrees/doc/rst/controller.doctree b/doc/.doctrees/doc/rst/controller.doctree index 61dc5a168670cd0d2634743cbc9a688c1638a30b..b3da1c570a94edfaf08e8807defcfd33a7cfbc68 100644 GIT binary patch literal 30333 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 SJiB??Ar}>7t8pzQoBtmdm1~gz literal 30089 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 Pq(cQ%kgdkG5O4Z_0|gZH diff --git a/doc/.doctrees/doc/rst/json_response.doctree b/doc/.doctrees/doc/rst/json_response.doctree index 2089bac5b3115a610b4c20a6150bbbc3b76ea65e..d7309e0e8f7f40e6ea5568a2732253749af55522 100644 GIT binary patch delta 139 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 NjH|Z5btpUI{{hc-S#$sZ literal 33919 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 diff --git a/doc/.doctrees/doc/rst/tracks_controller.doctree b/doc/.doctrees/doc/rst/tracks_controller.doctree index 23b1c1a7f2ef45843ac6d2dea9f8e3d71ffcd0c8..434e34a1b5774e3befcd0a76386ce3979d36e19c 100644 GIT binary patch literal 29924 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 Q(++Jw1@CpmwUliBf4rUXxc~qF literal 27467 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 R@U%k%QNcbnuBGIJ{{xpuH7x)D diff --git a/doc/.doctrees/environment.pickle b/doc/.doctrees/environment.pickle index 2f38d95ed3f98c959372ce9260eb52a79cf39420..8ae8fa73915fa846408bb62e12ce8dc58ec99754 100644 GIT binary patch literal 86061 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 MRn9-0qslq@4>x+5!vFvP literal 75434 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 aJ9M&up&j1HiR9o`=c}J?T;r>sG5-$$076Ir diff --git a/doc/.doctrees/index.doctree b/doc/.doctrees/index.doctree index 024f0a68c0d1217f507d67870aecb57cf6dc5ca6..41dcc1c278bb3fc48785ed1f1dc08126f7a88974 100644 GIT binary patch delta 165 zcmZ3jwn1%!g^))PD}|Qch}05gSmlBb2)+u^cYM z4ixfc4CPHJ%`J#8PAw_P%u6pW;+R}5Bqz)Xl4A&E&P*vT;sUa3i?}DR5mFN70ke65 qWQI(JMuuE%5#Qv8LRt#^K#|xY0U#O5R+O3s(k2L2Dg-1;lk@wpwk2h0tVMAxSM(Mh1qCQ0}6{^7z!e#H5_mlp;2ukT+u}Z%S!yL40v)Nl9j2 zdT|l^8EHF=|uk}x-z%>yJeWHK}| - Controller — Tallerify App Server 0.2.0 documentation + Controller — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -169,7 +169,7 @@

Controller
class Controller¶
-

Subclassed by PingController, TracksController

+

Subclassed by PingController, PlayController, TracksController

Public Functions

@@ -294,7 +294,7 @@

Controller var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/json_response.html b/doc/doc/rst/json_response.html index a9b6acc..51ef0ac 100644 --- a/doc/doc/rst/json_response.html +++ b/doc/doc/rst/json_response.html @@ -8,7 +8,7 @@ - JSONResponse — Tallerify App Server 0.2.0 documentation + JSONResponse — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -243,7 +243,7 @@

JSONResponse var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/mongo_dao.html b/doc/doc/rst/mongo_dao.html index e50e096..a7dec99 100644 --- a/doc/doc/rst/mongo_dao.html +++ b/doc/doc/rst/mongo_dao.html @@ -8,7 +8,7 @@ - MongoDao — Tallerify App Server 0.2.0 documentation + MongoDao — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -260,7 +260,7 @@

MongoDao var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/ping_controller.html b/doc/doc/rst/ping_controller.html index 56df76f..b1ef190 100644 --- a/doc/doc/rst/ping_controller.html +++ b/doc/doc/rst/ping_controller.html @@ -8,7 +8,7 @@ - PingController — Tallerify App Server 0.2.0 documentation + PingController — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -247,7 +247,7 @@

PingController var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/request.html b/doc/doc/rst/request.html index 46f66c0..8775365 100644 --- a/doc/doc/rst/request.html +++ b/doc/doc/rst/request.html @@ -8,7 +8,7 @@ - Request — Tallerify App Server 0.2.0 documentation + Request — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -185,6 +185,21 @@

Request +
+Request(mg_connection *connection, int event, void *eventData)¶
+

Request constructor for multipart requests

+
Parameters
+
    +
  • connection:
  • +
  • event:
  • +
  • eventData:
  • +
+
+
+

+

+
~Request()¶
@@ -270,6 +285,69 @@

Request +
+mg_connection *getConnection() const¶
+

Get the associated connection

+
Return
+
the connection
+
+

+

+ +
+
+http_message *getHttpMessage() const¶
+

Get the original http message

+
Return
+
the http message
+
+

+
+ +
+
+const std::string &getElementIdString() const¶
+

Get the element id as string

+
Return
+
element id as string
+
+

+
+ +
+
+void setElementIdString(const std::string &elementIdString)¶
+

Set the elementId as a string

+
Parameters
+
    +
  • elementIdString: to set
  • +
+
+
+

+
+ +
+
+int getEvent() const¶
+

Event getter

+
Return
+
the event code
+
+

+
+ +
+
+void *getEventData() const¶
+

Event data getter

+
Return
+
the event data as void*
+
+

+
+
@@ -319,7 +397,7 @@

Request var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/response.html b/doc/doc/rst/response.html index 8fcda9e..efcfecd 100644 --- a/doc/doc/rst/response.html +++ b/doc/doc/rst/response.html @@ -8,7 +8,7 @@ - Response — Tallerify App Server 0.2.0 documentation + Response — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -247,7 +247,7 @@

Response var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/server.html b/doc/doc/rst/server.html index 676dae2..6a746aa 100644 --- a/doc/doc/rst/server.html +++ b/doc/doc/rst/server.html @@ -8,7 +8,7 @@ - Server — Tallerify App Server 0.2.0 documentation + Server — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@
- 0.2.0 + 0.2.1
@@ -252,7 +252,7 @@

Server var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', - VERSION:'0.2.0', + VERSION:'0.2.1', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true, diff --git a/doc/doc/rst/track.html b/doc/doc/rst/track.html index f9b2db7..b1b6a00 100644 --- a/doc/doc/rst/track.html +++ b/doc/doc/rst/track.html @@ -8,7 +8,7 @@ - Track — Tallerify App Server 0.2.0 documentation + Track — Tallerify App Server 0.2.1 documentation @@ -35,7 +35,7 @@ - + @@ -65,7 +65,7 @@
- 0.2.0 + 0.2.1
@@ -257,7 +257,7 @@

Track @@ -65,7 +65,7 @@
- 0.2.0 + 0.2.1
@@ -252,19 +252,31 @@

R

  • Request (C++ class)
  • Request::getBody (C++ function) +
  • +
  • Request::getConnection (C++ function)
  • Request::getElementId (C++ function) +
  • +
  • Request::getElementIdString (C++ function) +
  • +
  • Request::getEvent (C++ function) +
  • +
  • Request::getEventData (C++ function) +
  • +
  • Request::getHttpMessage (C++ function)
  • Request::getHttpVerb (C++ function)
  • Request::getUrl (C++ function)
  • -
  • Request::Request (C++ function) + + -
      +
    • Request::setElementIdString (C++ function) +
    • Request::setUrl (C++ function)
    • Request::writeResponse (C++ function) @@ -321,9 +333,11 @@

      T

    • TracksController::handles (C++ function)
    • -
    • TracksController::post (C++ function) +
    • TracksController::post (C++ function)
    • TracksController::process (C++ function) +
    • +
    • TracksController::setFileName (C++ function)
    • TracksController::TracksController (C++ function)
    • @@ -368,7 +382,7 @@

      T

      + + + + + + + +
      +
      + + + + + + +
      +
      Tallerify App Server +
      +
      +
      + + + + + + + + +
      +
      + + +
      + +
      + + +
      +
      + +
      +
      PlayController.h File Reference
      +
      +
      +
      #include <regex>
      +#include "Controller.h"
      +#include "../networking/JSONResponse.h"
      +
      +

      Go to the source code of this file.

      + + + + +

      +Classes

      class  PlayController
       
      +
      + + + + diff --git a/doc/html/_play_controller_8h_source.html b/doc/html/_play_controller_8h_source.html new file mode 100644 index 0000000..0c6e6e7 --- /dev/null +++ b/doc/html/_play_controller_8h_source.html @@ -0,0 +1,87 @@ + + + + + + + +Tallerify App Server: src/api/controllers/PlayController.h Source File + + + + + + + + + +
      +
      + + + + + + +
      +
      Tallerify App Server +
      +
      +
      + + + + + + + + +
      +
      + + +
      + +
      + + +
      +
      +
      +
      PlayController.h
      +
      +
      +Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H
      5 
      6 #include <regex>
      7 #include "Controller.h"
      8 #include "../networking/JSONResponse.h"
      9 
      13 class PlayController : public Controller {
      14 public:
      19 
      23  virtual ~PlayController();
      24 
      31  bool handles(std::string method, std::string url);
      32 
      38  Response *process(Request &request);
      39 
      45  void get(Request &request, JSONResponse &response);
      46 
      47 private:
      48  std::regex playRegex;
      49 };
      50 
      51 
      52 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_PLAYCONTROLLER_H
      Response * process(Request &request)
      Definition: PlayController.cpp:19
      +
      bool handles(std::string method, std::string url)
      Definition: PlayController.cpp:15
      +
      virtual ~PlayController()
      Definition: PlayController.cpp:11
      +
      Definition: PlayController.h:13
      + +
      Definition: Request.h:13
      +
      Definition: JSONResponse.h:13
      +
      PlayController()
      Definition: PlayController.cpp:6
      +
      Definition: Controller.h:14
      +
      Definition: Response.h:12
      +
      + + + + diff --git a/doc/html/_request_8h_source.html b/doc/html/_request_8h_source.html index 74e5371..0a4c59e 100644 --- a/doc/html/_request_8h_source.html +++ b/doc/html/_request_8h_source.html @@ -66,18 +66,24 @@
      Request.h
      -Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      5 
      6 
      7 #include <mongoose/mongoose.h>
      8 #include "Response.h"
      9 
      13 class Request {
      14 public:
      22  Request(mg_connection *connection, http_message *httpMessage);
      23 
      27  virtual ~Request();
      28 
      33  virtual void writeResponse(Response *response);
      34 
      39  virtual const std::string &getUrl() const;
      40 
      45  virtual const std::string &getBody() const;
      46 
      51  virtual const std::string &getHttpVerb() const;
      52 
      57  int getElementId() const;
      58 
      63  void setElementId(int elementId);
      64 
      69  void setUrl(const std::string &url);
      70 
      71 private:
      72  mg_connection *connection;
      73  std::string url;
      74  std::string body;
      75  std::string httpVerb;
      76  int elementId;
      77 private:
      78 
      79  void parseMessage(http_message *httpMessage);
      80 };
      81 
      82 
      83 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      int getElementId() const
      Definition: Request.cpp:47
      -
      virtual const std::string & getHttpVerb() const
      Definition: Request.cpp:43
      -
      void setElementId(int elementId)
      Definition: Request.cpp:51
      -
      void setUrl(const std::string &url)
      Definition: Request.cpp:55
      +Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      5 
      6 
      7 #include <mongoose/mongoose.h>
      8 #include "Response.h"
      9 
      13 class Request {
      14 public:
      22  Request(mg_connection *connection, http_message *httpMessage);
      23 
      30  Request(mg_connection *connection, int event, void *eventData);
      31 
      35  virtual ~Request();
      36 
      41  virtual void writeResponse(Response *response);
      42 
      47  virtual const std::string &getUrl() const;
      48 
      53  virtual const std::string &getBody() const;
      54 
      59  virtual const std::string &getHttpVerb() const;
      60 
      65  int getElementId() const;
      66 
      71  void setElementId(int elementId);
      72 
      77  void setUrl(const std::string &url);
      78 
      83  mg_connection *getConnection() const;
      84 
      89  http_message *getHttpMessage() const;
      90 
      95  const std::string &getElementIdString() const;
      96 
      101  void setElementIdString(const std::string &elementIdString);
      102 
      107  int getEvent() const;
      108 
      113  void *getEventData() const;
      114 
      115 
      116 private:
      117  mg_connection *connection;
      118  http_message *httpMessage;
      119  std::string url;
      120  std::string body;
      121  std::string httpVerb;
      122  int elementId;
      123  std::string elementIdString;
      124  int event;
      125  void *eventData;
      126 
      127  void parseMessage(http_message *httpMessage);
      128 };
      129 
      130 
      131 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_REQUEST_H
      int getElementId() const
      Definition: Request.cpp:50
      +
      virtual const std::string & getHttpVerb() const
      Definition: Request.cpp:46
      +
      void * getEventData() const
      Definition: Request.cpp:88
      +
      void setElementId(int elementId)
      Definition: Request.cpp:54
      +
      void setUrl(const std::string &url)
      Definition: Request.cpp:58
      +
      const std::string & getElementIdString() const
      Definition: Request.cpp:70
      Definition: Request.h:13
      -
      virtual void writeResponse(Response *response)
      Definition: Request.cpp:16
      -
      virtual const std::string & getBody() const
      Definition: Request.cpp:39
      -
      virtual const std::string & getUrl() const
      Definition: Request.cpp:35
      -
      Request(mg_connection *connection, http_message *httpMessage)
      Definition: Request.cpp:6
      +
      virtual void writeResponse(Response *response)
      Definition: Request.cpp:19
      +
      mg_connection * getConnection() const
      Definition: Request.cpp:62
      +
      virtual const std::string & getBody() const
      Definition: Request.cpp:42
      +
      int getEvent() const
      Definition: Request.cpp:84
      +
      virtual const std::string & getUrl() const
      Definition: Request.cpp:38
      +
      Request(mg_connection *connection, http_message *httpMessage)
      Definition: Request.cpp:7
      Definition: Response.h:12
      -
      virtual ~Request()
      Definition: Request.cpp:12
      +
      http_message * getHttpMessage() const
      Definition: Request.cpp:66
      +
      virtual ~Request()
      Definition: Request.cpp:15
      +
      void setElementIdString(const std::string &elementIdString)
      Definition: Request.cpp:74
      -Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      5 
      6 #include <vector>
      7 #include "mongoose/mongoose.h"
      8 #include "../controllers/Controller.h"
      9 
      15 class Server {
      17  friend class ServerTest;
      18 
      19 public:
      25  Server(int port = 8080, std::string ip = "127.0.0.1");
      26 
      30  virtual ~Server();
      31 
      35  void start();
      36 
      40  void stop();
      41 
      42 private:
      43  mg_mgr *server;
      44  mg_connection *connection;
      45  int port;
      46  std::string localIp;
      47  bool running;
      48  std::vector<Controller *> controllers;
      49 
      50  void handleRequest(mg_connection *connection, http_message *message);
      51 
      52  friend void event_handler(mg_connection *c, int ev, void *p);
      53 
      54  Response *handleRequest(Request &request);
      55 
      56  void registerController(Controller *controller);
      57 };
      58 
      59 
      60 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      Definition: Server.h:15
      -
      void start()
      Definition: Server.cpp:35
      -
      Server(int port=8080, std::string ip="127.0.0.1")
      Definition: Server.cpp:18
      +Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      5 
      6 #include <vector>
      7 #include "mongoose/mongoose.h"
      8 #include "../controllers/Controller.h"
      9 
      15 class Server {
      17  friend class ServerTest;
      18 
      19 public:
      25  Server(int port = 8080, std::string ip = "127.0.0.1");
      26 
      30  virtual ~Server();
      31 
      35  void start();
      36 
      40  void stop();
      41 
      42 private:
      43  mg_mgr *server;
      44  mg_connection *connection;
      45  int port;
      46  std::string localIp;
      47  bool running;
      48  std::vector<Controller *> controllers;
      49 
      50  void handleRequest(mg_connection *connection, http_message *message);
      51 
      52  //void handleRequest(mg_connection *connection, int event, void *event_data);
      53 
      54  friend void event_handler(mg_connection *new_connection, int event, void *event_data);
      55 
      56  Response *handleRequest(Request &request);
      57 
      58  void registerController(Controller *controller);
      59 
      60  void dispatchRequest(Request &request);
      61 
      62 };
      63 
      64 
      65 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_SERVER_H
      Definition: Server.h:15
      +
      void start()
      Definition: Server.cpp:57
      +
      Server(int port=8080, std::string ip="127.0.0.1")
      Definition: Server.cpp:38
      Definition: Request.h:13
      Definition: Controller.h:14
      friend class ServerTest
      Friend class for testing private methods.
      Definition: Server.h:17
      -
      void stop()
      Definition: Server.cpp:54
      +
      void stop()
      Definition: Server.cpp:76
      Definition: Response.h:12
      -
      virtual ~Server()
      Definition: Server.cpp:26
      +
      virtual ~Server()
      Definition: Server.cpp:48
      -Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      5 
      6 
      7 #include "Controller.h"
      8 #include "../networking/JSONResponse.h"
      9 #include <regex>
      10 
      14 class TracksController : public Controller {
      15 public:
      20 
      24  virtual ~TracksController();
      25 
      32  bool handles(std::string method, std::string url);
      33 
      39  Response *process(Request &request);
      40 
      46  void get(Request &request, JSONResponse &response);
      47 
      53  void post(Request &request, JSONResponse &response);
      54 
      55 private:
      56  std::regex tracksRegex;
      57 };
      58 
      59 
      60 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      virtual ~TracksController()
      Definition: TracksController.cpp:14
      -
      bool handles(std::string method, std::string url)
      Definition: TracksController.cpp:18
      -
      Response * process(Request &request)
      Definition: TracksController.cpp:26
      -
      void post(Request &request, JSONResponse &response)
      +Go to the documentation of this file.
      1 
      2 
      3 #ifndef FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      4 #define FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      5 
      6 
      7 #include "Controller.h"
      8 #include "../networking/JSONResponse.h"
      9 #include <regex>
      10 
      14 class TracksController : public Controller {
      15 public:
      20 
      24  virtual ~TracksController();
      25 
      32  bool handles(std::string method, std::string url);
      33 
      39  Response *process(Request &request);
      40 
      46  void get(Request &request, JSONResponse &response);
      47 
      53  void post(int trackId, const char* filename);
      54 
      59  void setFileName(const char *fileName);
      60 
      61  static struct mg_str upload_fname(struct mg_connection *c, struct mg_str file_name);
      62 
      63 
      64 private:
      65  std::regex tracksRegex;
      66  std::string fileName;
      67 };
      68 
      69 
      70 #endif //FIUBA_TALLER2_TALLERIFY_APP_SERVER_TRACKSCONTROLLER_H
      virtual ~TracksController()
      Definition: TracksController.cpp:22
      +
      bool handles(std::string method, std::string url)
      Definition: TracksController.cpp:26
      +
      Response * process(Request &request)
      Definition: TracksController.cpp:34
      Definition: Request.h:13
      Definition: JSONResponse.h:13
      Definition: Controller.h:14
      -
      TracksController()
      Definition: TracksController.cpp:8
      +
      TracksController()
      Definition: TracksController.cpp:15
      +
      void setFileName(const char *fileName)
      Definition: TracksController.cpp:70
      Definition: Response.h:12
      +
      void post(int trackId, const char *filename)
      Definition: TracksController.cpp:62
      Definition: TracksController.h:14
      diff --git a/doc/html/annotated.html b/doc/html/annotated.html index 84177d1..3aa5f69 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -68,11 +68,13 @@  CJSONResponse  CMongoDao  CPingController - CRequest - CResponse - CServer - CTrack - CTracksController + CPlayController + CRequest + CResponse + CreturnType + CServer + CTrack + CTracksController
      diff --git a/doc/html/class_controller-members.html b/doc/html/class_controller-members.html index 2d2b4cd..d615154 100644 --- a/doc/html/class_controller-members.html +++ b/doc/html/class_controller-members.html @@ -71,8 +71,9 @@ process(Request &request)Controllervirtual routes (defined in Controller)Controllerprotected serverInternalError(std::string message)Controller - urls (defined in Controller)Controllerprotected - ~Controller()Controllervirtual + setElementId(Request &request)Controllerprotected + urls (defined in Controller)Controllerprotected + ~Controller()Controllervirtual
  •  Request (mg_connection *connection, http_message *httpMessage)   + Request (mg_connection *connection, int event, void *eventData) +  virtual ~Request ()   virtual void writeResponse (Response *response) @@ -86,10 +88,22 @@   void setUrl (const std::string &url)   +mg_connection * getConnection () const +  +http_message * getHttpMessage () const +  +const std::string & getElementIdString () const +  +void setElementIdString (const std::string &elementIdString) +  +int getEvent () const +  +void * getEventData () const + 

    Constructor & Destructor Documentation

    -

    ◆ Request()

    +

    ◆ Request() [1/2]

    @@ -121,6 +135,48 @@

    +

    ◆ Request() [2/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Request::Request (mg_connection * connection,
    int event,
    void * eventData 
    )
    +
    +

    Request constructor for multipart requests

    Parameters
    + + + + +
    connection
    event
    eventData
    +
    +
    +
    @@ -174,6 +230,24 @@

    Request body getter

    Returns
    parsed body
    +

    +
    + +

    ◆ getConnection()

    + +
    +
    + + + + + + + +
    mg_connection * Request::getConnection () const
    +
    +

    Get the associated connection

    Returns
    the connection
    +
    @@ -192,6 +266,78 @@

    Get request's element id

    Returns
    element id
    + + +
    +

    ◆ getElementIdString()

    + +
    +
    + + + + + + + +
    const std::string & Request::getElementIdString () const
    +
    +

    Get the element id as string

    Returns
    element id as string
    + +
    +
    + +

    ◆ getEvent()

    + +
    +
    + + + + + + + +
    int Request::getEvent () const
    +
    +

    Event getter

    Returns
    the event code
    + +
    +
    + +

    ◆ getEventData()

    + +
    +
    + + + + + + + +
    void * Request::getEventData () const
    +
    +

    Event data getter

    Returns
    the event data as void*
    + +
    +
    + +

    ◆ getHttpMessage()

    + +
    +
    + + + + + + + +
    http_message * Request::getHttpMessage () const
    +
    +

    Get the original http message

    Returns
    the http message
    +
    @@ -268,6 +414,30 @@

    +

    ◆ setElementIdString()

    + +
    +
    + + + + + + + + +
    void Request::setElementIdString (const std::string & elementIdString)
    +
    +

    Set the elementId as a string

    Parameters
    + + +
    elementIdStringto set
    +
    +
    +
    diff --git a/doc/html/class_server.html b/doc/html/class_server.html index 093ae7f..66e3e80 100644 --- a/doc/html/class_server.html +++ b/doc/html/class_server.html @@ -84,9 +84,9 @@ class ServerTest  Friend class for testing private methods.
      - -void event_handler (mg_connection *c, int ev, void *p) -  + +void event_handler (mg_connection *new_connection, int event, void *event_data) + 

    Constructor & Destructor Documentation

    diff --git a/doc/html/class_tracks_controller-members.html b/doc/html/class_tracks_controller-members.html index cd686c1..146803d 100644 --- a/doc/html/class_tracks_controller-members.html +++ b/doc/html/class_tracks_controller-members.html @@ -69,14 +69,17 @@ Controller()Controller get(Request &request, JSONResponse &response)TracksController handles(std::string method, std::string url)TracksControllervirtual - post(Request &request, JSONResponse &response)TracksController + post(int trackId, const char *filename)TracksController process(Request &request)TracksControllervirtual routes (defined in Controller)Controllerprotected serverInternalError(std::string message)Controller + setElementId(Request &request)Controllerprotected + setFileName(const char *fileName)TracksController TracksController()TracksController - urls (defined in Controller)Controllerprotected - ~Controller()Controllervirtual - ~TracksController()TracksControllervirtual + upload_fname(struct mg_connection *c, struct mg_str file_name) (defined in TracksController)TracksControllerstatic + urls (defined in Controller)Controllerprotected + ~Controller()Controllervirtual + ~TracksController()TracksControllervirtual