#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); } }