Fixed bug with writing responses
Connections are now closed after response is send if client requested "Connection: close"
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user