1
0

Can now receive POST data in WebPlugins!

Fixed Debug With optimized Noise in VS2010 by having it run the correct MCServer_debug.exe instead of MCServer.exe
Changed winsock.h to Winsock2.h in Globals.h so sockets can be graciously closed (See webserver Socket::Close() )

git-svn-id: http://mc-server.googlecode.com/svn/trunk@197 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
faketruth
2012-01-31 00:38:18 +00:00
parent f4583fda98
commit c142424571
14 changed files with 224 additions and 117 deletions

View File

@@ -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_);
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;
s->Close( true ); // true = wait for all data to be sent before closing
delete s;
return 0;
return 0;
}
void webserver::Stop()