diff options
Diffstat (limited to 'src/reqp.cpp')
| -rw-r--r-- | src/reqp.cpp | 604 |
1 files changed, 269 insertions, 335 deletions
diff --git a/src/reqp.cpp b/src/reqp.cpp index 583a9aa..ee455e4 100644 --- a/src/reqp.cpp +++ b/src/reqp.cpp @@ -1,9 +1,10 @@ /*:* *: File: ./src/reqp.cpp *: - *: yChat; Homepage: www.yChat.org; Version 0.5.6-BASIC + *: yChat; Homepage: www.yChat.org; Version 0.7.9.5-RELEASE *: - *: Copyright (C) 2003, 2004 Paul C. Buetow, Volker Richter + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow *: Copyright (C) 2005 EXA Digital Solutions GbR *: *: This program is free software; you can redistribute it and/or @@ -21,446 +22,379 @@ *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *:*/ -// class reqp implementation. - -#ifndef REQP_CXX -#define REQP_CXX +#ifndef REQP_CPP +#define REQP_CPP #include "reqp.h" -#include "s_chat.h" -#include "s_html.h" -#include "s_mutx.h" -#include "s_sock.h" -#include "s_tool.h" +#include "tool/tool.h" + using namespace std; -// inititialization of static members. -string reqp::HTTP_CODEOK = "HTTP/1.1 200 OK\n"; -string reqp::HTTP_SERVER = "Server: yChat (Unix)\n"; -string reqp::HTTP_CONTAC = "Contact: www.yChat.org\n"; -string reqp::HTTP_CACHEC = "Expires: 0\nCache-control: no-cache\nPragma: no-cache\n"; -string reqp::HTTP_CONNEC = "Connection: keep-alive\n"; -string reqp::HTTP_COTYPE = "Content-Type: "; +#define HEADER HEADER1 HEADER2 HEADER3 HEADER4 HEADER9 +#define STREAM HEADER5 HEADER6 + +const string reqp::s_http = HEADER; +const string reqp::s_http_stream = STREAM; +const string reqp::s_http_colength = HEADER7; +const string reqp::s_http_cotype = HEADER8; +const string reqp::s_http_cotype_add = HEADER8b; reqp::reqp( ) {} -string -reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params ) +void +reqp::get_request_parameters( string s_parameters, map<string,string>& map_params ) { - int i_sock = p_thrd->get_sock(); - unsigned i_pos, i_pos2; - string s_vars( "" ); - string s_ret; - int i_req; - - // GET request - if ( s_req.find("GET") != string::npos) - { - // Be sure that the GET request has minimum length - if ( s_req.length() > 5 ) - { - // Get rid of "GET /" - if ( (i_pos = s_req.find("\n")) == string::npos ) - i_pos = s_req.length() - 1; - - s_req = s_req.substr(5, i_pos - 5); - - // Get HTML site to be displayed - if ( (i_pos = s_req.find("?")) == string::npos ) - { - if ( (i_pos2 = s_req.find(" HTTP")) != string::npos ) - s_ret = url_decode( s_req.substr(0, i_pos2)); - } - else - { - s_ret = url_decode( s_req.substr(0, i_pos) ); - - // Get request parameters: - if ( (i_pos2 = s_req.find(" HTTP")) != string::npos ) - { - s_req = url_decode( s_req.substr(i_pos + 1, i_pos2 - i_pos - 1) ); - get_request_parameters( s_req, map_params ); - } - } - - } - } - - // POST request - else - { - if ( (i_pos2 = s_req.find("HTTP")) != string::npos ) - { - if ( 13 < i_pos2 ) - { - s_ret = url_decode( s_req.substr(6,i_pos2-7) ); - - int i_len = s_ret.length(); - int i_len2 = s_req.length()-1; - - s_req = s_req.substr( i_len < i_len2 ? i_len : i_len2 ); - - if ( (i_pos = s_req.find("event=")) == string::npos) - { - char c_req[1024]; - i_len = read(i_sock, c_req, 1024); - s_req = c_req; - s_req = s_req.substr(0, i_len); - - if ( (i_pos = s_req.find("event=")) != string::npos ) - get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params ); - } - else - { - get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params ); - } - } - } - } + string s_tmp; + unsigned i_pos, i_pos2; -#ifdef VERBOSE - - pthread_mutex_lock ( &s_mutx::get - ().mut_stdout ); - cout << REQUEST << s_ret << endl; - pthread_mutex_unlock( &s_mutx::get - ().mut_stdout ); -#endif + while( (i_pos = s_parameters.find("&")) != string::npos ) + { + s_tmp = s_parameters.substr(0, i_pos ); - if ( s_ret.empty() ) - s_ret = s_conf::get - ().get_val( "STARTMPL" ); + if ( (i_pos2 = s_tmp.find("=")) != string::npos ) + map_params[ s_tmp.substr(0, i_pos2) ] = tool::replace( s_tmp.substr( i_pos2+1 ), "\\AND", "&"); - else - s_ret = remove_dots(s_ret); + s_parameters = s_parameters.substr( i_pos + 1 ); + } - map_params["request"] = s_ret; + // Get the last request parameter, which does not have a "&" on the end! + if( (i_pos = s_parameters.find("=")) != string::npos ) + map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr( i_pos+1 ); - return s_ret; + //map<string,string>::iterator iter; + //for ( iter = map_params.begin(); iter != map_params.end(); ++iter ) + //cout << ">>>" << iter->first << "=" << iter->second << endl; } -/* string -reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params ) +reqp::get_url( string s_req, map<string, string> &map_params, int& i_postpayloadoffset ) { - auto unsigned int pos; - string s_ret ( "" ); + unsigned i_pos, i_pos2; string s_vars( "" ); - auto int i_request; - - i_request= ( s_req.find("GET",0) != string::npos ) ? RQ_GET : RQ_POST; - - pos = s_req.find( "HTTP", 0 ); + string s_ret; + int i_req; - if( i_request == RQ_GET ) - s_ret.append( s_req.substr( 5, pos-6 ) ); - else - s_ret.append( s_req.substr( 6, pos-7 ) ); - - // remove ".." from the request. - do + // GET request + if ( s_req.find("GET") != string::npos) { - pos = s_ret.find( "../", 0 ); - - if ( pos == string::npos ) - break; + // Be sure that the GET request has minimum length + if ( s_req.length() > 5 ) + { + // Get rid of "GET /" + if ( (i_pos = s_req.find("\n")) == string::npos ) + i_pos = s_req.length() - 1; + + s_req = s_req.substr(5, i_pos - 5); + + // Get HTML site to be displayed + if ( (i_pos = s_req.find("?")) == string::npos ) + { + if ( (i_pos2 = s_req.find(" HTTP")) != string::npos ) + s_ret = url_decode( s_req.substr(0, i_pos2)); + } + else + { + s_ret = url_decode( s_req.substr(0, i_pos) ); + + // Get request parameters: + if ( (i_pos2 = s_req.find(" HTTP")) != string::npos ) + { + s_req = url_decode( s_req.substr(i_pos + 1, i_pos2 - i_pos - 1) ); + get_request_parameters( s_req, map_params ); + } + } - s_ret.replace( pos, pos+2, "" ); + } } - while( true ); - // do not add the string behind "?" tp s_ret and add all params behind "?" to map_params. - if( i_request == RQ_GET ) - pos = s_ret.find( "?", 0 ); + // POST request else - pos = s_req.find("\r\n\r\n", 0); - - auto string s_params( "" ); - if ( pos != string::npos ) - { - if( i_request == RQ_GET ) - s_params.append( s_ret.substr( pos+1, s_ret.length() -pos-1 ) ); - - else - s_params = s_req.substr( pos+4, s_req.length() -pos-1 ); - - s_ret = s_ret.substr( 0, pos ); - } - - if ( i_request == RQ_POST && s_params.empty() ) - { - char c_req[READBUF]; - - if ( read ( p_thrd->get_sock() , c_req, READBUF ) <= 0 ) - return "NOBYTE"; - - s_params = string( strstr( c_req, "event" ) ); - } - - auto unsigned int pos2; - do { - pos = s_params.find( "=", 0 ); - if ( pos == string::npos ) - break; - - pos2 = s_params.find( "&", 0 ); - if ( pos2 == string::npos ) + if ( (i_pos2 = s_req.find("HTTP")) != string::npos ) { - auto string sValue( s_params.substr(pos+1, s_params.length()-pos-1) ); - auto string tmpstr( url_decode(sValue) ); - map_params[ s_params.substr( 0, pos ) ] = tmpstr; - break; + if (i_pos2 > 13) + { + s_ret = url_decode( s_req.substr(6,i_pos2-7) ); + + //wrap::system_message(s_req); + //wrap::system_message(string("data offset=") + tool::int2string(i_postpayloadoffset)); + i_pos = s_req.find("event=",i_postpayloadoffset ); + if(i_pos != string::npos) + { + get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params); + } + } } - auto string s_temp= s_params.substr( pos+1, pos2-pos-1 ); - map_params[ s_params.substr( 0, pos ) ] = url_decode(s_temp); - - s_params = s_params.substr( pos2+1, s_params.length()-pos2-1 ); } - while( true ); #ifdef VERBOSE - - pthread_mutex_lock ( &s_mutx::get - ().mut_stdout ); - cout << REQUEST << s_ret << endl; - pthread_mutex_unlock( &s_mutx::get - ().mut_stdout ); + wrap::system_message( REQUEST + s_ret ); #endif if ( s_ret.empty() ) - s_ret = s_conf::get - ().get_val( "STARTMPL" ); + s_ret = wrap::CONF->get_elem( "httpd.startsite" ); + + else + s_ret = remove_dots(s_ret); map_params["request"] = s_ret; return s_ret; } -*/ string -reqp::get_content_type( string s_file ) +reqp::get_content_type(string &s_file) { - string s_ext=s_tool::getExtension( s_file ); + string s_ext(tool::get_extension( s_file )); - if(s_ext=="") - s_ext="DEFAULT"; + if( s_ext == "" ) + s_ext = "default"; - return s_conf::get - ().get_val( "CT_"+s_ext ); + return wrap::CONF->get_elem( "httpd.contenttypes." + s_ext ); } + void -reqp::parse_headers( string s_req, map_string &map_params ) +reqp::parse_headers( string s_req, map<string,string> &map_params ) { - int pos = s_req.find("\n"); - if(pos!=string::npos) - map_params["QUERY_STRING"]=s_tool::trim(s_req.substr(0,pos-1)); + int pos = s_req.find("\n"); - while(pos!=string::npos) - { - auto string s_line=s_req.substr(0,pos); - auto int pos2=s_line.find(":"); - if(pos2!=string::npos) - { - auto string key=s_tool::trim(s_line.substr(0, pos2)); - auto string value=s_tool::trim(s_line.substr(pos2+1)); + if (pos != string::npos) + { + map_params["QUERY_STRING"] = tool::trim(s_req.substr(0,pos-1)); - map_params[key]=value; + int pos2; + do + { + string s_line( s_req.substr(0, pos) ); + pos2 = s_line.find(":"); + if (pos2 != string::npos && s_line.length() > pos2+1) + map_params[ tool::trim(s_line.substr(0, pos2)) ] = tool::trim(s_line.substr(pos2+1)); - } - s_req=s_req.substr(s_line.size()+1); - pos=s_req.find("\n"); + s_req = s_req.substr( s_line.size() + 1 ); + pos = s_req.find("\n"); } - + while( pos != string::npos); + } // if } - int -reqp::htoi(string *s) +reqp::htoi(string *p_str) { - int value; - int c; + int value, c; + c = p_str->at(0); - c=s->c_str()[0]; - if(isupper(c)) - c=tolower(c); + if( isupper(c) ) + c = tolower(c); - value=(c>='0' && c<='9'?c-'0':c-'a'+10)*16; + value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; - c=s->c_str()[1]; - if(isupper(c)) - c=tolower(c); + c = p_str->at(1); - value+=c>='0' && c<='9'?c-'0':c-'a'+10; - return value; + if( isupper(c) ) + c = tolower(c); + + value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; + + return value; } string -reqp::url_decode( string s_str ) +reqp::url_decode( string s_url ) { - auto string sDest=""; - int len = s_str.size(); + string s_dest = ""; + int i_len = s_url.size(); + int i_prv = i_len - 2; - for(int i=0;i<len;i++) + char c; + for( int i = 0; i < i_len; ++i) + { + c = s_url.at(i); + if( c == '+' ) { - char ch = s_str.at(i); - if(ch=='+') - { - sDest+=" "; - } - else if(ch=='%') - { - auto string sTmp=s_str.substr(i+1,2); - ch=(char)htoi(&sTmp); - sDest+=ch; - i+=2; - - } - else - - sDest+=ch; + s_dest += " "; + } + else if (c == '%' && i < i_prv) + { + string s_tmp = s_url.substr(i+1, 2); + c = (char) htoi(&s_tmp); + s_dest += c; + i += 2; + } + else + { + s_dest += c; } - return sDest; + } + + return s_dest; } string reqp::get_from_header( string s_req, string s_hdr ) { - auto unsigned int pos[2]; - pos[0] = s_req.find( s_hdr, 0 ); - pos[1] = s_req.find( "\n", pos[0] ); + unsigned i_pos[2]; + if ( (i_pos[0] = s_req.find( s_hdr, 0 )) == string::npos ) + return ""; + + if ( (i_pos[1] = s_req.find( "\n", i_pos[0]) ) == string::npos ) + return ""; - auto int i_length = s_hdr.length(); - return s_req.substr( pos[0]+i_length, pos[1]-pos[0]-i_length-1 ); + unsigned i_len = s_hdr.length(); + return s_req.substr( i_pos[0] + i_len, i_pos[1] - i_pos[0] - i_len - 1 ); } string -reqp::parse( thrd* p_thrd, string s_req, map_string &map_params ) +reqp::parse( socketcontainer *p_sock, string s_req, map<string,string> &map_params, int &i_postpayloadoffset ) { - // store all request informations in map_params. store the url in - // map_params["request"]. + // store all request informations in map_params. store the url in + // map_params["request"]. + get_url( s_req, map_params, i_postpayloadoffset ); - if ( get_url( p_thrd, s_req, map_params ).compare("NOBYTE") == 0 ) - map_params["request"] = s_conf::get - ().get_val("NOTFOUND"); + parse_headers( s_req, map_params ); + string s_event( map_params["event"] ); - parse_headers( s_req, map_params ); - // create the http header. - string s_rep( HTTP_CODEOK ); - s_rep.append( HTTP_SERVER ); - s_rep.append( HTTP_CONTAC ); - s_rep.append( HTTP_CACHEC ); - s_rep.append( HTTP_CONNEC ); - s_rep.append( HTTP_COTYPE ); - s_rep.append( get_content_type( map_params["request"] ) ); - s_rep.append("\r\n\r\n"); + map_params["content-type"] = get_content_type( map_params["request"] ); - // check the event variable. + string s_rep( "" ); - string s_event( map_params["event"] ); - if ( ! s_event.empty() ) + //<<* + // check the event variable. + if ( ! s_event.empty() ) + { + // login procedure. + if ( s_event == "login" ) + { + wrap::CHAT->login( map_params ); + } + else if ( s_event == "register" ) { - // login procedure. - if ( s_event == "login" ) + user* p_user = new user; + map_params["INFO"] = ""; + run_html_mod( s_event, map_params, p_user ); + wrap::GCOL->add_user_to_garbage( p_user ); + } + else + { + sess *p_sess = wrap::SMAN->get_session( map_params["tmpid"] ); + user *p_user = NULL; + + if( p_sess != NULL ) + { + p_user = p_sess->get_user(); + } + else + { + wrap::system_message(SESSERR); + return s_rep; + } + + if ( ! p_user ) + { + map_params["INFO"] = wrap::CONF->get_elem( "chat.msgs.err.notonline" ); + map_params["request"] = wrap::CONF->get_elem( "httpd.startsite" ); // redirect to the startpage. + } + else + { + map_params["nick"] = p_user->get_name().c_str(); + + // if a message input. + if ( s_event == "input" ) { - s_chat::get - ().login( map_params ); + if ( p_user ) + { + p_user->check_restore_away(); + wrap::CHAT->post( p_user, map_params ); + } } - else + // if a chat stream + else if ( s_event == "stream" ) { - bool b_found; - - // user* p_user = s_chat::get().get_user( map_params["nick"], b_found ); - sess *sess_temp=s_sman::get - ().getSession( map_params["tmpid"] ); - user *p_user; - if(sess_temp!=NULL) - { - string *s_nick=static_cast<string*>(sess_temp->getValue(string("nick"))); - p_user = s_chat::get - ().get_user( *s_nick, b_found); - } - else - return s_rep; - if ( ! b_found ) - { - map_params["INFO"] = E_NOTONL; - map_params["request"] = s_conf::get - ().get_val( "STARTMPL" ); // redirect to the startpage. - } - // if a message post. - else if ( s_event == "post" ) - s_chat::get - ().post( p_user, map_params ); - - - // if a chat stream - else if ( s_event == "stream" ) - { - string s_msg(s_html::get - ().parse( map_params ) ); - p_user->msg_post( &s_msg); - s_sock::get - ().chat_stream( p_thrd->get_sock(), p_user, map_params ); - } - - // if a request for the online list of the active room. - else if ( s_event == "online" ) - s_html::get - ().online_list( p_user, map_params ); + string s_msg ( wrap::HTML->parse( map_params ) ); + p_user->msg_post( &s_msg); + wrap::SOCK->chat_stream( p_sock, p_user, map_params ); } + + // if a request for the online list of the active room. + else if ( s_event == "online" ) + { + wrap::HTML->online_list( p_user, map_params ); + } + else //if ( s_event != "input" ) + { + run_html_mod( s_event, map_params, p_user ); + } + } } + } + //*>> + if ( wrap::CONF->get_elem("httpd.enablecgi").compare("true") == 0 && + string::npos != map_params["request"].find(".cgi") ) + { + s_rep.append( tool::shell_command( + wrap::CONF->get_elem("httpd.templatedir") + map_params["request"], + METH_RETSTRING ) ); + } + else + { // parse and get the requested html-template and also use // the values stored in map_params for %%KEY%% substituations. - s_rep.append( s_html::get - ().parse( map_params ) ); + s_rep.append( wrap::HTML->parse( map_params ) ); + } - // return the parsed html-template. - return s_rep; -} + // create the http header. -string -reqp::remove_dots( string s_ret ) -{ - // remove ".." from the request. - unsigned pos; + string s_resp(s_http); + if ( s_event.compare("stream") == 0 ) + s_resp.append( s_http_stream ); - if( (pos = s_ret.find( ".." )) != string::npos) - return s_ret.substr(0, pos); + s_resp.append( s_http_colength + tool::int2string(s_rep.size()) + "\r\n" + + s_http_cotype + map_params["content-type"] + + s_http_cotype_add + "\r\n" ); - return s_ret; + s_resp.append(s_rep); + + + // return the parsed html-template. + return s_resp; } +//<<* void -reqp::get_request_parameters( string s_parameters, map<string,string>& map_params ) +reqp::run_html_mod( string s_event, map<string,string> &map_params, user* p_user ) { - string s_tmp; - unsigned i_pos, i_pos2; + container *c = new container; - while( (i_pos = s_parameters.find("&")) != string::npos ) - { - s_tmp = s_parameters.substr(0, i_pos ); + c->elem[0] = (void*) wrap::WRAP; + c->elem[1] = (void*) &map_params; + c->elem[2] = (void*) p_user; - if ( (i_pos2 = s_tmp.find("=")) != string::npos ) - map_params[ s_tmp.substr(0, i_pos2) ] = s_tool::replace( s_tmp.substr( i_pos2+1 ), "\\AND", "&"); + string s_mod = wrap::CONF->get_elem("httpd.modules.htmldir") + "yc_" + s_event + ".so"; - s_parameters = s_parameters.substr( i_pos + 1 ); - } + dynmod* p_module = wrap::MODL->get_module( s_mod, p_user->get_name() ); - // Get the last request parameter, which does not have a "&" on the end! - if( (i_pos = s_parameters.find("=")) != string::npos ) - map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr( i_pos+1 ); + if ( p_module != NULL ) + ( *( p_module->the_func ) ) ( static_cast<void*>(c) ); - //map<string,string>::iterator iter; - //for ( iter = map_params.begin(); iter != map_params.end(); ++iter ) - //cout << ">>>" << iter->first << "=" << iter->second << endl; + delete c; } +//*>> +string +reqp::remove_dots( string s_ret ) +{ + // remove ".." from the request. + unsigned i_pos; + + if ( (i_pos = s_ret.find( ".." )) != string::npos ) + return remove_dots(s_ret.substr(0, i_pos)); + + return s_ret; +} #endif |
