std::string Proxy:: correctConnectionInfo(std::string &httpMessage ) { //Remove potential host name from GET request std::string newHttpMessage = httpMessage; std::string hostName = extractHost( newHttpMessage ); std::string getHostName = "GET http://" + hostName; long wrongGetIndex = newHttpMessage.find( getHostName ); if ( wrongGetIndex != std::string::npos ) { newHttpMessage = "GET " + newHttpMessage.substr( getHostName.length() ); } //Detect Connection or Proxy-Connection std::string searchWord = "Proxy-Connection"; long foundWordIndex = newHttpMessage.find( searchWord ); if ( foundWordIndex == std::string::npos ) { searchWord = "Connection: "; foundWordIndex = newHttpMessage.find( searchWord ); if ( foundWordIndex == std::string::npos ) { return newHttpMessage; } } //Set to "Connection: close" long fieldValueLength = newHttpMessage.find("\r",foundWordIndex) - foundWordIndex; std::string messageBefore = newHttpMessage.substr( 0, foundWordIndex ); std::string messageAfter = newHttpMessage.substr( foundWordIndex + fieldValueLength, newHttpMessage.length() ); return messageBefore + "Connection: close" + messageAfter; }
void Proxy:: handleProxyTransaction( Socket & browserSocket ) { // Recieve HTTP header from browser std::string browserHeader = ""; if ( ! browserSocket.recieveHttpHeader( browserHeader ) ) { std::cout << "\n\n**** Error recieving HTTP header from browser ****\n\n"; return; } std::cout << browserHeader << std::endl; if (searchStringForIllegalContents( pickOutJumbledURL( browserHeader ), mIllegalContents )) { std::cout << "\n\n**** We found some illegal content in the URL! ****\n\n"; sendBadUrlRedirectToBrowser( browserSocket ); } std::string hostName = extractHost( browserHeader ); if (hostName == "") { std::cout << "\n\n**** Empty browser bessage recieved ****\n\n"; return; } // Create clientsocket Socket clientSocket; clientSocket.createAndConnect( hostName.c_str() ); std::string toServerHeader = correctConnectionInfo( browserHeader ); std::cout << "Message to send by client :" << std::endl << toServerHeader; clientSocket.sendString( toServerHeader ); if ( headerComesWithData( toServerHeader ) ) { pipeDataTrough( browserSocket, clientSocket ); } std::string responseHeader = ""; if ( ! clientSocket.recieveHttpHeader( responseHeader ) ) { std::cout << "\n\n**** Error recieving HTTP header from web server ****\n\n"; return; } std::cout << responseHeader << std::endl << std::endl; if ( filteringPossible( responseHeader ) ) { filterContent(responseHeader, clientSocket, browserSocket ); } else { browserSocket.sendString( responseHeader ); pipeDataTrough( clientSocket, browserSocket ); } browserSocket.close(); }
std::string handleRequest( const std::string & header, std::string & request ) { static unsigned requestCount = -1; ++requestCount; std::string content; long int contentLength = 0; // fprintf( stderr, "Handling header '%s'\n", header.c_str() ); if( extractContentLength( header, contentLength ) ) { // fprintf( stderr, "content = '%s'\n", content.c_str() ); content = request.substr( 0, contentLength ); request = request.substr( contentLength ); // fprintf( stderr, "content = '%s', request = '%s'\n", content.c_str(), request.c_str() ); } std::string URL; if( ! extractURL( header, URL ) ) { return constructReply( "HTTP/1.1 400 Bad Request", "" ); } std::string host; if( ! extractHost( header, host ) ) { return constructReply( "HTTP/1.1 400 Bad Request", "" ); } std::transform( host.begin(), host.end(), host.begin(), & tolower ); // fprintf( stderr, "DEBUG: found 'http://%s%s'\n", host.c_str(), URL.c_str() ); // // Rather than rewrite the parser, just change URL to the appropriate // string from the body of the PUT. // URL = "?" + content; AttributeValueMap queryParameters; std::string::size_type i = URL.find( "?" ); while( i < URL.size() ) { // Properly encoded URLs will only have ampersands between // the key-value pairs, and equals between keys and values. std::string::size_type equalsIdx = URL.find( "=", i + 1 ); if( std::string::npos == equalsIdx ) { std::ostringstream error; error << "Malformed URL '" << URL << "': attribute without value; failing" << std::endl; fprintf( stderr, "%s", error.str().c_str() ); return constructReply( "HTTP/1.1 400 Bad Request", error.str() ); } std::string::size_type ampersandIdx = URL.find( "&", i + 1 ); if( std::string::npos == ampersandIdx ) { ampersandIdx = URL.size(); } std::string key = URL.substr( i + 1, equalsIdx - (i + 1) ); std::string value = URL.substr( equalsIdx + 1, ampersandIdx - (equalsIdx + 1 ) ); // fprintf( stderr, "DEBUG: key = '%s', value = '%s'\n", key.c_str(), value.c_str() ); queryParameters[ key ] = value; i = ampersandIdx; } // // Quick hack to handle signature V4. // std::string accessKeyID = queryParameters[ "AWSAccessKeyId" ]; if( accessKeyID.empty() ) { if( ! extractAccessKeyID( header, accessKeyID ) ) { return constructReply( "HTTP/1.1 400 Bad Request", "Unable to extract accessKeyID" ); } queryParameters[ "AWSAccessKeyId" ] = accessKeyID; } std::string method = "POST"; if( ! validateSignature( method, host, URL, queryParameters ) ) { return constructReply( "HTTP/1.1 401 Unauthorized", "Failed signature validation." ); } std::string action = queryParameters[ "Action" ]; if( action.empty() ) { return constructReply( "HTTP/1.1 400 Bad Request", "No action specified." ); } std::string response; ActionToHandlerMap::const_iterator ci = simulatorActions.find( action ); if( simulatorActions.end() == ci ) { std::ostringstream error; error << "Action '" << action << "' not found." << std::endl; fprintf( stderr, "%s", error.str().c_str() ); return constructReply( "HTTP/1.1 404 Not Found", error.str() ); } if( (*(ci->second))( queryParameters, response, requestCount ) ) { return constructReply( "HTTP/1.1 200 OK", response ); } else { return constructReply( "HTTP/1.1 406 Not Acceptable", response ); } }