diff options
Diffstat (limited to 'WebServer')
-rw-r--r-- | WebServer/Events.cpp | 125 | ||||
-rw-r--r-- | WebServer/Events.h | 18 | ||||
-rw-r--r-- | WebServer/Globals.cpp | 10 | ||||
-rw-r--r-- | WebServer/Globals.h | 15 | ||||
-rw-r--r-- | WebServer/Socket.cpp | 376 | ||||
-rw-r--r-- | WebServer/Socket.h | 127 | ||||
-rw-r--r-- | WebServer/StdHelpers.cpp | 62 | ||||
-rw-r--r-- | WebServer/StdHelpers.h | 65 | ||||
-rw-r--r-- | WebServer/Tracer.h | 113 | ||||
-rw-r--r-- | WebServer/UrlHelper.cpp | 169 | ||||
-rw-r--r-- | WebServer/UrlHelper.h | 42 | ||||
-rw-r--r-- | WebServer/WebServer.cpp | 498 | ||||
-rw-r--r-- | WebServer/WebServer.h | 108 | ||||
-rw-r--r-- | WebServer/base64.cpp | 102 | ||||
-rw-r--r-- | WebServer/base64.h | 4 |
15 files changed, 0 insertions, 1834 deletions
diff --git a/WebServer/Events.cpp b/WebServer/Events.cpp deleted file mode 100644 index 30eb731f9..000000000 --- a/WebServer/Events.cpp +++ /dev/null @@ -1,125 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Events.h" - - - - - -cEvents::cEvents( unsigned int a_NumEvents /* = 1 */ ) - : m_NumEvents( a_NumEvents ) -#ifndef _WIN32 - , m_bNamed( false ) -#endif -{ - if( m_NumEvents < 1 ) m_NumEvents = 1; - -#ifdef _WIN32 - m_Handle = new HANDLE[ m_NumEvents ]; - for( unsigned int i = 0; i < m_NumEvents; i++) - { - ((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 ); - } -#else - m_Handle = new sem_t*[ m_NumEvents ]; - for( unsigned int i = 0; i < m_NumEvents; i++) - { - - sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; - HandlePtr = new sem_t; - - if( sem_init( HandlePtr, 0, 0 ) ) - { - LOG("WARNING cEvents: Could not create unnamed semaphore, fallback to named."); - m_bNamed = true; - delete HandlePtr; // named semaphores return their own address - - char c_Str[32]; - sprintf( c_Str, "cEvents%p", &HandlePtr ); - HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 ); - if( HandlePtr == SEM_FAILED ) - LOG("ERROR: Could not create Event. (%i)", errno); - else - if( sem_unlink( c_Str ) != 0 ) - LOG("ERROR: Could not unlink cEvents. (%i)", errno); - } - } -#endif -} - - - - - -cEvents::~cEvents() -{ -#ifdef _WIN32 - for( unsigned int i = 0; i < m_NumEvents; i++ ) - { - CloseHandle( ((HANDLE*)m_Handle)[i] ); - } - delete [] (HANDLE*)m_Handle; -#else - for( unsigned int i = 0; i < m_NumEvents; i++ ) - { - if( m_bNamed ) - { - sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; - char c_Str[32]; - sprintf( c_Str, "cEvents%p", &HandlePtr ); - // LOG("Closing event: %s", c_Str ); - // LOG("Sem ptr: %p", HandlePtr ); - if( sem_close( HandlePtr ) != 0 ) - { - LOG("ERROR: Could not close cEvents. (%i)", errno); - } - } - else - { - sem_destroy( ((sem_t**)m_Handle)[i] ); - delete ((sem_t**)m_Handle)[i]; - } - } - delete [] (sem_t**)m_Handle; m_Handle = 0; -#endif -} - - - - - -void cEvents::Wait() -{ -#ifdef _WIN32 - WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE ); -#else - for(unsigned int i = 0; i < m_NumEvents; i++) - { - if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 ) - { - LOG("ERROR: Could not wait for cEvents. (%i)", errno); - } - } -#endif -} - - - - - -void cEvents::Set(unsigned int a_EventNum /* = 0 */) -{ -#ifdef _WIN32 - SetEvent( ((HANDLE*)m_Handle)[a_EventNum] ); -#else - if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 ) - { - LOG("ERROR: Could not set cEvents. (%i)", errno); - } -#endif -} - - - - diff --git a/WebServer/Events.h b/WebServer/Events.h deleted file mode 100644 index 352dc4056..000000000 --- a/WebServer/Events.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -class cEvents -{ -public: - cEvents( unsigned int a_NumEvents = 1 ); - ~cEvents(); - - void Wait(); - void Set(unsigned int a_EventNum = 0); -private: - unsigned int m_NumEvents; - void* m_Handle; // HANDLE[] pointer - -#ifndef _WIN32 - bool m_bNamed; -#endif -}; diff --git a/WebServer/Globals.cpp b/WebServer/Globals.cpp deleted file mode 100644 index 13c6ae709..000000000 --- a/WebServer/Globals.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -// Globals.cpp - -// This file is used for precompiled header generation in MSVC environments - -#include "Globals.h" - - - - diff --git a/WebServer/Globals.h b/WebServer/Globals.h deleted file mode 100644 index d60f34720..000000000 --- a/WebServer/Globals.h +++ /dev/null @@ -1,15 +0,0 @@ - -// Globals.h - -// This file gets included from every module in the project, so that global symbols may be introduced easily -// Also used for precompiled header generation in MSVC environments - - - - - -#include "../source/Globals.h" - - - - diff --git a/WebServer/Socket.cpp b/WebServer/Socket.cpp deleted file mode 100644 index 82c76a8f1..000000000 --- a/WebServer/Socket.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - Socket.cpp - - Copyright (C) 2002-2004 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Socket.h" -#include <iostream> - -#ifndef _WIN32 - #include <cstring> - #include <sys/time.h> - #include <unistd.h> - #define SD_SEND 0x01 -#else - #define MSG_NOSIGNAL (0) -#endif - -#ifdef __MAC_NA - #define MSG_NOSIGNAL (0) -#endif - -#ifndef MSG_NOSIGNAL - #define MSG_NOSIGNAL 0 -#endif // MSG_NOSIGNAL - -using namespace std; - -int Socket::nofSockets_= 0; - - - - - -void Socket::Start() -{ - #ifdef _WIN32 - if (!nofSockets_) - { - WSADATA info; - if (WSAStartup(MAKEWORD(2,0), &info)) - { - throw "Could not start WSA"; - } - } - #endif - ++nofSockets_; -} - - - - - -void Socket::End() -{ -#ifdef _WIN32 - WSACleanup(); -#endif -} - - - - - -Socket::Socket() : - s_(INVALID_SOCKET) -{ - Start(); - // UDP: use SOCK_DGRAM instead of SOCK_STREAM - s_ = socket(AF_INET,SOCK_STREAM,0); - - if (!IsValid()) - { -#if !defined(ANDROID_NDK) - throw "INVALID_SOCKET"; -#endif - } - - refCounter_ = new int(1); -} - - - - - -Socket::Socket(SOCKET s) : s_(s) -{ - Start(); - refCounter_ = new int(1); -}; - - - - - -Socket::~Socket() -{ - if (! --(*refCounter_)) - { - Close(); - delete refCounter_; - } - - --nofSockets_; - if (!nofSockets_) - { - End(); - } -} - - - - - -Socket::Socket(const Socket& o) -{ - refCounter_=o.refCounter_; - (*refCounter_)++; - s_ =o.s_; - - nofSockets_++; -} - - - - - -Socket& Socket::operator=(Socket& o) -{ - (*o.refCounter_)++; - - refCounter_ = o.refCounter_; - s_ = o.s_; - - nofSockets_++; - - return *this; -} - - - - - -bool Socket::IsValid(void) const -{ - #ifdef _WIN32 - return (s_ != INVALID_SOCKET); - #else - return (s_ >= 0); - #endif -} - - - - - -void Socket::Close( bool a_WaitSend /* = false */ ) -{ - if (IsValid()) - { - if (a_WaitSend) - { - assert( shutdown(s_, SD_SEND ) == 0 ); - char c; - while( recv(s_, &c, 1, 0 ) > 0 ) - {} - } - - #ifndef _WIN32 - // Linux needs to shut the socket down first, otherwise the socket keeps blocking accept() and select() calls! - // Ref.: http://forum.mc-server.org/showthread.php?tid=344 - if (shutdown(s_, SHUT_RDWR) != 0) - { - LOGWARN("Error on shutting down socket %d", s_); - } - #endif // _WIN32 - - closesocket(s_); - - s_ = INVALID_SOCKET; - } -} - - - - - -std::string Socket::ReceiveLine() -{ - std::string ret; - while (1) - { - char r; - - if (recv(s_, &r, 1, 0) <= 0 ) - { - return ""; - } - ret += r; - if (r == '\n') return ret; - } -} - - - - - -std::string Socket::ReceiveBytes( unsigned int a_Length ) -{ - std::string ret; - while( ret.size() < a_Length ) - { - char r; - - if (recv(s_, &r, 1, 0) <= 0 ) - { - return ""; - } - ret += r; - } - return ret; -} - - - - - -void Socket::SendLine(std::string s) -{ - s += '\n'; - if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 ) - { - //printf("SendLine Socket error!! \n" ); - Close(); - } -} - - - - - -void Socket::SendBytes(const std::string& s) -{ - if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 ) - { - //printf("SendBytes Socket error!! \n" ); - Close(); - } -} - - - - - -SocketServer::SocketServer(int port, int connections, TypeSocket type) -{ - sockaddr_in sa; - - memset(&sa, 0, sizeof(sa)); - - sa.sin_family = PF_INET; - sa.sin_port = htons(port); - s_ = socket(AF_INET, SOCK_STREAM, 0); - - if (!IsValid()) - { - LOG("WebServer: INVALID_SOCKET"); - } - - if(type==NonBlockingSocket) - { - return; - } - - #ifdef _WIN32 - char yes = 1; - #else - int yes = 1; - #endif - - if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) - { - LOG("WebServer: setsockopt == -1"); - return; - } - - /* bind the socket to the internet address */ - if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) - { - closesocket(s_); - LOG("WebServer: INVALID_SOCKET"); - } - - listen(s_, connections); -} - - - - - -Socket* SocketServer::Accept() -{ - Socket * r = new Socket(accept(s_, 0, 0)); - if (!r->IsValid()) - { - delete r; - r = NULL; - } - - return r; -} - - - - - -SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) -{ - FD_ZERO(&fds_); - SOCKET Highest = s1->s_; - FD_SET(const_cast<Socket*>(s1)->s_,&fds_); - if(s2) - { - FD_SET(const_cast<Socket*>(s2)->s_,&fds_); - if (s2->s_ > Highest) - { - Highest = s2->s_; - } - } - if (select(Highest + 1, &fds_, NULL, NULL, NULL) == SOCKET_ERROR) - { -#if !defined(ANDROID_NDK) - throw "Error in select"; -#endif - } -} - - - - - -bool SocketSelect::Readable(Socket const* const s) -{ - return (FD_ISSET(s->s_,&fds_) != 0); -} - - - - diff --git a/WebServer/Socket.h b/WebServer/Socket.h deleted file mode 100644 index b144659c7..000000000 --- a/WebServer/Socket.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - Socket.h - - Copyright (C) 2002-2004 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#ifndef SOCKET_H -#define SOCKET_H - - - - - -#ifndef _WIN32 - typedef int SOCKET; - #define SOCKET_ERROR (-1) - #define INVALID_SOCKET (-1) - #define closesocket close -#endif // !_WIN32 - - - - - -enum TypeSocket {BlockingSocket, NonBlockingSocket}; - - - - - -class Socket -{ -public: - - virtual ~Socket(); - Socket(const Socket&); - Socket& operator=(Socket&); - - std::string ReceiveLine(); - std::string ReceiveBytes( unsigned int a_Length ); - - bool IsValid(void) const; - - void Close( bool a_WaitSend = false ); - - // The parameter of SendLine is not a const reference - // because SendLine modifes the std::string passed. - void SendLine (std::string); - - // The parameter of SendBytes is a const reference - // because SendBytes does not modify the std::string passed - // (in contrast to SendLine). - void SendBytes(const std::string&); - -protected: - friend class SocketServer; - friend class SocketSelect; - - Socket(SOCKET s); - Socket(); - - - SOCKET s_; - - int* refCounter_; - -private: - static void Start(); - static void End(); - static int nofSockets_; -}; - - - - - -class SocketServer : - public Socket -{ -public: - SocketServer(int port, int connections, TypeSocket type=BlockingSocket); - - Socket* Accept(); -}; - - - - - -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wsapiref_2tiq.asp -class SocketSelect -{ -public: - SocketSelect(Socket const * const s1, Socket const * const s2=NULL, TypeSocket type=BlockingSocket); - - bool Readable(Socket const * const s); - -private: - fd_set fds_; -}; - -#endif diff --git a/WebServer/StdHelpers.cpp b/WebServer/StdHelpers.cpp deleted file mode 100644 index 63e48a7d2..000000000 --- a/WebServer/StdHelpers.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - stdHelpers.cpp - - Copyright (C) 2002-2004 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "StdHelpers.h" -#include <cctype> - -std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) { - std::string ret = in; - - std::string::size_type pos = ret.find(search_for); - - while (pos != std::string::npos) { - ret = ret.replace(pos, search_for.size(), replace_with); - pos = pos - search_for.size() + replace_with.size() + 1; - pos = ret.find(search_for, pos); - } - - return ret; -} - -// std:toupper and std::tolower are overloaded. Well... -// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html -char toLower_ (char c) { return std::tolower(c); } -char toUpper_ (char c) { return std::toupper(c); } - -void ToUpper(std::string& s) { - std::transform(s.begin(), s.end(), s.begin(),toUpper_); -} - -void ToLower(std::string& s) { - std::transform(s.begin(), s.end(), s.begin(),toLower_); -} diff --git a/WebServer/StdHelpers.h b/WebServer/StdHelpers.h deleted file mode 100644 index 1011881f8..000000000 --- a/WebServer/StdHelpers.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - stdHelpers.h - - Copyright (C) 2002-2005 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#ifndef STDHELPERS_H__ -#define STDHELPERS_H__ - -#include <string> -#include <sstream> - -std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with); - -void ToUpper(std::string& s); -void ToLower(std::string& s); - -template <class T> -T To(std::string const& s) { - T ret; - - std::stringstream stream; - stream << s; - stream >> ret; - - return ret; -} - -template<class T> -std::string StringFrom(T const& t) { - std::string ret; - - std::stringstream stream; - stream << t; - stream >> ret; - - return ret; -} - -#endif
\ No newline at end of file diff --git a/WebServer/Tracer.h b/WebServer/Tracer.h deleted file mode 100644 index c13d5128f..000000000 --- a/WebServer/Tracer.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - Tracer.h - - Copyright (C) 2002-2004 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. - - The most current version of Tracer.h can be found at - http://www.adp-gmbh.ch/cpp/common/Tracer.html - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#ifndef TRACER_H__ -#define TRACER_H__ - -#ifdef DO_TRACE - -#include <string> -#include <sstream> - -#include <windows.h> - -#define StartTrace(x) TraceFunc_::StartTrace_(x) -#define Trace(x) dummy_____for_trace_func______.Trace_(x) -#define Trace2(x,y) dummy_____for_trace_func______.Trace_(x,y) -#define TraceFunc(x) TraceFunc_ dummy_____for_trace_func______(x) -#define TraceFunc2(x,y) TraceFunc_ dummy_____for_trace_func______(x,y) - -class TraceFunc_ { - std::string func_name_; - public: - /* - Calling TraceFunc_ indents the output until the enclosing scope ( {...} ) - is left. - */ - TraceFunc_(std::string const&); - TraceFunc_(std::string const&, std::string const& something); - ~TraceFunc_(); - - /* - Creates the trace output file named by filename. - Must be called before any other tracing function. - Use the StartTrace macro for it. - */ - static void StartTrace_(std::string const& filename); - - template <class T> - void Trace_(T const& t) { - DWORD d; - std::string indent_s; - std::stringstream s; - - s << t; - - for (int i=0; i< indent; i++) indent_s += " "; - - ::WriteFile(trace_file_,indent_s.c_str(), indent_s.size(), &d, 0); - ::WriteFile(trace_file_, s.str().c_str(), s.str().size() ,&d, 0); - ::WriteFile(trace_file_,"\x0a",1,&d,0); - } - - template <class T, class U> - void Trace_(T const& t, U const& u) { - std::string indent_s; - std::stringstream s; - - s << t; - s << u; - Trace_(s.str()); - } - - static int indent; - /* trace_file_ is a HANDLE for the file in which the traced output goes. - The file is opened (that is, created) by calling StartTrace_. - Better yet, use the StartTrace macro - to create the file. - */ - static HANDLE trace_file_; -}; - -#else - -#define StartTrace(x) -#define Trace(x) -#define Trace2(x,y) -#define TraceFunc(x) -#define TraceFunc2(x,y) - -#endif - -#endif // TRACER_H__ diff --git a/WebServer/UrlHelper.cpp b/WebServer/UrlHelper.cpp deleted file mode 100644 index 3ed5660b0..000000000 --- a/WebServer/UrlHelper.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - UrlHelper.cpp - - Copyright (C) 2002-2004 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "UrlHelper.h" -#include "Tracer.h" -#include "StdHelpers.h" - -#include <sstream> -#include <iostream> - -bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) { - TraceFunc("RemoveProtocolFromUrl"); - Trace(std::string("url='")+url+"'"); - std::string::size_type pos_colon = url.find(":"); - - if (pos_colon == std::string::npos) { - rest = url; - return false; - } - - if (url.size() < pos_colon + 2) { - rest = url; - return false; - } - - if (url[pos_colon+1] != '/' || - url[pos_colon+2] != '/') { - rest = url; - return false; - } - - protocol = url.substr(0,pos_colon); - rest = url.substr(3+pos_colon); // Skipping three characters ( '://' ) - - return true; -} - -void SplitGetReq(std::string get_req, std::string& path, std::map<std::string, std::string>& params) { - TraceFunc("SplitGetReq"); - - // Remove trailing newlines - if (get_req[get_req.size()-1] == '\x0d' || - get_req[get_req.size()-1] == '\x0a') - get_req=get_req.substr(0, get_req.size()-1); - - if (get_req[get_req.size()-1] == '\x0d' || - get_req[get_req.size()-1] == '\x0a') - get_req=get_req.substr(0, get_req.size()-1); - - // Remove potential Trailing HTTP/1.x - if (get_req.size() > 7) { - if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") { - get_req=get_req.substr(0, get_req.size()-9); - } - } - - std::string::size_type qm = get_req.find("?"); - if (qm != std::string::npos) { - std::string url_params = get_req.substr(qm+1); - - path = get_req.substr(0, qm); - - // Appending a '&' so that there are as many '&' as name-value pairs. - // It makes it easier to split the url for name value pairs, he he he - url_params += "&"; - - std::string::size_type next_amp = url_params.find("&"); - - while (next_amp != std::string::npos) { - std::string name_value = url_params.substr(0,next_amp); - url_params = url_params.substr(next_amp+1); - next_amp = url_params.find("&"); - - std::string::size_type pos_equal = name_value.find("="); - - std::string nam = name_value.substr(0,pos_equal); - std::string val = name_value.substr(pos_equal+1); - - std::string::size_type pos_plus; - while ( (pos_plus = val.find("+")) != std::string::npos ) { - val.replace(pos_plus, 1, " "); - } - - while ( (pos_plus = val.find("%20")) != std::string::npos ) { - val.replace(pos_plus, 3, " "); - } - - // Replacing %xy notation - std::string::size_type pos_hex = 0; - while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) { - std::stringstream h; - h << val.substr(pos_hex+1, 2); - h << std::hex; - - int i; - h>>i; - - std::stringstream f; - f << static_cast<char>(i); - std::string s; - f >> s; - - val.replace(pos_hex, 3, s); - pos_hex ++; - } - - params.insert(std::map<std::string,std::string>::value_type(nam, val)); - } - } - else { - path = get_req; - } -} - -void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) { - TraceFunc("SplitUrl"); - RemoveProtocolFromUrl(url, protocol, server); - - if (protocol == "http") { - std::string::size_type pos_slash = server.find("/"); - - if (pos_slash != std::string::npos) { - Trace("slash found"); - path = server.substr(pos_slash); - server = server.substr(0, pos_slash); - } - else { - Trace("slash not found"); - path = "/"; - } - } - else if (protocol == "file") { - path = ReplaceInStr(server, "\\", "/"); - server = ""; - } - else { - std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl; - } -} diff --git a/WebServer/UrlHelper.h b/WebServer/UrlHelper.h deleted file mode 100644 index 12f12c6fe..000000000 --- a/WebServer/UrlHelper.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - UrlHelper.h - - Copyright (C) 2002-2004 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 -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ -#ifndef __URL_HELPER_H__ -#define __URL_HELPER_H__ - -#include <string> -#include <map> - -void SplitUrl (std::string const& url, std::string& protocol, std::string& server, std::string& path); -bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest); - -void SplitGetReq (std::string et_req, std::string& path, std::map<std::string, std::string>& params); - -#endif diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp deleted file mode 100644 index eb9a09049..000000000 --- a/WebServer/WebServer.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/* - 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 "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include <ctime> -#ifdef _WIN32 - #include <process.h> -#endif -#include <iostream> -#include <sstream> - - -#include "WebServer.h" -#include "Events.h" -#include "Socket.h" -#include "UrlHelper.h" -#include "base64.h" - - - - - -webserver::request_func webserver::request_func_ = NULL; - - - - - -static std::string EatLine( std::string& a_String ) -{ - std::string RetVal = ""; - unsigned int StringSize = a_String.size(); - const char* c = a_String.c_str(); - - for( unsigned int i = 0; i < StringSize; ++i, ++c) - { - if( *c == '\n' ) - { - RetVal += *c; -// ++i; ++c; -// if( i < StringSize ) -// { -// if( *c == '\r' ) -// { -// RetVal += *c; -// } -// } - break; - } - RetVal += *c; - } - a_String = a_String.substr( RetVal.size() ); - return RetVal; -} - - - - - -// Turns -// "blabla my string with \"quotes\"!" -// into -// blabla my string with "quotes"! -static std::string GetQuotedString( const std::string& a_String ) -{ - std::string RetVal; - - bool bGotFirstQuote = false; - bool bIgnoreNext = false; - unsigned int StrLen = a_String.size(); - for( unsigned int i = 0; i < StrLen; ++i ) - { - if( bIgnoreNext == false ) - { - if( a_String[i] == '\"' ) - { - if( bGotFirstQuote == false ) - { - bGotFirstQuote = true; - } - else - { - break; - } - continue; - } - else if( a_String[i] == '\\' ) // Escape character - { - bIgnoreNext = true; - continue; - } - } - RetVal.push_back( a_String[i] ); - bIgnoreNext = false; - } - - return RetVal; -} - - - - - -void ParseMultipartFormData( webserver::http_request& req, Socket* s) -{ - static const std::string multipart_form_data = "multipart/form-data"; - if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :( - { - AStringVector ContentTypeData = StringSplit( req.content_type_, "; " ); - - std::string boundary; - // Find boundary - for( unsigned int i = 0; i < ContentTypeData.size(); ++i ) - { - static const std::string boundary_ = "boundary="; - if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary - { - boundary = ContentTypeData[i].substr( boundary_.size() ); - } - } - - //LOGINFO("Boundary: %s", boundary.c_str() ); - std::string boundary_start = "--" + boundary; - std::string boundary_end = boundary_start + "--"; - - std::string Content = s->ReceiveBytes( req.content_length_ ); - - //printf("Total content: \n%s\n", Content.c_str() ); - - // Should start with boundary! - std::string line = EatLine( Content ); - if( line.substr(0, boundary_start.size() ) != boundary_start ) - { - // Something was wrong! :( - Content.clear(); - } - - while( !Content.empty() ) - { - webserver::formdata FormData; - - static const std::string content_disposition = "Content-Disposition: "; - static const std::string content_type = "Content-Type: "; - - std::string f_disposition; - - while( 1 ) - { - std::string line = EatLine( Content ); - if( line.empty() ) - break; - - unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); - if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy - - if( line.substr(0, content_disposition.size() ) == content_disposition ) - { - f_disposition = line.substr(content_disposition.size()); - LOGINFO("Disposition: %s", f_disposition.c_str() ); - } - else if( line.substr(0, content_type.size() ) == content_type ) - { - FormData.content_type_ = line.substr(content_type.size()); - } - - //LOGINFO("Got line: '%s'", line.c_str() ); - } - - // Check if we got the proper headers - if( !f_disposition.empty() ) - { - static const std::string disp_name = "name="; - static const std::string disp_filename = "filename="; - - // Parse the disposition - AStringVector DispositionData = StringSplit( f_disposition, "; " ); - for( unsigned int i = 0; i < DispositionData.size(); ++i ) - { - if( DispositionData[i].substr(0, disp_name.size()) == disp_name ) - { - FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) ); - } - else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename ) - { - FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) ); - } - } - - std::string ContentValue; - // Parse until boundary_end is found - while( 1 ) - { - std::string line = EatLine( Content ); - if( line.empty() ) - break; - - if( line.substr(0, boundary_end.size() ) == boundary_end ) - { - break; - } - else if( line.substr(0, boundary_start.size() ) == boundary_start ) - { - break; - } - ContentValue.append( line.c_str(), line.size() ); - } - - - FormData.value_ = ContentValue; - } - - req.multipart_formdata_.push_back( FormData ); - } - } -} - - - - - -#ifdef _WIN32 -unsigned webserver::Request(void* ptr_s) -#else -void* webserver::Request(void* ptr_s) -#endif -{ - Socket* s = (reinterpret_cast<Socket*>(ptr_s)); - - std::string line = s->ReceiveLine(); - if (line.empty()) - { - s->Close(); - delete s; - return 0; - } - - http_request req; - std::string path; - std::map<std::string, std::string> params; - size_t posStartPath = 0; - - if (line.find("GET") == 0) - { - req.method_="GET"; - posStartPath = line.find_first_not_of(" ",3); - } - else if (line.find("POST") == 0) - { - req.method_="POST"; - posStartPath = line.find_first_not_of(" ",4); - } - - SplitGetReq(line.substr(posStartPath), path, params); - - req.status_ = "202 OK"; - req.s_ = s; - req.path_ = path; - req.params_ = params; - - static const char authorization[] = "Authorization: Basic "; - static const char accept[] = "Accept: "; - static const char accept_language[] = "Accept-Language: "; - static const char accept_encoding[] = "Accept-Encoding: "; - static const char user_agent[] = "User-Agent: "; - static const char content_length[] = "Content-Length: "; - static const char content_type[] = "Content-Type: "; - - 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.compare(0, sizeof(authorization) - 1, authorization) == 0) - { - req.authentication_given_ = true; - std::string encoded = line.substr(sizeof(authorization) - 1); - 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.compare(0, sizeof(accept) - 1, accept) == 0) - { - req.accept_ = line.substr(sizeof(accept) - 1); - } - else if (line.compare(0, sizeof(accept_language) - 1, accept_language) == 0) - { - req.accept_language_ = line.substr(sizeof(accept_language) - 1); - } - else if (line.compare(0, sizeof(accept_encoding) - 1, accept_encoding) == 0) - { - req.accept_encoding_ = line.substr(sizeof(accept_encoding) - 1); - } - else if (line.compare(0, sizeof(user_agent) - 1, user_agent) == 0) - { - req.user_agent_ = line.substr(sizeof(user_agent) - 1); - } - else if (line.compare(0, sizeof(content_length) - 1, content_length) == 0) - { - req.content_length_ = atoi(line.substr(sizeof(content_length) - 1).c_str() ); - } - else if (line.compare(0, sizeof(content_type) - 1, content_type) == 0) - { - req.content_type_ = line.substr(sizeof(content_type) - 1); - } - } - - if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) ) - { - const char FormUrlEncoded[] = "application/x-www-form-urlencoded"; - // The only content type we can parse at the moment, the default HTML post data - if( req.content_type_.substr(0, strlen(FormUrlEncoded)).compare( FormUrlEncoded ) == 0 ) - { - std::string Content = s->ReceiveBytes( req.content_length_ ); - Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content - - std::string dummy; - std::map<std::string, std::string> post_params; - SplitGetReq(Content, dummy, post_params); - - req.params_post_ = post_params; - } - else - { - ParseMultipartFormData( req, s ); - } - } - - request_func_(&req); - - std::stringstream str_str; - str_str << req.answer_.size(); - - time_t ltime; - time(<ime); - tm* gmt= gmtime(<ime); - -#ifdef _WIN32 - static const char serverName[] = "MCServerWebAdmin (Windows)"; -#elif __APPLE__ - static const char serverName[] = "MCServerWebAdmin (MacOSX)"; -#else - static const char 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( true ); // true = wait for all data to be sent before closing - delete s; - - - return 0; -} - - - - - -void webserver::Stop() -{ - m_bStop = true; - m_Socket->Close(); - m_Events->Wait(); -} - - - - - -bool webserver::Begin() -{ - if (!m_Socket->IsValid()) - { - LOGINFO("WebAdmin: The server socket is invalid. Terminating WebAdmin."); - return false; - } - 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; - } - if (ptr_s == NULL) - { - LOGINFO("WebAdmin: Accepted socket is NULL. Terminating WebAdmin to avoid busywait."); - return false; - } - - #ifdef _WIN32 - unsigned ret; - HANDLE hHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, Request, (void *)ptr_s, 0, &ret)); - CloseHandle(hHandle); - #else - // Mattes: TODO: this handle probably leaks! - pthread_t * hHandle = new pthread_t; - pthread_create( hHandle, NULL, Request, ptr_s); - #endif - } - m_Events->Set(); - return true; -} - - - - - -webserver::webserver(unsigned int port_to_listen, request_func r) -{ - m_Socket = new SocketServer(port_to_listen, 1); - - request_func_ = r; - m_Events = new cEvents(); -} - - - - - -webserver::~webserver() -{ - delete m_Socket; - delete m_Events; -} - - - - diff --git a/WebServer/WebServer.h b/WebServer/WebServer.h deleted file mode 100644 index 882624db5..000000000 --- a/WebServer/WebServer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - WebServer.h - - Copyright (C) 2003-2004 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 - -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - - -class cEvents; -class Socket; -class SocketServer; -class webserver { -public: - struct formdata - { - std::string name_; - std::string filename_; - std::string content_type_; - std::string value_; - }; - - struct http_request { - - http_request() - : s_( 0 ) - , content_length_( 0 ) - , authentication_given_(false) - {} - - Socket* s_; - std::string method_; - std::string path_; - std::map<std::string, std::string> params_; - std::map<std::string, std::string> params_post_; - - std::string accept_; - std::string accept_language_; - std::string accept_encoding_; - std::string user_agent_; - int content_length_; - std::string content_type_; - std::vector< formdata > multipart_formdata_; - - /* status_: used to transmit server's error status, such as - o 202 OK - o 404 Not Found - and so on */ - std::string status_; - - /* auth_realm_: allows to set the basic realm for an authentication, - no need to additionally set status_ if set */ - std::string auth_realm_; - - std::string answer_; - - /* authentication_given_ is true when the user has entered a username and password. - These can then be read from username_ and password_ */ - bool authentication_given_; - std::string username_; - std::string password_; - }; - - typedef void (*request_func) (http_request*); - webserver(unsigned int port_to_listen, request_func); - ~webserver(); - - bool Begin(); - void Stop(); - -private: - bool m_bStop; - - #ifdef _WIN32 - static unsigned __stdcall Request(void*); - #else - static void* Request(void*); - #endif - - static request_func request_func_; - - cEvents * m_Events; - SocketServer* m_Socket; -}; diff --git a/WebServer/base64.cpp b/WebServer/base64.cpp deleted file mode 100644 index f505ea6c3..000000000 --- a/WebServer/base64.cpp +++ /dev/null @@ -1,102 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "base64.h" -#include <iostream> -#if defined(ANDROID_NDK) -#include <ctype.h> -#endif - -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -static inline bool is_base64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - - } - - return ret; - -} - -std::string base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - unsigned char char_array_4[4], char_array_3[3]; - std::string ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret += char_array_3[i]; - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; - } - - return ret; -} diff --git a/WebServer/base64.h b/WebServer/base64.h deleted file mode 100644 index 65d5db8b2..000000000 --- a/WebServer/base64.h +++ /dev/null @@ -1,4 +0,0 @@ -#include <string> - -std::string base64_encode(unsigned char const* , unsigned int len); -std::string base64_decode(std::string const& s); |