Skip to content

Instantly share code, notes, and snippets.

Created March 19, 2016 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/3f4e323a09c38c3ed87a to your computer and use it in GitHub Desktop.
Save anonymous/3f4e323a09c38c3ed87a to your computer and use it in GitHub Desktop.
parse.c
bool parse(const char* line, char* abs_path, char* query)
{
/* method SP request-target SP HTTP-version CRLF
* GET /path/to/file.extension?query HTTP/1.1\r\n
* very likely inputs
* GET /path/to/file.extension HTTP/1.1\r\n
* GET path/to/file.extension?query HTTP/1.1\r\n
* GET "/path/to/file.extension?query" HTTP/1.1\r\n
* GET /path/to/file.extension?query HTTP/1.0\r\n
*/
// makes sure method is GET
// create a buffer in which to hold line
char buffer[strlen(line)];
// copy the line into the buffer for further parsing
strcpy(buffer, line);
// parse up until the first space which should be the method
char* method = strtok(buffer, " ");
// if the method is GET (the only supported method), continue, otherwise
if(strcmp(method, "GET") != 0)
{
// error
error(405);
return false;
}
// makes sure request target begins with /
// store the next token into target
// this token should end by the next space
char* target = strtok(NULL, " ");
// if first character isn't /
if(target[0] != '/')
{
// error
error(501);
return false;
}
// otherwise, continue
// makes sure the target doesn't contain any ""
// iterate over every character
for(int i = 0, len = strlen(target); i < len; i++)
{
// if current character is a '
if(target[i] == '"')
{
error(400);
return false;
}
}
// make sure version is HTTP/1.1 and \r\n
// The next token should be the version
// store the next token into a variable called version
char* version = strtok(NULL, " ");
// compare HTTP/1.1 supported version vs whatever version the user
// may be using
if(strcmp(version, "HTTP/1.1\r\n") != 0)
{
// error if not supported
error(505);
return false;
}
// else we continue
// store target up until ? in the abs_path if it exists
// else there's nothing to do
// to do this, let's iterate over all the chars in target
// break in case we find an ? or an space, whatever comes first
int i;
for(i = 0; target[i] != '?' && target[i] != ' ' && target[i] != '\0'; i++)
{
abs_path[i] = target[i];
}
// store the query substring in target in query
// it comes after ? and before an space
// if there's space after ? return ""
// else the substring before the space
if(target[i] == '?' && target[i + 1] != ' ')
{
i++;
for(int z = 0; target[i] != ' ' && target[i] != '\0'; i++, z++)
{
query[z] = target[i];
}
}
else if(target[i] == '?' && target[i + 1] == ' ')
{
query[0] = '\0';
}
else if(target[i] == ' ')
{
query[0] = '\0';
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment