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.
 
 

310 lines
8.5 KiB

#ifndef RESPONSE_TEST
#define RESPONSE_TEST value
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <stdbool.h>
#include "munit/munit.h"
#include "../src/readline.h"
#include "../src/requestresponse.h"
#include "../src/response.h"
typedef struct {
char *fullLine;
float version;
int statusCode;
char *statusMessage;
} firstLine;
static firstLine line1Examples[] = {
//Full Line, version status Code Status Message
{ "HTTP/1.1 200 OK", 1.1, 200, "OK" },
{ "HTTP/2.0 404 Not Found", 2.0, 404, "Not Found" },
{ NULL, 0, 0, NULL }
};
MunitResult testResponseNewStatus(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
responseBarebones(rsp);
munit_assert_int( rsp->statusCode, ==, 200 );
return MUNIT_OK;
}
MunitResult testResponseNewStatusMessage(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
responseBarebones(rsp);
munit_assert_string_equal( rsp->statusMessage, "OK" );
return MUNIT_OK;
}
MunitResult testResponseNewVersion(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
responseBarebones(rsp);
munit_assert_float( rsp->version, ==, 1.1 );
return MUNIT_OK;
}
MunitResult testResponseSetBody(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
responseBarebones(rsp);
responseSetBody( rsp, "Testing", 1 );
munit_assert_string_equal( rsp->body, "Testing" );
munit_assert_string_equal( getHeader( rsp->headers, "content-length" )->value, "7" );
return MUNIT_OK;
}
MunitResult testResponseToString(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
responseBarebones(rsp);
munit_assert_string_equal( responseToString( rsp ), "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n" );
responseSetBody( rsp, "Testing", 1 );
munit_assert_string_equal( responseToString( rsp ), "HTTP/1.1 200 OK\r\nContent-Length: 7\r\nContent-Type: text/plain\r\n\r\nTesting\r\n" );
return MUNIT_OK;
}
MunitResult testResponseFirstLineStatusCode(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp;
for ( firstLine *line = line1Examples; line->fullLine != NULL; line++ ){
rsp = newResponse();
responseFirstLine( rsp, line->fullLine );
munit_assert_int( rsp->statusCode, ==, line->statusCode );
free( rsp );
}
return MUNIT_OK;
}
MunitResult testResponseFirstLineStatusMessage(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp;
for ( firstLine *line = line1Examples; line->fullLine != NULL; line++ ){
rsp = newResponse();
responseFirstLine( rsp, line->fullLine );
munit_assert_string_equal( rsp->statusMessage, line->statusMessage );
free( rsp );
}
return MUNIT_OK;
}
MunitResult testResponseFirstLineVersion(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp;
for ( firstLine *line = line1Examples; line->fullLine != NULL; line++ ){
rsp = newResponse();
responseFirstLine( rsp, line->fullLine );
munit_assert_float( rsp->version, ==, line->version );
free( rsp );
}
return MUNIT_OK;
}
static void* setupSocketTests(const MunitParameter params[], void* user_data) {
int client_fd = 0;
struct sockaddr_in address;
memset( &address, 0, sizeof(address) );
struct hostent *host = gethostbyname("example.com");
Response *rsp = NULL;
if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
perror("socket failed");
return NULL;
}
address.sin_family = AF_INET;
address.sin_port = htons( 80 );
// We want the request to go out to whatever the host was resolved to
memcpy( &address.sin_addr, host->h_addr_list[0], host->h_length );
if((connect(client_fd, (struct sockaddr *)&address, sizeof(address)))<0) {
perror("connect failed");
return NULL;
}
char *toSend = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
if ( write( client_fd, toSend, strlen(toSend) ) != strlen(toSend) ){
perror( "Write Error" );
return NULL;
}
rsp = newResponseFromSocket( client_fd );
return rsp;
}
MunitResult testResponseFromSocketHeaderLength(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = ( Response * )user_data_or_fixture;
if ( rsp == NULL ) return MUNIT_ERROR;
//Check there are the right nubmer of haeders
// Unfortunately it changes from request to request so this is a "loose"
// check
munit_assert_int( countHeaders( rsp->headers ), >, 7 );
return MUNIT_OK;
}
MunitResult testResponseFromSocketStatusCode(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = ( Response * )user_data_or_fixture;
if ( rsp == NULL ) return MUNIT_ERROR;
//Check there are the right nubmer of haeders
munit_assert_int( rsp->statusCode, ==, 200 );
return MUNIT_OK;
}
MunitResult testResponseFromSocketBody(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = ( Response * )user_data_or_fixture;
Header *contentLength = getHeader( rsp->headers, "content-length" );
unsigned int length = 0;
if ( contentLength == NULL ) return MUNIT_ERROR;
munit_assert_int( atoi( contentLength->value ), ==, strlen( (char *)rsp->body ) );
//Check there are the right nubmer of haeders
munit_assert_int( rsp->statusCode, ==, 200 );
return MUNIT_OK;
}
MunitResult testConectionEstablished(const MunitParameter params[],
void* user_data_or_fixture){
Response *rsp = newResponse();
connectionEstablished(rsp);
munit_assert_string_equal(
responseToString( rsp ),
"HTTP/1.1 200 Connection Established\r\n\r\n"
);
return MUNIT_OK;
}
static MunitTest response_tests[] = {
{
"/new/status", /* name */
testResponseNewStatus, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/new/statusMessage", /* name */
testResponseNewStatusMessage, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/new/version", /* name */
testResponseNewVersion, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/set/body", /* name */
testResponseSetBody, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/to/string", /* name */
testResponseToString, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/to/string/connectionEstablished", /* name */
testConectionEstablished, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/line1/statusCode", /* name */
testResponseFirstLineStatusCode, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/line1/statusMessage", /* name */
testResponseFirstLineStatusMessage, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/line1/version", /* name */
testResponseFirstLineVersion, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/fromSocket/headerLength", /* name */
testResponseFromSocketHeaderLength, /* test */
setupSocketTests, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/fromSocket/statusCode", /* name */
testResponseFromSocketStatusCode, /* test */
setupSocketTests, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
}, {
"/fromSocket/body", /* name */
testResponseFromSocketBody, /* test */
setupSocketTests, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
},
/* Mark the end of the array with an entry where the test
* function is NULL */
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
MunitSuite response_test_suite = {
"/response", /* name */
response_tests, /* tests */
NULL, /* suites */
1, /* iterations */
MUNIT_SUITE_OPTION_NONE /* options */
};
#ifndef MAINTEST
#define MAINTEST
int main (int argc, char* argv[]) {
return munit_suite_main(&response_test_suite, NULL, argc, argv);
}
#endif /* ifndef MAINTEST */
#endif /* ifndef RESPONSE_TEST */