summaryrefslogtreecommitdiffstats
path: root/WebServer/WebServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebServer/WebServer.cpp')
-rw-r--r--WebServer/WebServer.cpp219
1 files changed, 129 insertions, 90 deletions
diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp
index 466093fd3..5de1385a2 100644
--- a/WebServer/WebServer.cpp
+++ b/WebServer/WebServer.cpp
@@ -12,12 +12,12 @@
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.
+ 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.
+ misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
@@ -55,121 +55,160 @@ unsigned webserver::Request(void* ptr_s)
void* webserver::Request(void* ptr_s)
#endif
{
- Socket* s = (reinterpret_cast<Socket*>(ptr_s));
+ Socket* s = (reinterpret_cast<Socket*>(ptr_s));
- std::string line = s->ReceiveLine();
- if (line.empty()) {
- s->Close();
- delete s;
- return 0;
- }
+ std::string line = s->ReceiveLine();
+ if (line.empty())
+ {
+ s->Close();
+ delete s;
+ return 0;
+ }
- http_request req;
+ 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";
- }
- else if (line.find("POST") == 0) {
- req.method_="POST";
- }
+ 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);
+ }
- std::string path;
- std::map<std::string, std::string> params;
+ SplitGetReq(line.substr(posStartPath), path, params);
- size_t posStartPath = line.find_first_not_of(" ",3);
+ req.status_ = "202 OK";
+ req.s_ = s;
+ req.path_ = path;
+ req.params_ = params;
- SplitGetReq(line.substr(posStartPath), path, 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: " ;
+ static const std::string content_length = "Content-Length: " ;
+ static const std::string content_type = "Content-Type: " ;
- req.status_ = "202 OK";
- req.s_ = s;
- req.path_ = path;
- req.params_ = params;
+ while(1)
+ {
+ line=s->ReceiveLine();
+ if (line.empty()) break;
- 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: " ;
+ unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d");
+ if (pos_cr_lf == 0) break;
- while(1) {
- line=s->ReceiveLine();
+ line = line.substr(0,pos_cr_lf);
- if (line.empty()) break;
+ 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_cr_lf = line.find_first_of("\x0a\x0d");
- if (pos_cr_lf == 0) break;
+ unsigned int pos_colon = decoded.find(":");
- line = line.substr(0,pos_cr_lf);
+ 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());
+ }
+ else if (line.substr(0, content_length.size()) == content_length)
+ {
+ req.content_length_ = atoi( line.substr(content_length.size()).c_str() );
+ }
+ else if (line.substr(0, content_type.size()) == content_type)
+ {
+ req.content_type_ = line.substr(content_type.size());
+ }
+ }
- if (line.substr(0, authorization.size()) == authorization) {
- req.authentication_given_ = true;
- std::string encoded = line.substr(authorization.size());
- std::string decoded = base64_decode(encoded);
+ if( req.method_.compare("POST") == 0 )
+ {
+ if( req.content_length_ > 0 )
+ {
+ // The only content type we can parse at the moment, the default HTML post data
+ if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 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
- unsigned int pos_colon = decoded.find(":");
+ std::string dummy;
+ std::map<std::string, std::string> post_params;
+ SplitGetReq(Content, dummy, post_params);
- 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());
- }
- }
+ req.params_post_ = post_params;
+ }
+ }
+ }
- request_func_(&req);
+ request_func_(&req);
- std::stringstream str_str;
- str_str << req.answer_.size();
+ std::stringstream str_str;
+ str_str << req.answer_.size();
- time_t ltime;
- time(&ltime);
- tm* gmt= gmtime(&ltime);
+ time_t ltime;
+ time(&ltime);
+ tm* gmt= gmtime(&ltime);
#ifdef _WIN32
- static std::string const serverName = "MCServerWebAdmin (Windows)";
+ static std::string const serverName = "MCServerWebAdmin (Windows)";
#elif __APPLE__
- static std::string const serverName = "MCServerWebAdmin (MacOSX)";
+ static std::string const serverName = "MCServerWebAdmin (MacOSX)";
#else
- static std::string const serverName = "MCServerWebAdmin (Linux)";
+ static std::string const serverName = "MCServerWebAdmin (Linux)";
#endif
- char* asctime_remove_nl = std::asctime(gmt);
- asctime_remove_nl[24] = 0;
+ char* asctime_remove_nl = std::asctime(gmt);
+ asctime_remove_nl[24] = 0;
- s->SendBytes("HTTP/1.1 ");
+ 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;
+ 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;
+ return 0;
}
void webserver::Stop()