I am building a web server from scratch and trying to make certain tasks faster by embedding C code into the mix for performance. Specifically I'm worried about how the std::string
class with the .find()
and other functions compare to straight pointer arithmetic.
#include <iostream>
#include <map>
#include <string>
std::map<std::string, std::string> http_request;
void parse_header( void * );
int main()
{
char * msg= "GET / HTTP/1.1\r\n"
"Host: 192.241.213.46:6880\r\n"
"Upgrade-Insecure-Requests: 1\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8\r\n"
"Accept-Language: en-us\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Connection: keep-alive\r\n\r\n";
parse_header( msg );
}
void parse_header( void *msg )
{
char *head = (char *) msg;
char *mid;
char *tail = head;
if( sizeof( msg ) == 0 )
{
return;
}
// Find request type
while( *head++ != ' ');
http_request[ "Type" ] = std::string( ( char * ) msg ).substr( 0 , ( head - 1) - tail );
// Find path
tail = head;
while( *head++ != ' ');
http_request[ "Path" ] = std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( head - 1) - tail );
// Find HTTP version
tail = head;
while( *head++ != '\r');
http_request[ "Version" ] = std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( head - 1) - tail );
// Map all headers from a key to a value
while( true )
{
tail = head + 1;
while( *head++ != '\r' );
mid = strstr( tail, ":" );
// Look for the failed strstr
if( tail > mid )
break;
http_request[ std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( mid ) - tail ) ] = std::string( ( char * ) msg ).substr( mid + 2 - ( char *) msg , ( head - 3 ) - mid );
}
// Determine if successful
std::cout << http_request[ "Host" ] << std::endl;
std::cout << http_request[ "Upgrade-Insecure-Requests" ] << std::endl;
std::cout << http_request[ "Accept" ] << std::endl;
std::cout << http_request[ "User-Agent" ] << std::endl;
std::cout << http_request[ "Accept-Language" ] << std::endl;
std::cout << http_request[ "Accept-Encoding" ] << std::endl;
std::cout << http_request[ "Connection" ] << std::endl;
}
Data comes in via the linux socket.send()
function, so it is a void *
type. I directly send that data to a parse_header
function to create a std::map
for easy access. Is it necessary to be this low-level, or can this speed be obtained by the STL?
Note: I killed OO design for a minimal example. The end-goal has an HTTP class.
Note++: I'd prefer to have this code review pertain to performance rather than c++ semantics, I'd like it to be as conforming as possible while also being fast and lightweight. This seems to be the purest form of the cluge of C/C++.
sizeof(msg) == 0
, I don't think this is what you meant. \$\endgroup\$nginx
\$\endgroup\$