blob: d049f301a74051af0867e24dea6c318914c95574 [file] [log] [blame] [raw]
/*
Copyright: Boaz segev, 2016-2017
License: MIT
Feel free to copy, use and enjoy according to the license provided.
*/
#include "http1_request.h"
#include "http1.h"
#include <string.h>
#include <strings.h>
/* *****************************************************************************
Initialization
***************************************************************************** */
/** Creates / allocates a protocol version's request object. */
http_request_s *http1_request_create(void) {
http1_request_s *req = malloc(sizeof(*req));
req->request.body_file = 0;
http1_request_clear((http_request_s *)req);
return (http_request_s *)req;
}
/** Destroys the request object. */
void http1_request_destroy(http_request_s *request) {
http1_request_clear(request);
free(request);
}
/** Recycle's the request object, clearing it's data. */
void http1_request_clear(http_request_s *request) {
if (request->body_file)
close(request->body_file);
*request = (http_request_s){.http_version = HTTP_V1, .fd = request->fd};
((http1_request_s *)request)->buffer_pos = 0;
((http1_request_s *)request)->header_pos = 0;
}
/** Duplicates a request object. */
http_request_s *http1_request_dup(http_request_s *request) {
http1_request_s *req = (http1_request_s *)http1_request_create();
*req = *((http1_request_s *)request);
return (http_request_s *)req;
}
/* *****************************************************************************
Header Access
***************************************************************************** */
/** searches for a header in the request's data store, returning a `header_s`
* structure with all it's data.*/
http_header_s http1_request_header_find(http_request_s *request,
const char *header, size_t header_len) {
for (size_t i = 0; i < request->headers_count; i++) {
if (((http1_request_s *)request)->headers[i].name_len == header_len &&
strncasecmp((char *)header,
(char *)((http1_request_s *)request)->headers[i].name,
header_len) == 0)
return ((http1_request_s *)request)->headers[i];
}
return (http_header_s){.name = NULL};
}
/** Starts itterating the header list, returning the first header. Header
* itteration is NOT thread-safe. */
http_header_s http1_request_header_first(http_request_s *request) {
((http1_request_s *)request)->header_pos = 0;
if (!request->headers_count)
return (http_header_s){.name = NULL};
return ((http1_request_s *)request)->headers[0];
}
/**
* Continues itterating the header list.
*
* Returns NULL header data if at end of list (header.name == NULL);
*
* Header itteration is NOT thread-safe. */
http_header_s http1_request_header_next(http_request_s *request) {
((http1_request_s *)request)->header_pos++;
if (((http1_request_s *)request)->header_pos >= request->headers_count)
return (http_header_s){.name = NULL};
return ((http1_request_s *)request)
->headers[((http1_request_s *)request)->header_pos];
}