Yet Another Intercepting Proxy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

205 lines
5.0 KiB

#include "request.h"
Request* newRequest(){
Request *request = malloc(sizeof(Request));
memset(request, 0, sizeof(Request));
request->method = NULL;
request->protocol = NULL;
request->host = NULL;
request->path = NULL;
request->headers = NULL;
request->queryString = NULL;
request->body = NULL;
return request;
}
void requestFirstLine( Request *req, char line[] ){
char method[20] = {'\0'}; //Get, post, etc.
// This may contain the method, the path, the domain and so on
char *url = malloc(sizeof(char) *2048);
memset(url, '\0', sizeof(char) * 2048);
char *currentPos = url;
float version = 0;
char host[254] = {'\0'};
int port = -1; // 0 is a valid port number, -1 isn't
//https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
char path[2000] = {'\0'};
sscanf( line, "%20s %2048s HTTP/%f", method, url, &version );
req->method = strdup(method);
req->version = version;
//We've pulled out the easy bits. Now to go through the url and pull out what we need
int protEnd = strpos(url, "://" );
if ( protEnd > -1 ){
req->protocol = strndup( url, protEnd );
currentPos += protEnd + 3;
} else {
req->protocol = strdup("");
}
sscanf( currentPos, "%253[^:/]", host );
if ( strlen( host ) > 0 ){
currentPos = currentPos + strlen(host);
req->host = strdup(host);
} else {
req->host = strdup("");
}
if ( currentPos[0] == ':' ){
currentPos++;
sscanf( currentPos, "%i", &port );
req->port = port;
currentPos += (int)floor( log10( port ) ) + 1;
} else {
req->port = -1;
}
sscanf( currentPos, "%2000[^? ]", path );
if ( strlen( path ) > 0 ){
currentPos += strlen(path);
req->path = strdup(path);
} else {
req->path = strdup("");
}
if ( strlen( currentPos ) > 0 ){
req->queryString = strdup( currentPos );
} else {
req->queryString = strdup("");
}
//We try and work out port and protocol if we don't have them
if ( req->port == -1){
if ( strcmp( "https", req->protocol ) == 0 )
req->port = 443;
else
req->port = 80;
}
if ( strlen(req->protocol) == 0 ){
free(req->protocol);
if ( req->port == 443 )
req->protocol = strdup("https");
else
req->protocol = strdup("http");
}
free(url);
}
Request* newRequestFromSocket(int socket){
Request *req = newRequest();
int valread;
char line[1024] = {0};
// The first line will give us some important information
valread = fdReadLine( socket, line, 1024);
requestFirstLine(req, line);
//a length of 2 will indicate an empty line which will split the headers
//from the body (if there is a body)
valread = fdReadLine( socket, line, 1024);
while ( valread > 2 ){
requestAddHeader( req, line );
//I believe at this point all the headers are done.
valread = fdReadLine( socket , line, 1024);
}
//TODO: make requests work with a body
//contentLength = getHeader( req->headers, "content-length" );
//if ( contentLength != NULL ){
// printf( "Content length is %i\n", atoi(contentLength->value) );
//}
return req;
}
Request* newRequestFromString(char *string){
// We don't want to modify the original string
char *str = strdup(string);
Request *req = newRequest();
int valread;
//Find the new line
char *occurance = strchr( str, '\n' );
occurance[0] = '\0';
requestFirstLine(req, str);
str = occurance + 1;
occurance = strchr( str, '\n' );
occurance[0] = '\0';
while ( strlen(str) > 1 ){
requestAddHeader( req, str );
str = occurance + 1;
occurance = strchr( str, '\n' );
occurance[0] = '\0';
}
//TODO: make requests work with a body
//contentLength = getHeader( req->headers, "content-length" );
//if ( contentLength != NULL ){
// printf( "Content length is %i\n", atoi(contentLength->value) );
//}
return req;
}
char* requestToString( Request *req){
unsigned int fullLength = strlen(req->method) + 1 + sizeof( req->path ) +
//11 = [space]http/1.1\r\n
sizeof( req->queryString ) + 11 + headerListCharLength( req->headers );
if ( strcmp( req->method, "CONNECT" ) == 0 )
fullLength += sizeof(req->host);
char retString[fullLength];
memset( retString, '\0', fullLength );
if ( strcmp( req->method, "CONNECT" ) == 0 )
sprintf(retString, "%s %s HTTP/%.1f\r\n%s\r\n", req->method,
req->host, req->version, headersToString(req->headers));
else
sprintf(retString, "%s %s%s HTTP/%.1f\r\n%s\r\n", req->method,
req->path, req->queryString, req->version,
headersToString(req->headers));
// rsp->statusMessage,headersToString(rsp->headers),rsp->body);
return strdup(retString);
//return strdup(retString);
}
void requestAddHeader( Request *req, char header[] ){
if ( req->headers == NULL ){
req->headers = malloc(sizeof( HeaderList ));
req->headers->header = newHeader( header );
req->headers->next = NULL;
} else
addHeader( req->headers, header );
}
void freeRequest( Request *req ){
if ( req == NULL ) return;
free(req->method);
free(req->protocol);
free(req->host);
free(req->path);
freeHeaderList( req->headers );
free(req->queryString);
free(req->body);
free(req);
}