summaryrefslogtreecommitdiff
path: root/datastore-leveldb/src/server_eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'datastore-leveldb/src/server_eh.c')
-rw-r--r--datastore-leveldb/src/server_eh.c222
1 files changed, 0 insertions, 222 deletions
diff --git a/datastore-leveldb/src/server_eh.c b/datastore-leveldb/src/server_eh.c
deleted file mode 100644
index 1fd3f9e..0000000
--- a/datastore-leveldb/src/server_eh.c
+++ /dev/null
@@ -1,222 +0,0 @@
-#include "server_eh.h"
-#include "http_parser.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <unistd.h>
-
-// utils
-
-static inline int setnonblock(int fd) {
- int flags = fcntl(fd, F_GETFL);
- if (flags < 0) return flags;
- flags |= O_NONBLOCK;
- if (fcntl(fd, F_SETFL, flags) < 0) return -1;
- return 0;
-}
-
-#define REQUEST_BUFFER_SIZE 2048
-
-#define alloc_cpy(dest, src, len) \
- dest = (char*)malloc(len + 1);\
- memcpy(dest, src, len);\
- dest[len] = '\0';
-
-// http_parser callback and settings
-
-int null_cb(http_parser *parser) { return 0; }
-
-static int count = 0;
-int url_cb(http_parser *parser, const char *buf, size_t len) {
- count++;
- struct http_request *request = (struct http_request *) parser->data;
- request->method = parser->method;
- request->http_major = parser->http_major;
- request->http_minor = parser->http_minor;
- alloc_cpy(request->url, buf, len)
- if (count % 100 == 0) printf("%d\n", count);
- return 0;
-}
-
-int header_field_cb(http_parser *parser, const char *buf, size_t len) {
- struct http_request *request = (struct http_request *) parser->data;
- struct http_header *header = add_http_header(request);
- alloc_cpy(header->name, buf, len)
- return 0;
-}
-
-int header_value_cb(http_parser *parser, const char *buf, size_t len) {
- struct http_request *request = (struct http_request *) parser->data;
- struct http_header *header = request->headers;
- while (header->next != NULL) {
- header = header->next;
- }
- alloc_cpy(header->value, buf, len)
- return 0;
-}
-
-int body_cb(http_parser *parser, const char *buf, size_t len) {
- struct http_request *request = (struct http_request *) parser->data;
- alloc_cpy(request->body, buf, len)
- return 0;
-}
-
-static http_parser_settings parser_settings =
-{
- .on_message_begin = null_cb
- ,.on_message_complete = null_cb
- ,.on_headers_complete = null_cb
- ,.on_header_field = header_field_cb
- ,.on_header_value = header_value_cb
- ,.on_url = url_cb
- ,.on_body = body_cb
-};
-
-struct http_request *parse_request(char *request_data, int len) {
- http_parser *parser = malloc(sizeof(http_parser));
- http_parser_init(parser, HTTP_REQUEST);
- struct http_request *request = new_http_request();
- parser->data = request;
- int res = http_parser_execute(parser, &parser_settings, request_data, len);
- if (res == len) {
- if (http_should_keep_alive(parser)) {
- request->flags |= F_HREQ_KEEPALIVE;
- }
- free(parser);
- return request;
- }
- delete_http_request(request);
- free(parser);
- return NULL;
-}
-
-// libev callbacks and client structures
-
-struct client {
- int fd;
- ev_io ev_accept;
- ev_io ev_read;
- ev_io ev_write;
- char *request_data;
- struct http_request *request;
- void (*handle_request)(struct http_request *request, int fd);
-};
-
-static void write_cb(struct ev_loop *loop, struct ev_io *w, int revents) {
- if (!(revents & EV_WRITE)) {
- ev_io_stop(EV_A_ w);
- return;
- }
- struct client *client =
- (struct client *)
- (((char *) w) - offsetof(struct client, ev_write));
- struct http_request *request = client->request;
- if (request == NULL) {
- write(client->fd, "HTTP/1.1 400 Bad Request\r\n\r\n", 24);
- close(client->fd);
- free(client->request_data);
- free(client);
- ev_io_stop(EV_A_ w);
- return;
- }
- client->handle_request(request, client->fd);
- delete_http_request(request);
- free(client->request_data);
- free(client);
- ev_io_stop(EV_A_ w);
-}
-
-static void read_cb(struct ev_loop *loop, struct ev_io *w, int revents) {
- if (!(revents & EV_READ)) {
- ev_io_stop(EV_A_ w);
- return;
- }
- struct client *client =
- (struct client *)
- (((char *) w) - offsetof(struct client, ev_read));
- char *rbuff[REQUEST_BUFFER_SIZE + 1];
- int sum = 0, len = 0;
- client->request_data = NULL;
- do {
- len = read(client->fd, &rbuff, REQUEST_BUFFER_SIZE);
- sum += len;
- if (len < REQUEST_BUFFER_SIZE)
- rbuff[len] = '\0';
- if (client->request_data == NULL) {
- client->request_data = malloc(len+1);
- memcpy(client->request_data, rbuff, len);
- } else {
- client->request_data = realloc(client->request_data, sum + 1);
- memcpy(client->request_data + sum - len, rbuff, len);
- }
- } while (len == REQUEST_BUFFER_SIZE);
- client->request = NULL;
- client->request = parse_request(client->request_data, len);
- ev_io_stop(EV_A_ w);
- ev_io_init(&client->ev_write, write_cb, client->fd, EV_WRITE);
- ev_io_start(loop, &client->ev_write);
-}
-
-static void accept_cb(struct ev_loop *loop, struct ev_io *w, int revents) {
- struct client *main_client =
- (struct client *)
- (((char *) w) - offsetof(struct client, ev_accept));
- struct sockaddr_in client_addr;
- socklen_t client_len = sizeof(struct sockaddr_in);
- int client_fd = accept(w->fd, (struct sockaddr *) &client_addr, &client_len);
- if (client_fd == -1) {
- return;
- }
- if (setnonblock(client_fd) < 0) {
- perror("failed to set client socket to nonblock");
- return;
- }
- struct client *client = malloc(sizeof(struct client));
- client->handle_request = main_client->handle_request;
- client->fd = client_fd;
- ev_io_init(&client->ev_read, read_cb, client->fd, EV_READ);
- ev_io_start(loop, &client->ev_read);
-}
-
-int http_server_loop(struct http_server *server) {
- server->loop = ev_default_loop(0);
- int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (listen_fd < 0) {
- perror("listen failed(socket)");
- return -1;
- }
- int reuseaddr_on = 1;
- if (setsockopt(
- listen_fd,
- SOL_SOCKET,
- SO_REUSEADDR,
- &reuseaddr_on,
- sizeof(server->listen_addr)) == -1) {
- perror("setsockopt failed");
- return -1;
- }
- struct sockaddr *listen_addr = (struct sockaddr *) server->listen_addr;
- if (bind(listen_fd, listen_addr, sizeof(*listen_addr)) < 0) {
- perror("bind failed");
- return -1;
- }
- if (listen(listen_fd, 5) < 0) {
- perror("listen failed(listen)");
- return -1;
- }
- if (setnonblock(listen_fd) < 0) {
- perror("failed to set server socket to nonblock");
- return -1;
- }
- struct client *main_client = malloc(sizeof(struct client));
- main_client->handle_request = server->handle_request;
- ev_io_init(&main_client->ev_accept, accept_cb, listen_fd, EV_READ);
- ev_io_start(server->loop, &main_client->ev_accept);
- server->ev_accept = &main_client->ev_accept;
- ev_loop(server->loop, 0);
- return 0;
-}