Created
August 19, 2014 03:17
-
-
Save artur-kink/96fffe58ddb7e4b081f6 to your computer and use it in GitHub Desktop.
C++ Webserver using libmicrohttpd. A simple wrapper for libmicrohttpd to create websites using C++.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CONTROLLER_ | |
#define _CONTROLLER_ | |
#include <sstream> | |
/** | |
* Base controller for handling http requests. | |
*/ | |
class Controller{ | |
public: | |
/** | |
* Check if given path and method are handled by this controller. | |
*/ | |
virtual bool validPath(const char* path, const char* method) = 0; | |
/** | |
* Handles given request. | |
*/ | |
virtual int handleRequest(struct MHD_Connection* connection, | |
const char* url, const char* method, const char* upload_data, | |
size_t* upload_data_size) = 0; | |
}; | |
/** | |
* The dynamic controller is a controller for creating user defined pages. | |
*/ | |
class DynamicController:public Controller{ | |
public: | |
virtual bool validPath(const char* path, const char* method) = 0; | |
/** | |
* User defined http response. | |
*/ | |
virtual void createResponse(struct MHD_Connection* connection, | |
const char* url, const char* method, const char* upload_data, | |
size_t* upload_data_size, std::stringstream& response) = 0; | |
virtual int handleRequest(struct MHD_Connection* connection, | |
const char* url, const char* method, const char* upload_data, | |
size_t* upload_data_size){ | |
std::stringstream response_string; | |
createResponse(connection, url, method, upload_data, upload_data_size, response_string); | |
//Send response. | |
struct MHD_Response * response = MHD_create_response_from_buffer(strlen(response_string.str().c_str()), | |
(void*)response_string.str().c_str(), MHD_RESPMEM_MUST_COPY); | |
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
MHD_destroy_response(response); | |
return ret; | |
} | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "WebServer.hpp" | |
#include <time.h> | |
class MyController:public DynamicController{ | |
public: | |
virtual bool validPath(const char* path, const char* method){ | |
if(strcmp(path, "/") == 0 && strcmp("GET", method) == 0){ | |
return true; | |
} | |
return false; | |
} | |
virtual void createResponse(struct MHD_Connection * connection, | |
const char * url, const char * method, const char * upload_data, | |
size_t * upload_data_size, std::stringstream& response){ | |
time_t time_cur; | |
time(&time_cur); | |
struct tm* time_now = localtime(&time_cur); | |
response << "<html><head><title>Hello World from cpp</title></head><body>Hello World at " | |
<< time_now->tm_hour << ":" << time_now->tm_min << ":" << time_now->tm_sec << "!</body></html>"; | |
} | |
}; | |
int main(int argc, char** argv){ | |
MyController myPage; | |
WebServer server(8080); | |
server.addController(&myPage); | |
server.start(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "WebServer.hpp" | |
#include "Controller.hpp" | |
int WebServer::request_handler(void* cls, struct MHD_Connection* connection, | |
const char* url, const char* method, const char* version, | |
const char* upload_data, size_t* upload_data_size, void** ptr) { | |
std::cout << "Request: " << url << ", Method: " << method << std::endl; | |
WebServer* server = (WebServer*)cls; | |
Controller* controller = 0; | |
for(int i = 0; i < server->controllers.size(); i++){ | |
Controller* c = server->controllers.at(i); | |
if(c->validPath(url, method)){ | |
controller = c; | |
break; | |
} | |
} | |
if(!controller){ | |
std::cout << "Path not found.\n"; | |
struct MHD_Response* response = MHD_create_response_from_buffer(0, 0, MHD_RESPMEM_PERSISTENT); | |
return MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); | |
} | |
return controller->handleRequest(connection, url, method, upload_data, upload_data_size); | |
} | |
WebServer::WebServer(int p){ | |
port = p; | |
daemon = 0; | |
} | |
void WebServer::addController(Controller* controller){ | |
controllers.push_back(controller); | |
} | |
int WebServer::start(){ | |
daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, | |
8080, NULL, NULL, &request_handler, this, MHD_OPTION_END); | |
if(!daemon) | |
return 1; | |
while(1){ | |
sleep(10000); | |
} | |
MHD_stop_daemon(daemon); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _WEBSERVER_ | |
#define _WEBSERVER_ | |
#include <microhttpd.h> | |
#include <iostream> | |
#include <string.h> | |
#include <vector> | |
#include "Controller.hpp" | |
class WebServer{ | |
private: | |
int port; | |
struct MHD_Daemon* daemon; | |
/** List of controllers this server has. */ | |
std::vector<Controller*> controllers; | |
static int request_handler(void * cls, struct MHD_Connection * connection, | |
const char * url, const char * method, const char * version, | |
const char * upload_data, size_t * upload_data_size, void ** ptr); | |
public: | |
WebServer(int p); | |
void addController(Controller* controller); | |
int start(); | |
}; | |
#endif |
When I try to send a post request the upload_data comes empty. (upload_data_size = 0)
Could you please help me why is this happening? This is quite urgent request.
Thanks so much.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very useful, Thanks!