8abebaa361f98909e9406a0925341b16a88c1cab
[blerg.git] / http_blerg.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <microhttpd.h>
5 #include "database.h"
6 #include "tags.h"
7
8 #define URL_INFO_AUTHOR 0x1
9 #define URL_INFO_RECORD 0x2
10 #define DERP "DERP DERP DERP"
11 #define NOTFOUND "<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1>I couldn't find that.</body></html>"
12
13 struct MHD_Response *response404;
14
15 void init_responses() {
16         response404 = MHD_create_response_from_data(strlen(NOTFOUND), NOTFOUND, MHD_NO, MHD_NO);
17 }
18
19 int respond_404(struct MHD_Connection *connection) {
20         return MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response404);
21 }
22
23 int parse_url_info(const char *url, char *author, uint64_t *record) {
24         const char *c;
25         int ret = 0;
26         int len;
27
28         c = strchr(url, '/');
29         if (c == NULL) {
30                 len = strlen(url);
31         } else {
32                 len = c - url;
33         }
34         if (len == 0)
35                 return 0;
36         memcpy(author, url, len);
37         author[len] = 0;
38         ret |= URL_INFO_AUTHOR;
39
40         if (c != NULL && c[1] != 0) {
41                 *record = strtoull(c + 1, NULL, 10);
42                 ret |= URL_INFO_RECORD;
43         }
44
45         return ret;
46 }
47
48 static int
49 ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const char *method,
50           const char *version, const char *upload_data, size_t *upload_data_size, void **ptr) {
51         struct MHD_Response *response;
52         int ret, len;
53         char author[33];
54         uint64_t record;
55         char *data;
56
57         if (strncmp(url, "/get", 4) == 0 && strlen(url) > 4) {
58                 if (strcmp(method, MHD_HTTP_METHOD_GET) != 0)
59                         return MHD_NO;
60                 if (url[4] != '/')
61                         return respond_404(connection);
62                 ret = parse_url_info(url + 5, author, &record);
63                 if (ret & URL_INFO_AUTHOR == 0)
64                         return respond_404(connection);
65
66                 if (ret & URL_INFO_RECORD) {
67                         if (*ptr == NULL) {
68                                 *ptr = (void *) 1;
69                                 return MHD_YES;
70                         } else {
71                                 *ptr == NULL;
72
73                                 struct blerg *b = blerg_open(author);
74                                 ret = blerg_fetch(b, record, &data, &len);
75                                 blerg_close(b);
76
77                                 if (ret == 0) {
78                                         return respond_404(connection);
79                                 } else {
80                                         response = MHD_create_response_from_data(len, data, MHD_YES, MHD_NO);
81                                         ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
82                                 }
83                                 MHD_destroy_response(response);
84                                 return ret;
85                         }
86                 } else {
87                         if (*ptr == NULL) {
88                                 *ptr = (void*) 1;
89                                 return MHD_YES;
90                         } else {
91                                 *ptr == NULL;
92                                 response = MHD_create_response_from_data(strlen(DERP), DERP, MHD_NO, MHD_NO);
93                                 ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
94                                 MHD_destroy_response(response);
95                                 return ret;
96                         }
97                 }
98         } else if (strncmp(url, "/put", 4) == 0) {
99         } else {
100                 return respond_404(connection);
101         }
102 }
103
104
105 int main(int argc, char *argv[]) {
106         struct MHD_Daemon *daemon;
107         fd_set rs, ws, es;
108         int max;
109
110         init_responses();
111
112         daemon = MHD_start_daemon(MHD_USE_DEBUG, 8080, NULL, NULL, &ahc_derp, NULL, MHD_OPTION_END);
113         if (daemon == NULL) {
114                 fprintf(stderr, "Could not start web server\n");
115                 return 1;
116         }
117
118         while (1) {
119                 FD_ZERO(&rs); FD_ZERO(&ws); FD_ZERO(&es);
120                 if (MHD_get_fdset(daemon, &rs, &ws, &es, &max) != MHD_YES) {
121                         fprintf(stderr, "Fatal error getting fd sets\n");
122                         break;
123                 }
124                 select(max + 1, &rs, &ws, &es, NULL);
125                 MHD_run(daemon);
126         }
127         MHD_stop_daemon(daemon);
128         return 0;
129 }