Fixed some issues in HTTP, added GET param support, fixed a bug, etc... lots of maintenaince.
This commit is contained in:
		
							parent
							
								
									266196d731
								
							
						
					
					
						commit
						fdfe95e792
					
				
					 4 changed files with 72 additions and 33 deletions
				
			
		| 
						 | 
					@ -14,9 +14,9 @@ void HTTP::Parser::Clean(){
 | 
				
			||||||
  method = "GET";
 | 
					  method = "GET";
 | 
				
			||||||
  url = "/";
 | 
					  url = "/";
 | 
				
			||||||
  protocol = "HTTP/1.1";
 | 
					  protocol = "HTTP/1.1";
 | 
				
			||||||
  body = "";
 | 
					  body.clear();
 | 
				
			||||||
  length = 0;
 | 
					  length = 0;
 | 
				
			||||||
  HTTPbuffer = "";
 | 
					  HTTPbuffer.clear();
 | 
				
			||||||
  headers.clear();
 | 
					  headers.clear();
 | 
				
			||||||
  vars.clear();
 | 
					  vars.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -172,7 +172,10 @@ bool HTTP::Parser::parse(){
 | 
				
			||||||
        if (f != std::string::npos){url = tmpA.substr(0, f); tmpA.erase(0, f+1);}
 | 
					        if (f != std::string::npos){url = tmpA.substr(0, f); tmpA.erase(0, f+1);}
 | 
				
			||||||
        f = tmpA.find(' ');
 | 
					        f = tmpA.find(' ');
 | 
				
			||||||
        if (f != std::string::npos){protocol = tmpA.substr(0, f); tmpA.erase(0, f+1);}
 | 
					        if (f != std::string::npos){protocol = tmpA.substr(0, f); tmpA.erase(0, f+1);}
 | 
				
			||||||
        /// \todo Include GET variable parsing?
 | 
					        if (url.find('?') != std::string::npos){
 | 
				
			||||||
 | 
					          std::string queryvars = url.substr(url.find('?')+1);
 | 
				
			||||||
 | 
					          parseVars(queryvars); //parse GET variables
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }else{
 | 
					      }else{
 | 
				
			||||||
        if (tmpA.size() == 0){
 | 
					        if (tmpA.size() == 0){
 | 
				
			||||||
          seenHeaders = true;
 | 
					          seenHeaders = true;
 | 
				
			||||||
| 
						 | 
					@ -191,22 +194,7 @@ bool HTTP::Parser::parse(){
 | 
				
			||||||
        if (HTTPbuffer.length() >= length){
 | 
					        if (HTTPbuffer.length() >= length){
 | 
				
			||||||
          body = HTTPbuffer.substr(0, length);
 | 
					          body = HTTPbuffer.substr(0, length);
 | 
				
			||||||
          HTTPbuffer.erase(0, length);
 | 
					          HTTPbuffer.erase(0, length);
 | 
				
			||||||
          std::string tmppost = body;
 | 
					          parseVars(body); //parse POST variables
 | 
				
			||||||
          std::string varname;
 | 
					 | 
				
			||||||
          std::string varval;
 | 
					 | 
				
			||||||
          while (tmppost.find('=') != std::string::npos){
 | 
					 | 
				
			||||||
            size_t found = tmppost.find('=');
 | 
					 | 
				
			||||||
            varname = urlunescape((char*)tmppost.substr(0, found).c_str());
 | 
					 | 
				
			||||||
            tmppost.erase(0, found+1);
 | 
					 | 
				
			||||||
            found = tmppost.find('&');
 | 
					 | 
				
			||||||
            varval = urlunescape((char*)tmppost.substr(0, found).c_str());
 | 
					 | 
				
			||||||
            SetVar(varname, varval);
 | 
					 | 
				
			||||||
            if (found == std::string::npos){
 | 
					 | 
				
			||||||
              tmppost.clear();
 | 
					 | 
				
			||||||
            }else{
 | 
					 | 
				
			||||||
              tmppost.erase(0, found+1);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return true;
 | 
					          return true;
 | 
				
			||||||
        }else{
 | 
					        }else{
 | 
				
			||||||
          return false;
 | 
					          return false;
 | 
				
			||||||
| 
						 | 
					@ -229,6 +217,26 @@ void HTTP::Parser::SendResponse(Socket::Connection & conn, std::string code, std
 | 
				
			||||||
  conn.write(tmp);
 | 
					  conn.write(tmp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Parses GET or POST-style variable data.
 | 
				
			||||||
 | 
					/// Saves to internal variable structure using HTTP::Parser::SetVar.
 | 
				
			||||||
 | 
					void HTTP::Parser::parseVars(std::string & data){
 | 
				
			||||||
 | 
					  std::string varname;
 | 
				
			||||||
 | 
					  std::string varval;
 | 
				
			||||||
 | 
					  while (data.find('=') != std::string::npos){
 | 
				
			||||||
 | 
					    size_t found = data.find('=');
 | 
				
			||||||
 | 
					    varname = urlunescape(data.substr(0, found));
 | 
				
			||||||
 | 
					    data.erase(0, found+1);
 | 
				
			||||||
 | 
					    found = data.find('&');
 | 
				
			||||||
 | 
					    varval = urlunescape(data.substr(0, found));
 | 
				
			||||||
 | 
					    SetVar(varname, varval);
 | 
				
			||||||
 | 
					    if (found == std::string::npos){
 | 
				
			||||||
 | 
					      data.clear();
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					      data.erase(0, found+1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Sends data as HTTP/1.1 bodypart to conn.
 | 
					/// Sends data as HTTP/1.1 bodypart to conn.
 | 
				
			||||||
/// HTTP/1.1 chunked encoding is automatically applied if needed.
 | 
					/// HTTP/1.1 chunked encoding is automatically applied if needed.
 | 
				
			||||||
/// \param conn The Socket::Connection to send the part over.
 | 
					/// \param conn The Socket::Connection to send the part over.
 | 
				
			||||||
| 
						 | 
					@ -257,24 +265,26 @@ void HTTP::Parser::SendBodyPart(Socket::Connection & conn, std::string bodypart)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Unescapes URLencoded C-strings to a std::string.
 | 
					/// Unescapes URLencoded std::strings.
 | 
				
			||||||
/// This function *will* destroy the input data!
 | 
					std::string HTTP::Parser::urlunescape(std::string in){
 | 
				
			||||||
std::string HTTP::Parser::urlunescape(char *s){
 | 
					  std::string out;
 | 
				
			||||||
  char  *p;
 | 
					  for (unsigned int i = 0; i < in.length(); ++i){
 | 
				
			||||||
  for (p = s; *s != '\0'; ++s){
 | 
					    if (in[i] == '%'){
 | 
				
			||||||
    if (*s == '%'){
 | 
					      char tmp = 0;
 | 
				
			||||||
      if (*++s != '\0'){
 | 
					      ++i;
 | 
				
			||||||
        *p = unhex(*s) << 4;
 | 
					      if (i < in.length()){
 | 
				
			||||||
 | 
					        tmp = unhex(in[i]) << 4;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (*++s != '\0'){
 | 
					      ++i;
 | 
				
			||||||
        *p++ += unhex(*s);
 | 
					      if (i < in.length()){
 | 
				
			||||||
 | 
					        tmp += unhex(in[i]);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      out += tmp;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      if (*s == '+'){*p++ = ' ';}else{*p++ = *s;}
 | 
					      if (in[i] == '+'){out += ' ';}else{out += in[i];}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *p = '\0';
 | 
					  return out;
 | 
				
			||||||
  return std::string(s);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Helper function for urlunescape.
 | 
					/// Helper function for urlunescape.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ namespace HTTP{
 | 
				
			||||||
      void SendBodyPart(Socket::Connection & conn, std::string bodypart);
 | 
					      void SendBodyPart(Socket::Connection & conn, std::string bodypart);
 | 
				
			||||||
      void Clean();
 | 
					      void Clean();
 | 
				
			||||||
      bool CleanForNext();
 | 
					      bool CleanForNext();
 | 
				
			||||||
      std::string urlunescape(char *s); ///< Unescapes URLencoded C-strings to a std::string.
 | 
					      std::string urlunescape(std::string in);
 | 
				
			||||||
      std::string body;
 | 
					      std::string body;
 | 
				
			||||||
      std::string method;
 | 
					      std::string method;
 | 
				
			||||||
      std::string url;
 | 
					      std::string url;
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@ namespace HTTP{
 | 
				
			||||||
      bool seenHeaders;
 | 
					      bool seenHeaders;
 | 
				
			||||||
      bool seenReq;
 | 
					      bool seenReq;
 | 
				
			||||||
      bool parse();
 | 
					      bool parse();
 | 
				
			||||||
 | 
					      void parseVars(std::string & data);
 | 
				
			||||||
      std::string HTTPbuffer;
 | 
					      std::string HTTPbuffer;
 | 
				
			||||||
      std::map<std::string, std::string> headers;
 | 
					      std::map<std::string, std::string> headers;
 | 
				
			||||||
      std::map<std::string, std::string> vars;
 | 
					      std::map<std::string, std::string> vars;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,10 +10,35 @@
 | 
				
			||||||
#if DEBUG >= 1
 | 
					#if DEBUG >= 1
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::map<pid_t, std::string> Util::Procs::plist;
 | 
					std::map<pid_t, std::string> Util::Procs::plist;
 | 
				
			||||||
bool Util::Procs::handler_set = false;
 | 
					bool Util::Procs::handler_set = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Sets the current process' running user
 | 
				
			||||||
 | 
					void Util::setUser(std::string username){
 | 
				
			||||||
 | 
					  if (username != "root"){
 | 
				
			||||||
 | 
					    struct passwd * user_info = getpwnam(username.c_str());
 | 
				
			||||||
 | 
					    if (!user_info){
 | 
				
			||||||
 | 
					      #if DEBUG >= 1
 | 
				
			||||||
 | 
					      fprintf(stderr, "Error: could not setuid %s: could not get PID\n", username.c_str());
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					      return 1;
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					      if (setuid(user_info->pw_uid) != 0){
 | 
				
			||||||
 | 
					        #if DEBUG >= 1
 | 
				
			||||||
 | 
					        fprintf(stderr, "Error: could not setuid %s: not allowed\n", username.c_str());
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					      }else{
 | 
				
			||||||
 | 
					        #if DEBUG >= 3
 | 
				
			||||||
 | 
					        fprintf(stderr, "Changed user to %s\n", username.c_str());
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Used internally to capture child signals and update plist.
 | 
					/// Used internally to capture child signals and update plist.
 | 
				
			||||||
void Util::Procs::childsig_handler(int signum){
 | 
					void Util::Procs::childsig_handler(int signum){
 | 
				
			||||||
  if (signum != SIGCHLD){return;}
 | 
					  if (signum != SIGCHLD){return;}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,4 +27,7 @@ namespace Util{
 | 
				
			||||||
      static pid_t getPid(std::string name);
 | 
					      static pid_t getPid(std::string name);
 | 
				
			||||||
      static std::string getName(pid_t name);
 | 
					      static std::string getName(pid_t name);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static setUser(std::string user);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue