Fixed bug with writing responses

Connections are now closed after response is send if client requested "Connection: close"
This commit is contained in:
2014-07-29 21:23:36 +01:00
parent 31e1ff4f97
commit e8d1e4d7d9
6 changed files with 23 additions and 4 deletions

View File

@@ -88,6 +88,7 @@ http_response* server_process_request(config_server* config, http_request *reque
if (filepath_actual == NULL) { if (filepath_actual == NULL) {
warning("realpath: not found/error", true); warning("realpath: not found/error", true);
response = http_response_create_builtin(404, "File not found"); response = http_response_create_builtin(404, "File not found");
http_header_list_add(response->headers, http_header_new(HEADER_CONNECTION, "close"), false);
return response; return response;
} }
//Check that the file is within the server directory of the host //Check that the file is within the server directory of the host
@@ -116,6 +117,7 @@ http_response* server_process_request(config_server* config, http_request *reque
if (file == NULL) { if (file == NULL) {
warning("failed to open file for reading", true); warning("failed to open file for reading", true);
response = http_response_create_builtin(404, "File not found"); response = http_response_create_builtin(404, "File not found");
http_header_list_add(response->headers, http_header_new(HEADER_CONNECTION, "close"), false);
return response; return response;
} }
@@ -141,5 +143,11 @@ http_response* server_process_request(config_server* config, http_request *reque
free(filepath_requested); free(filepath_requested);
free(filepath_actual); free(filepath_actual);
//Check to see if client requested the connection be closed
http_header* request_connection = http_header_list_get(request->headers, HEADER_CONNECTION);
if (request_connection != NULL && strcasecmp(request_connection->content, "close") == 0) {
http_header_list_add(response->headers, http_header_new(HEADER_CONNECTION, "close"), false);
}
return response; return response;
} }

View File

@@ -180,6 +180,7 @@ void http_header_list_add(http_header_list* list, http_header *header, bool repl
free(header); free(header);
} }
http_header* http_header_list_get(http_header_list* list, const char* name) { http_header* http_header_list_get(http_header_list* list, const char* name) {
http_header *elem;
HTTP_HEADER_FOREACH(list, elem) { HTTP_HEADER_FOREACH(list, elem) {
if (strcmp(elem->name, name) == 0) { if (strcmp(elem->name, name) == 0) {
return elem; return elem;
@@ -190,6 +191,7 @@ http_header* http_header_list_get(http_header_list* list, const char* name) {
http_header** http_header_list_getall(http_header_list* list, const char* name, size_t *out_header_count) { http_header** http_header_list_getall(http_header_list* list, const char* name, size_t *out_header_count) {
http_header **headers = NULL; http_header **headers = NULL;
size_t count = 0; size_t count = 0;
http_header *elem;
HTTP_HEADER_FOREACH(list, elem) { HTTP_HEADER_FOREACH(list, elem) {
if (strcmp(elem->name, name) == 0) { if (strcmp(elem->name, name) == 0) {
count++; count++;
@@ -245,6 +247,7 @@ char* http_request_write(http_request *req) {
req->req->version == HTTP10 ? "HTTP/1.0" : "HTTP/1.1" req->req->version == HTTP10 ? "HTTP/1.0" : "HTTP/1.1"
); );
http_header *elem;
HTTP_HEADER_FOREACH(req->headers, elem) { HTTP_HEADER_FOREACH(req->headers, elem) {
utstring_printf(output, "%s: %s\r\n", utstring_printf(output, "%s: %s\r\n",
elem->name, elem->content); elem->name, elem->content);
@@ -333,9 +336,13 @@ char* http_response_write(http_response *resp) {
char dateStr[100] = {0}; char dateStr[100] = {0};
strftime(dateStr, 99, FORMAT_HEADER_DATE, timeinfo); strftime(dateStr, 99, FORMAT_HEADER_DATE, timeinfo);
http_header_list_add(resp->headers, http_header_new(HEADER_DATE, dateStr), true); http_header_list_add(resp->headers, http_header_new(HEADER_DATE, dateStr), true);
//Add server identifier header
http_header_list_add(resp->headers, http_header_new(HEADER_SERVER, SERVER_NAME), true);
} }
//write headers //write headers
http_header *elem;
HTTP_HEADER_FOREACH(resp->headers, elem) { HTTP_HEADER_FOREACH(resp->headers, elem) {
utstring_printf(output, "%s: %s\r\n", elem->name, elem->content); utstring_printf(output, "%s: %s\r\n", elem->name, elem->content);
} }
@@ -419,6 +426,7 @@ char* http_chunks_terminate(http_header_list *footers) {
utstring_printf(output, "0\r\n"); utstring_printf(output, "0\r\n");
if (footers != NULL) { if (footers != NULL) {
//write footers //write footers
http_header *elem;
HTTP_HEADER_FOREACH(footers, elem) { HTTP_HEADER_FOREACH(footers, elem) {
utstring_printf(output, "%s: %s\r\n", elem->name, elem->content); utstring_printf(output, "%s: %s\r\n", elem->name, elem->content);
} }

View File

@@ -67,7 +67,7 @@ extern "C" {
extern UT_icd http_header_icd; extern UT_icd http_header_icd;
#define HTTP_HEADER_FOREACH(list, elem) \ #define HTTP_HEADER_FOREACH(list, elem) \
for ( http_header *elem= (http_header*)utarray_next(list,NULL); \ for (elem= (http_header*)utarray_next(list,NULL); \
elem!= NULL; \ elem!= NULL; \
elem=(http_header*)utarray_next(list,elem)) elem=(http_header*)utarray_next(list,elem))

View File

@@ -171,13 +171,13 @@ void skt_elem_write_response(skt_elem *elem, http_response *response, bool dispo
char *response_str = http_response_write(response); char *response_str = http_response_write(response);
utstring_printf(elem->info->write, "%s", response_str); utstring_printf(elem->info->write, "%s", response_str);
free(response_str); free(response_str);
if (dispose == true) {
http_response_delete(response);
}
http_header* connection_header = http_header_list_get(response->headers, HEADER_CONNECTION); http_header* connection_header = http_header_list_get(response->headers, HEADER_CONNECTION);
if (connection_header != NULL && strcasecmp(connection_header->content, "close") == 0) { if (connection_header != NULL && strcasecmp(connection_header->content, "close") == 0) {
elem->info->close_afterwrite = true; elem->info->close_afterwrite = true;
} }
if (dispose == true) {
http_response_delete(response);
}
} }
void skt_elem_delete(skt_elem* elem) { void skt_elem_delete(skt_elem* elem) {
if (elem->info!=NULL) skt_delete(elem->info); if (elem->info!=NULL) skt_delete(elem->info);

View File

@@ -12,6 +12,8 @@
extern "C" { extern "C" {
#endif #endif
#define SERVER_NAME "KHTTP/0.1"
#include <stdbool.h> #include <stdbool.h>
#include "http_parser.h" #include "http_parser.h"
#include "socket.h" #include "socket.h"

View File

@@ -4,4 +4,5 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Referer: https://www.google.co.uk/ Referer: https://www.google.co.uk/
Accept-Language: en-US,en;q=0.8 Accept-Language: en-US,en;q=0.8
Connection: close