Improve http argument parsing for special cases

This commit is contained in:
Lekensteyn 2012-02-25 23:46:39 +01:00
parent a491b59fe8
commit a2eae38e6a

View file

@ -109,8 +109,11 @@ void HTTP::Parser::SetHeader(std::string i, int v){
void HTTP::Parser::SetVar(std::string i, std::string v){ void HTTP::Parser::SetVar(std::string i, std::string v){
Trim(i); Trim(i);
Trim(v); Trim(v);
//only set if there is actually a key
if(!i.empty()){
vars[i] = v; vars[i] = v;
} }
}
/// Attempt to read a whole HTTP request or response from Socket::Connection. /// Attempt to read a whole HTTP request or response from Socket::Connection.
/// \param sock The socket to use. /// \param sock The socket to use.
@ -201,23 +204,36 @@ void HTTP::Parser::SendResponse(Socket::Connection & conn, std::string code, std
conn.write(tmp); conn.write(tmp);
} }
#include <iostream>
/// Parses GET or POST-style variable data. /// Parses GET or POST-style variable data.
/// Saves to internal variable structure using HTTP::Parser::SetVar. /// Saves to internal variable structure using HTTP::Parser::SetVar.
void HTTP::Parser::parseVars(std::string data){ void HTTP::Parser::parseVars(std::string data){
std::string varname; std::string varname;
std::string varval; std::string varval;
while (data.find('=') != std::string::npos){ // position where a part start (e.g. after &)
size_t found = data.find('='); size_t pos = 0;
varname = urlunescape(data.substr(0, found)); while (pos < data.length()){
data.erase(0, found+1); size_t nextpos = data.find('&', pos);
found = data.find('&'); if (nextpos == std::string::npos){
varval = urlunescape(data.substr(0, found)); nextpos = data.length();
SetVar(varname, varval);
if (found == std::string::npos){
data.clear();
}else{
data.erase(0, found+1);
} }
size_t eq_pos = data.find('=', pos);
if (eq_pos < nextpos){
// there is a key and value
varname = data.substr(pos, eq_pos - pos);
varval = data.substr(eq_pos + 1, nextpos - eq_pos - 1);
}else{
// no value, only a key
varname = data.substr(pos, nextpos - pos);
varval.clear();
}
SetVar(urlunescape(varname), urlunescape(varval));
if (nextpos == std::string::npos){
// in case the string is gigantic
break;
}
// erase &
pos = nextpos + 1;
} }
} }