From aafef187ef856a36c3f8e599afea2dee44f08904 Mon Sep 17 00:00:00 2001 From: faketruth Date: Mon, 3 Oct 2011 19:25:04 +0000 Subject: Source for additional projects -jsoncpp -lua -tolua++ -WebServer -zlib -iniFile git-svn-id: http://mc-server.googlecode.com/svn/trunk@4 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- WebServer/WebServer.cpp | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 WebServer/WebServer.cpp (limited to 'WebServer/WebServer.cpp') diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp new file mode 100644 index 000000000..954791663 --- /dev/null +++ b/WebServer/WebServer.cpp @@ -0,0 +1,226 @@ +/* + WebServer.cpp + + Copyright (C) 2003-2007 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + + Thanks to Tom Lynn who pointed out an error in this source code. +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include + + +#include "WebServer.h" +#include "Socket.h" +#include "UrlHelper.h" +#include "base64.h" + +#include "cEvent.h" + + +webserver::request_func webserver::request_func_=0; + +#ifdef _WIN32 +unsigned webserver::Request(void* ptr_s) +#else +void* webserver::Request(void* ptr_s) +#endif +{ + Socket* s = (reinterpret_cast(ptr_s)); + + std::string line = s->ReceiveLine(); + if (line.empty()) { + s->Close(); + delete s; + return 0; + } + + http_request req; + + if (line.find("GET") == 0) { + req.method_="GET"; + } + else if (line.find("POST") == 0) { + req.method_="POST"; + } + + std::string path; + std::map params; + + size_t posStartPath = line.find_first_not_of(" ",3); + + SplitGetReq(line.substr(posStartPath), path, params); + + req.status_ = "202 OK"; + req.s_ = s; + req.path_ = path; + req.params_ = params; + + static const std::string authorization = "Authorization: Basic "; + static const std::string accept = "Accept: " ; + static const std::string accept_language = "Accept-Language: " ; + static const std::string accept_encoding = "Accept-Encoding: " ; + static const std::string user_agent = "User-Agent: " ; + + while(1) { + line=s->ReceiveLine(); + + if (line.empty()) break; + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; + + line = line.substr(0,pos_cr_lf); + + if (line.substr(0, authorization.size()) == authorization) { + req.authentication_given_ = true; + std::string encoded = line.substr(authorization.size()); + std::string decoded = base64_decode(encoded); + + unsigned int pos_colon = decoded.find(":"); + + req.username_ = decoded.substr(0, pos_colon); + req.password_ = decoded.substr(pos_colon+1 ); + } + else if (line.substr(0, accept.size()) == accept) { + req.accept_ = line.substr(accept.size()); + } + else if (line.substr(0, accept_language.size()) == accept_language) { + req.accept_language_ = line.substr(accept_language.size()); + } + else if (line.substr(0, accept_encoding.size()) == accept_encoding) { + req.accept_encoding_ = line.substr(accept_encoding.size()); + } + else if (line.substr(0, user_agent.size()) == user_agent) { + req.user_agent_ = line.substr(user_agent.size()); + } + } + + request_func_(&req); + + std::stringstream str_str; + str_str << req.answer_.size(); + + time_t ltime; + time(<ime); + tm* gmt= gmtime(<ime); + +#ifdef _WIN32 + static std::string const serverName = "MCServerWebAdmin (Windows)"; +#elif __APPLE__ + static std::string const serverName = "MCServerWebAdmin (MacOSX)"; +#else + static std::string const serverName = "MCServerWebAdmin (Linux)"; +#endif + + + char* asctime_remove_nl = std::asctime(gmt); + asctime_remove_nl[24] = 0; + + s->SendBytes("HTTP/1.1 "); + + if (! req.auth_realm_.empty() ) { + s->SendLine("401 Unauthorized"); + s->SendBytes("WWW-Authenticate: Basic Realm=\""); + s->SendBytes(req.auth_realm_); + s->SendLine("\""); + } + else { + s->SendLine(req.status_); + } + s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT"); + s->SendLine(std::string("Server: ") +serverName); + s->SendLine("Connection: close"); + s->SendLine("Content-Type: text/html; charset=ISO-8859-1"); + s->SendLine("Content-Length: " + str_str.str()); + s->SendLine(""); + s->SendLine(req.answer_); + + s->Close(); + delete s; + + + return 0; +} + +void webserver::Stop() +{ + m_bStop = true; + m_Socket->Close(); + m_Event->Wait(); +} + +void webserver::Begin() +{ + m_bStop = false; + while ( !m_bStop ) + { + Socket* ptr_s=m_Socket->Accept(); + if( m_bStop ) + { + if( ptr_s != 0 ) + { + ptr_s->Close(); + delete ptr_s; + } + break; + } + + // unused variable 'ret' + //_beginthreadex(0,0,Request,(void*) ptr_s,0,&ret); + // Thanks to Frank M. Hoffmann for fixing a HANDLE leak + #ifdef _WIN32 + unsigned ret; + HANDLE hHandle = reinterpret_cast(_beginthreadex(0,0,Request,(void*) ptr_s,0,&ret)); + CloseHandle(hHandle); + #else + pthread_t* hHandle = new pthread_t; + pthread_create( hHandle, NULL, Request, ptr_s); + #endif + } + m_Event->Set(); +} + +webserver::webserver(unsigned int port_to_listen, request_func r) { + m_Socket = new SocketServer(port_to_listen,1); + + request_func_ = r; + m_Event = new cEvent(); +} + +webserver::~webserver() +{ + delete m_Socket; + delete m_Event; +} -- cgit v1.2.3