From 7a388dad85152a203033c14fee3c64607301865a Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sat, 8 Jul 2023 15:06:33 -0300 Subject: libactivity: (tmp name) http request parse the parse works via callbacks, registered to a method and path. further work will be done to simplify extraction of path, and to make the request struct more private. missing the parsing and handling of reponses. Signed-off-by: Anna (navi) Figueiredo Gomes --- src/main.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..09cf045 --- /dev/null +++ b/src/main.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "buffer.h" +#include "http.h" + +static struct reply *handle(struct request *req, void *data) { + (void)data; + struct reply *ret = malloc(sizeof(struct reply)); + cJSON *obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "path", req->path); + cJSON_AddStringToObject(obj, "query", req->query); + cJSON_AddStringToObject(obj, "method", req->method); + cJSON_AddStringToObject(obj, "version", req->http_version); + cJSON_AddStringToObject(obj, "hostname", http_get_header(req, "Host")); + if (req->data) { + cJSON_AddItemReferenceToObject(obj, "data", cJSON_Parse(req->data)); + } + + ret->status = 200; + ret->body = cJSON_Print(obj); + cJSON_Delete(obj); + + return ret; +} + +int main(int argc, char **argv) { + (void)argc; + (void)argv; + int server_fd = 0; + int client_fd = 0; + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = INADDR_ANY, + .sin_port = htons(45748), + }; + + int addrlen = sizeof(addr); + + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket failed"); + return EXIT_FAILURE; + } + + int opt = 1; + + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { + perror("setsockopt failed"); + return EXIT_FAILURE; + } + + if (bind(server_fd, (struct sockaddr*)&addr, addrlen) < 0) { + perror("bind failed"); + return EXIT_FAILURE; + } + + if (listen(server_fd, 16) < 0) { + perror("listen failed"); + return EXIT_FAILURE; + } + + bool running = true; + ssize_t rlen; + char buf[1025]; + struct buffer *request, *reply; + struct reply *rpy; + + struct http *http = http_init(); + + http_register_handler(http, "GET", "/", NULL, &handle); + http_register_handler(http, "GET", "/nyaa", NULL, &handle); + http_register_handler(http, "POST", "/nyaa", NULL, &handle); + + while (running) { + if ((client_fd = accept(server_fd, + (struct sockaddr*)&addr, (socklen_t*)&addrlen)) < 0) { + perror("accept failed"); + return EXIT_FAILURE; + } + + if ((rlen = read(client_fd, buf, 1024)) < 0) { + perror("read failed"); + return EXIT_FAILURE; + } + + buf[rlen] = '\0'; + request = buf_new(buf); + + while (rlen >= 1024) { + if ((rlen = read(client_fd, buf, 1024)) < 0) { + perror("read failed"); + return EXIT_FAILURE; + } + buf[rlen] = '\0'; + buf_append(request, buf); + } + + printf("%s\n", request->data); + + rpy = http_handle_request(http, request); + reply = http_build_reply(rpy); + free(rpy); + + write(client_fd, reply->data, reply->size); + + buf_del(&request); + + close(client_fd); + } +} -- cgit v1.2.3