diff options
-rw-r--r-- | http.c | 65 | ||||
-rw-r--r-- | http.h | 21 | ||||
-rw-r--r-- | plop.c | 11 |
3 files changed, 24 insertions, 73 deletions
@@ -4,18 +4,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/socket.h> -#include <sys/types.h> - -const char * method_str[] = { - [METHOD_GET] = "GET", - [METHOD_HEAD] = "HEAD", - [METHOD_POST] = "POST", - [METHOD_PUT] = "PUT", - [METHOD_DELETE] = "DELETE", - [METHOD_OPTIONS] = "OPTIONS", - [METHOD_PATCH] = "PATCH", -}; +#include <unistd.h> const char * status_str[] = { [STATUS_OK] = "200 OK", @@ -59,55 +48,35 @@ int respond_with_body(const int fd, const enum status status, const char * body) return -1; // TODO: Handle errors properly } - return send(fd, body, strlen(body), 0); + return write(fd, body, strlen(body)); } -/// Compares the `buffer` to list of supported methods. -/// \param buffer Pointer to the first byte of request -/// \return One of supported methods or METHOD_INVALID -enum method parse_method(const char * buffer) +/// Collects request between calls to `poll`. +/// \param fd Client socket +/// \param request Buffer with the request content +/// \return Number of bytes parsed, -1 if an error occured or 0 if expects more data +int collect_request(const int fd, char ** request) { - for (int i = 0; i < NUMBER_OF_METHODS; ++i) + static const int size = 4096; + + if (NULL == *request) { - if (0 == strncmp(method_str[i], buffer, strlen(method_str[i]))) + *request = malloc(size); + if (NULL == *request) { - return i; + return -1; } } - return METHOD_INVALID; -} - -/// Receives and parses request or part of it from a client. -/// \param fd Client socket -/// \param request Parser output and state -/// \return Number of bytes parsed or -1 if an error occurred -int parse_request(const int fd, struct request * const request) -{ - char buffer[10240] = {0}; - - int length = recv(fd, buffer, 10240, 0); - - if (-1 == length && EWOULDBLOCK != errno && EAGAIN != errno) - { - return -1; - } + // TODO: Expand buffer until EAGAIN or arbitrary limit + int length = read(fd, *request, size - 1); - if (0 == length) + if (0 == length || (-1 == length && EWOULDBLOCK != errno && EAGAIN != errno)) { return -1; // TODO: Handle errors properly } - request->method = parse_method(buffer); - - if (METHOD_INVALID == request->method) - { - // TODO: 501 Not Implemented - } - - request->body = malloc(length + 1); - memcpy(request->body, buffer, length); - request->body[length] = 0; + (*request)[length] = 0; return length; } @@ -1,25 +1,6 @@ #ifndef HTTP_H #define HTTP_H -enum method -{ - METHOD_GET, - METHOD_HEAD, - METHOD_POST, - METHOD_PUT, - METHOD_DELETE, - METHOD_OPTIONS, - METHOD_PATCH, - NUMBER_OF_METHODS, - METHOD_INVALID, -}; - -struct request -{ - enum method method; - char * body; -}; - enum status { STATUS_OK = 200, @@ -36,6 +17,6 @@ extern const char * status_str[]; int respond_only_status(int, enum status); int respond_with_body(int, enum status, const char *); -int parse_request(int, struct request *); +int collect_request(int, char **); #endif // HTTP_H @@ -89,20 +89,21 @@ int handle_client(struct pollfd * pfd, const int shift_by) return -1; // TODO: Handle errors properly } - struct request request = {METHOD_INVALID, NULL}; - parse_request(pfd->fd, &request); + char * request = NULL; - if (-1 == respond_with_body(pfd->fd, STATUS_OK, method_str[request.method])) + if (-1 == collect_request(pfd->fd, &request)) { - // TODO: Handle errors properly + return -1; // TODO: Handle errors properly } - free(request.body); + respond_with_body(pfd->fd, STATUS_OK, request); close(pfd->fd); (pfd - shift_by)->fd = -1; (pfd - shift_by)->events = pfd->events; + free(request); + return shift_by + 1; } |