diff --git a/examples/embedded_cpp/embedded_cpp.cpp b/examples/embedded_cpp/embedded_cpp.cpp index 42b3d011..b3cc0c21 100644 --- a/examples/embedded_cpp/embedded_cpp.cpp +++ b/examples/embedded_cpp/embedded_cpp.cpp @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013-2014 the Civetweb developers * Copyright (c) 2013 No Face Press, LLC * License http://opensource.org/licenses/mit-license.php MIT License */ @@ -12,7 +12,7 @@ #endif #define DOCUMENT_ROOT "." -#define PORT "8888" +#define PORT "8081" #define EXAMPLE_URI "/example" #define EXIT_URI "/exit" bool exitNow = false; @@ -47,14 +47,27 @@ public: class AHandler: public CivetHandler { -public: - bool handleGet(CivetServer *server, struct mg_connection *conn) { +private: + bool handleAll(const char * method, CivetServer *server, struct mg_connection *conn) { + std::string s = ""; mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); mg_printf(conn, ""); - mg_printf(conn, "

This is the A handler!!!

"); + mg_printf(conn, "

This is the A handler for \"%s\" !

", method); + if (CivetServer::getParam(conn, "param", s)) { + mg_printf(conn, "

param set to %s

", s.c_str()); + } else { + mg_printf(conn, "

param not set

"); + } mg_printf(conn, "\n"); return true; } +public: + bool handleGet(CivetServer *server, struct mg_connection *conn) { + return handleAll("GET", server, conn); + } + bool handlePost(CivetServer *server, struct mg_connection *conn) { + return handleAll("POST", server, conn); + } }; class ABHandler: public CivetHandler diff --git a/include/CivetServer.h b/include/CivetServer.h index 4fe91af5..0b129bd9 100644 --- a/include/CivetServer.h +++ b/include/CivetServer.h @@ -1,5 +1,6 @@ -/* +/* Copyright (c) 2013-2014 the Civetweb developers * Copyright (c) 2013 No Face Press, LLC + * * License http://opensource.org/licenses/mit-license.php MIT License */ @@ -272,6 +273,7 @@ public: protected: struct mg_context *context; + char * postData; private: /** @@ -285,6 +287,20 @@ private: */ static int requestHandler(struct mg_connection *conn, void *cbdata); + /** + * closeHandler(struct mg_connection *) + * + * Handles closing a request (internal handler) + * + * @param conn - the connection information + */ + static void closeHandler(struct mg_connection *conn); + + /** + * Stores the user provided close handler + */ + void (*userCloseHandler)(struct mg_connection *conn); + }; #endif /* __cplusplus */ diff --git a/src/CivetServer.cpp b/src/CivetServer.cpp index 70a414da..753cc5fd 100644 --- a/src/CivetServer.cpp +++ b/src/CivetServer.cpp @@ -1,5 +1,6 @@ -/* +/* Copyright (c) 2013-2014 the Civetweb developers * Copyright (c) 2013 No Face Press, LLC + * * License http://opensource.org/licenses/mit-license.php MIT License */ @@ -44,7 +45,10 @@ bool CivetHandler::handleDelete(CivetServer *server, struct mg_connection *conn) int CivetServer::requestHandler(struct mg_connection *conn, void *cbdata) { struct mg_request_info *request_info = mg_get_request_info(conn); + assert(request_info != NULL); CivetServer *me = (CivetServer*) (request_info->user_data); + assert(me != NULL); + CivetHandler *handler = (CivetHandler *)cbdata; if (handler) { @@ -60,22 +64,23 @@ int CivetServer::requestHandler(struct mg_connection *conn, void *cbdata) } return 0; // No handler found - } CivetServer::CivetServer(const char **options, const struct mg_callbacks *_callbacks) : - context(0) + context(0), postData(0) { - - + struct mg_callbacks callbacks; + memset(&callbacks, 0, sizeof(callbacks)); if (_callbacks) { - context = mg_start(_callbacks, this, options); + callbacks = *_callbacks; + userCloseHandler = _callbacks->connection_close; } else { - struct mg_callbacks callbacks; - memset(&callbacks, 0, sizeof(callbacks)); - context = mg_start(&callbacks, this, options); + userCloseHandler = NULL; } + callbacks.connection_close = closeHandler; + + context = mg_start(&callbacks, this, options); } CivetServer::~CivetServer() @@ -83,6 +88,20 @@ CivetServer::~CivetServer() close(); } +void CivetServer::closeHandler(struct mg_connection *conn) +{ + struct mg_request_info *request_info = mg_get_request_info(conn); + assert(request_info != NULL); + CivetServer *me = (CivetServer*) (request_info->user_data); + assert(me != NULL); + + if (me->userCloseHandler) me->userCloseHandler(conn); + if (me->postData) { + delete [] (me->postData); + me->postData = 0; + } +} + void CivetServer::addHandler(const std::string &uri, CivetHandler *handler) { mg_set_request_handler(context, uri.c_str(), requestHandler, handler); @@ -151,14 +170,33 @@ CivetServer::getParam(struct mg_connection *conn, const char *name, std::string &dst, size_t occurrence) { const char *formParams = NULL; - mg_request_info * ri = mg_get_request_info(conn); + struct mg_request_info *ri = mg_get_request_info(conn); + assert(ri != NULL); + CivetServer *me = (CivetServer*) (ri->user_data); + assert(me != NULL); - if (ri) { + if (me->postData != NULL) { + formParams = me->postData; + } else { + const char * con_len_str = mg_get_header(conn, "Content-Length"); + if (con_len_str) { + unsigned long con_len = atoi(con_len_str); + if (con_len>0) { + me->postData = new char[con_len]; + if (me->postData != NULL) { + /* NULL check is not required according to current C++ standard */ + mg_read(conn, me->postData, con_len); + formParams = me->postData; + } + } + } + } + if (formParams == NULL) { // get requests do store html
field values in the http query_string formParams = ri->query_string; } - if (formParams) { + if (formParams != NULL) { return getParam(formParams, strlen(formParams), name, dst, occurrence); }