diff --git a/.gitignore b/.gitignore index 378eac25d3..e7f8a12fa7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index f03cc00124..3f33dde989 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,9 @@ option (ENABLE_STATS option (ENABLE_REGEX_URL "Enable url regex matching dispatcher" OFF) + +option (ENABLE_SESSION_BOOST_ANY + "Enable session values with boost any" OFF) set (JSONCPP_DIR "${PROJECT_SOURCE_DIR}/../jsoncpp" CACHE STRING "Json C++ directory") @@ -40,9 +43,16 @@ endif (ENABLE_STATS) if (ENABLE_REGEX_URL) add_definitions("-DENABLE_REGEX_URL") - SET (CMAKE_CXX_FLAGS "-std=c++11") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif (ENABLE_REGEX_URL) +if (ENABLE_SESSION_BOOST_ANY) + find_package(Boost REQUIRED) + include_directories(${Boost_INCLUDE_DIRS}) + set (EXTRA_LIBS ${EXTRA_LIBS} ${Boost_LIBRARIES}) + add_definitions("-DENABLE_SESSION_BOOST_ANY") +endif (ENABLE_SESSION_BOOST_ANY) + if (CPP_BINDING) set (SOURCES ${SOURCES} @@ -84,9 +94,9 @@ if (NOT WEBSOCKET) add_definitions("-DNO_WEBSOCKET") endif (NOT WEBSOCKET) -# Adding dl +# Adding dl and pthread if (NOT WIN32) - set (EXTRA_LIBS ${EXTRA_LIBS} dl) + set (EXTRA_LIBS ${EXTRA_LIBS} dl pthread) endif (NOT WIN32) # Adding sockets for Win32 diff --git a/mongoose.c b/mongoose.c index 93721f9bc7..b1da4e3a01 100644 --- a/mongoose.c +++ b/mongoose.c @@ -51,7 +51,9 @@ #include // For _lseeki64 #include // For _mkdir typedef int socklen_t; -typedef HANDLE pid_t; +#ifndef __MINGW32__ + typedef HANDLE pid_t; +#endif typedef SOCKET sock_t; typedef unsigned char uint8_t; typedef unsigned int uint32_t; diff --git a/mongoose.h b/mongoose.h index 014eee1b30..ec1ed5dd22 100644 --- a/mongoose.h +++ b/mongoose.h @@ -100,6 +100,7 @@ void *mg_start_thread(void *(*func)(void *), void *param); char *mg_md5(char buf[33], ...); int mg_authorize_digest(struct mg_connection *c, FILE *fp); void mg_send_digest_auth_request(struct mg_connection *conn); +int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded); void mg_server_do_i_handle(struct mg_server *server, mg_handler_t handler); diff --git a/mongoose/Controller.cpp b/mongoose/Controller.cpp index 92a2c291d5..b1cd067ef4 100644 --- a/mongoose/Controller.cpp +++ b/mongoose/Controller.cpp @@ -109,16 +109,6 @@ namespace Mongoose } - Response *Controller::serverInternalError(string message) - { - StreamResponse *response = new StreamResponse; - - response->setCode(HTTP_SERVER_ERROR); - *response << "[500] Server internal error: " << message; - - return response; - } - vector Controller::getUrls() { return urls; diff --git a/mongoose/Controller.h b/mongoose/Controller.h index 9d2537dd23..d5a02430c0 100644 --- a/mongoose/Controller.h +++ b/mongoose/Controller.h @@ -117,15 +117,6 @@ namespace Mongoose */ void dumpRoutes(); - /** - * Called when an exception occur during the rendering - * - * @param string the error message - * - * @return response a response to send, 404 will occur if NULL - */ - virtual Response *serverInternalError(string message); - /** * Gets the session for a request/response * diff --git a/mongoose/Request.cpp b/mongoose/Request.cpp index 2c529e1404..b9b7b7e02c 100644 --- a/mongoose/Request.cpp +++ b/mongoose/Request.cpp @@ -3,6 +3,7 @@ #include #include #include "Request.h" +#include "Utils.h" using namespace std; @@ -153,16 +154,17 @@ namespace Mongoose return false; } - - map Request::getAllVariable() + + multimap Request::getAllVariable() { - map mapKeyValue; - stringstream ss(data); + multimap mapKeyValue; + stringstream ss(data + '&' + (connection->query_string ? connection->query_string:"")); //POST + GET string param; while(std::getline(ss, param, '&')){ //block for '&' - const string& key = param.substr(0, param.find('=')); - const string& value = param.substr(param.find('=')+1); - mapKeyValue[key] = value; // insert map + const size_t& delimitPos = param.find('='); + const string& key = param.substr(0, delimitPos); + const string& value = param.substr(delimitPos+1); + mapKeyValue.insert(make_pair(key, Utils::urlDecode(value) ) ); // insert map } return mapKeyValue; } @@ -210,6 +212,22 @@ namespace Mongoose return output; } + // Looking on the header + const char* referer = mg_get_header(this->connection, "Referer"); + if(referer){ + output = referer; + stringstream ss(output.substr(output.find('?')+1)); + string param; + while(std::getline(ss, param, '&')){ //block for '&' + const size_t& delimitPos = param.find('='); + const string& name = param.substr(0, delimitPos); + if(name == key){ + const string& value = param.substr(delimitPos+1); + return value; + } + } + } + return fallback; } diff --git a/mongoose/Request.h b/mongoose/Request.h index 622b141dec..902c307539 100644 --- a/mongoose/Request.h +++ b/mongoose/Request.h @@ -45,7 +45,7 @@ namespace Mongoose * @brief getAllVariable * @return map with all variables */ - map getAllVariable(); + multimap getAllVariable(); /** * Get the value for a certain variable diff --git a/mongoose/RequestHandler.h b/mongoose/RequestHandler.h index cad5f03a69..8c2089e9ce 100644 --- a/mongoose/RequestHandler.h +++ b/mongoose/RequestHandler.h @@ -24,6 +24,20 @@ namespace Mongoose { } + /** + * Called when an exception occur during the rendering + * + * @param string the error message + * + * @return response a response to send, 404 will occur if NULL + */ + virtual void serverInternalError(Request& request, Response& response, string message) + { + response.setCode(HTTP_SERVER_ERROR); + std::cerr << "Request: " << request.getUrl() << " Method: " << request.getMethod() << std::endl; + std::cerr << "[500] Server internal error: " << message; + } + Response *process(Request &request) { R *response = new R; @@ -32,9 +46,11 @@ namespace Mongoose controller->preProcess(request, *response); (controller->*function)(request, *response); } catch (string exception) { - return controller->serverInternalError(exception); + serverInternalError(request, *response, exception); + } catch (const std::exception& exception) { + serverInternalError(request, *response, exception.what()); } catch (...) { - return controller->serverInternalError("Unknown error"); + serverInternalError(request, *response, "Unknown error"); } return response; diff --git a/mongoose/Server.cpp b/mongoose/Server.cpp index 4dd0389708..11686b6901 100644 --- a/mongoose/Server.cpp +++ b/mongoose/Server.cpp @@ -1,10 +1,10 @@ #ifndef _MSC_VER -#include +# include #else -#include -#include -#include +# include +# include #endif +#include #include #include #include @@ -77,7 +77,7 @@ namespace Mongoose Server::Server(int port, const char *documentRoot) : stopped(false), - destroyed(false), + destroyed(true), server(NULL) #ifndef NO_WEBSOCKET ,websockets(NULL) @@ -256,6 +256,15 @@ namespace Mongoose optionsMap[key] = value; } + string Server::getOption(const string& key) + { + map::iterator it = optionsMap.find(key); + if (it != optionsMap.end()) + return it->second; + + return ""; + } + #ifndef NO_WEBSOCKET WebSockets &Server::getWebSockets() { diff --git a/mongoose/Server.h b/mongoose/Server.h index 82f876f4df..7f09c45fe9 100644 --- a/mongoose/Server.h +++ b/mongoose/Server.h @@ -102,6 +102,14 @@ namespace Mongoose */ void setOption(string key, string value); + /** + * Get a mongoose extra option + * + * @param string the name of the option + * @return string the value of the option + */ + string getOption(const string& key); + #ifndef NO_WEBSOCKET /** * Returns the WebSockets container diff --git a/mongoose/Session.cpp b/mongoose/Session.cpp index bf546f6352..d0621efd13 100644 --- a/mongoose/Session.cpp +++ b/mongoose/Session.cpp @@ -19,7 +19,7 @@ namespace Mongoose mutex.unlock(); } - void Session::setValue(string key, string value) + void Session::setValue(string key, Session::TypeValue value) { mutex.lock(); values[key] = value; @@ -38,11 +38,11 @@ namespace Mongoose return values.find(key) != values.end(); } - string Session::get(string key, string fallback) + Session::TypeValue Session::get(string key, Session::TypeValue fallback) { mutex.lock(); if (hasValue(key)) { - string value = values[key]; + TypeValue value = values[key]; mutex.unlock(); return value; @@ -56,4 +56,5 @@ namespace Mongoose { return time(NULL)-date; } + } diff --git a/mongoose/Session.h b/mongoose/Session.h index a1b830e727..a926f37e1a 100644 --- a/mongoose/Session.h +++ b/mongoose/Session.h @@ -3,9 +3,13 @@ #include #include "Mutex.h" +#ifdef ENABLE_SESSION_BOOST_ANY +# include +#endif using namespace std; + /** * A session contains the user specific values */ @@ -13,6 +17,11 @@ namespace Mongoose { class Session { +#ifdef ENABLE_SESSION_BOOST_ANY + typedef boost::any TypeValue; +#else + typedef std::string TypeValue; +#endif public: Session(); @@ -20,9 +29,9 @@ namespace Mongoose * Sets the value of a session variable * * @param string the name of the variable - * @param string the value of the variable + * @param Session::TypeValue the value of the variable */ - void setValue(string key, string value); + void setValue(string key, Session::TypeValue value); /** * Unset a session varaible @@ -42,11 +51,31 @@ namespace Mongoose * Try to get the value for the given variable * * @pram string the name of the variable - * @param string the fallback value + * @param Session::TypeValue the fallback value * - * @return string the value of the variable if it exists, fallback else + * @return Session::TypeValue the value of the variable if it exists, fallback else */ - string get(string key, string fallback = ""); + TypeValue get(string key, Session::TypeValue fallback = Session::TypeValue()); + +#ifdef ENABLE_SESSION_BOOST_ANY + /** + * Try to get the value for the given variable + * + * @pram string the name of the variable + * @param TypeValue the fallback value + * + * @return Type the value of the variable if it exists, fallback else + */ + template + Type get(const string& key, Type fallback = Type()) + { + TypeValue any = get(key); + if( ! any.empty() ) + return boost::any_cast(any); + else + return fallback; + } +#endif /** * Pings the session, this will update the creation date to now @@ -62,7 +91,7 @@ namespace Mongoose int getAge(); protected: - map values; + map values; int date; Mutex mutex; }; diff --git a/mongoose/Utils.cpp b/mongoose/Utils.cpp index d808e909e6..011abca497 100644 --- a/mongoose/Utils.cpp +++ b/mongoose/Utils.cpp @@ -1,10 +1,11 @@ #include #include +#include #include "Utils.h" -#ifndef WIN32 +#ifndef _MSC_VER #include #endif -#ifdef WIN32 +#ifdef _MSC_VER #include #endif @@ -33,10 +34,32 @@ namespace Mongoose void Utils::sleep(int ms) { -#ifdef WIN32 +#ifdef _MSC_VER Sleep(ms); #else usleep(1000 * ms); #endif } + + + string Utils::urlDecode(const string &SRC) { + string ret; + char ch; + int ii; + for (int i = 0; i(ii); + ret += ch; + i = i + 2; + } + else if (SRC[i] == '+'){ + ret += ' '; + } + else { + ret += SRC[i]; + } + } + return (ret); + } } diff --git a/mongoose/Utils.h b/mongoose/Utils.h index d8a36eca72..d9e8cd92ef 100644 --- a/mongoose/Utils.h +++ b/mongoose/Utils.h @@ -2,6 +2,7 @@ #define _MONGOOSE_UTILS_H #include +#include using namespace std; @@ -12,6 +13,7 @@ namespace Mongoose public: static string htmlEntities(string data); static void sleep(int ms); + static string urlDecode(const string &SRC); }; }