From 6fde6b0fe90abde84011202edd40fe46eb06af44 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 21 Nov 2010 16:20:55 +0000 Subject: --- src/reqp.cpp | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 250 insertions(+), 32 deletions(-) (limited to 'src/reqp.cpp') diff --git a/src/reqp.cpp b/src/reqp.cpp index fbf794f..7f5349e 100644 --- a/src/reqp.cpp +++ b/src/reqp.cpp @@ -1,12 +1,11 @@ /*:* *: File: ./src/reqp.cpp *: - *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: yChat; Homepage: www.yChat.org; Version 0.8.3-CURRENT *: *: Copyright (C) 2003 Paul C. Buetow, Volker Richter *: Copyright (C) 2004 Paul C. Buetow *: Copyright (C) 2005 EXA Digital Solutions GbR - *: Copyright (C) 2006, 2007 Paul C. Buetow *: *: This program is free software; you can redistribute it and/or *: modify it under the terms of the GNU General Public License @@ -44,12 +43,223 @@ reqp::reqp( ) {} void -reqp::parse(context *p_context) +reqp::get_request_parameters( string s_parameters, map& map_params ) { - map &map_params = *p_context->p_map_params; + string s_tmp; + unsigned i_pos, i_pos2; - string *p_response = p_context->p_response; - string &s_event = map_params["event"]; + while( (i_pos = s_parameters.find("&")) != string::npos ) + { + s_tmp = s_parameters.substr(0, i_pos ); + + 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", "&"); + + s_parameters = s_parameters.substr( i_pos + 1 ); + } + + // 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 ); + + //map::iterator iter; + //for ( iter = map_params.begin(); iter != map_params.end(); ++iter ) + //cout << ">>>" << iter->first << "=" << iter->second << endl; +} + +string +reqp::get_url( string s_req, map &map_params, int& i_postpayloadoffset ) +{ + 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 (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); + } + } + } + + } + +#ifdef VERBOSE + wrap::system_message( REQUEST + s_ret ); +#endif + + if ( s_ret.empty() ) + 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) +{ + string s_ext(tool::get_extension( s_file )); + + if( s_ext == "" ) + s_ext = "default"; + + return wrap::CONF->get_elem( "httpd.contenttypes." + s_ext ); +} + +void +reqp::parse_headers( string s_req, map &map_params ) +{ + int pos = s_req.find("\n"); + + if (pos != string::npos) + { + map_params["QUERY_STRING"] = tool::trim(s_req.substr(0,pos-1)); + + 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"); + } + while( pos != string::npos); + } // if +} + +int +reqp::htoi(string *p_str) +{ + int value, c; + c = p_str->at(0); + + if( isupper(c) ) + c = tolower(c); + + value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; + + c = p_str->at(1); + + if( isupper(c) ) + c = tolower(c); + + value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; + + return value; +} + +string +reqp::url_decode( string s_url ) +{ + string s_dest = ""; + int i_len = s_url.size(); + int i_prv = i_len - 2; + + char c; + for( int i = 0; i < i_len; ++i) + { + c = s_url.at(i); + if( c == '+' ) + { + 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 s_dest; +} + +string +reqp::get_from_header( string s_req, string s_hdr ) +{ + 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 ""; + + 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( _socket *p_sock, string s_req, map &map_params, int &i_postpayloadoffset ) +{ + + // store all request informations in map_params. store the url in + // map_params["request"]. + get_url( s_req, map_params, i_postpayloadoffset ); + + parse_headers( s_req, map_params ); + string s_event( map_params["event"] ); + + map_params["content-type"] = get_content_type( map_params["request"] ); + + string s_rep( "" ); //<<* // check the event variable. @@ -72,14 +282,14 @@ reqp::parse(context *p_context) sess *p_sess = wrap::SMAN->get_session( map_params["tmpid"] ); user *p_user = NULL; - if ( p_sess != NULL ) + if( p_sess != NULL ) { p_user = p_sess->get_user(); } else { wrap::system_message(SESSERR); - return; + return s_rep; } if ( ! p_user ) @@ -104,18 +314,9 @@ reqp::parse(context *p_context) // if a chat stream else if ( s_event == "stream" ) { - /* - string s_resp(s_http+s_http_stream); - s_resp.append(s_http_colength + tool::int2string(s_response.size()) + "\r\n" + - s_http_cotype + map_params["content-type"] - // + s_http_cotype_add - + "\r\n\r\n" );*/ - /* string s_resp(""); - s_resp.append(wrap::HTML->parse(map_params)); - p_user->set_context(p_context); - */ - map_params["KEEP_ALIVE"] = "yes"; - return; + 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. @@ -130,32 +331,37 @@ reqp::parse(context *p_context) } } } + //*>> if ( wrap::CONF->get_elem("httpd.enablecgi").compare("true") == 0 && string::npos != map_params["request"].find(".cgi") ) { - p_response->append( tool::shell_command( - wrap::CONF->get_elem("httpd.templatedir") + map_params["request"], - METH_RETSTRING ) ); + 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. - p_response->append( wrap::HTML->parse( map_params ) ); + s_rep.append( wrap::HTML->parse( map_params ) ); } - // create the http header if not a stream -// if ( s_event.compare("stream") != 0 ) { - string s_resp(""); - s_resp.append(s_http); - //s_resp.append( s_http_stream ); - s_resp.append( s_http_colength + tool::int2string(p_response->size()) + "\r\n" + + // create the http header. + + string s_resp(s_http); + if ( s_event.compare("stream") == 0 ) + s_resp.append( s_http_stream ); + + 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" ); - s_resp.append(*p_response); -// } + s_resp.append(s_rep); + + + // return the parsed html-template. + return s_resp; } //<<* @@ -179,4 +385,16 @@ reqp::run_html_mod( string s_event, map &map_params, user* p_user } //*>> +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 -- cgit v1.2.3