1 /* Blerg is (C) 2011 The Dominion of Awesome, and is distributed under a
2 * BSD-style license. Please see the COPYING file for details.
8 #include <yajl/yajl_gen.h>
12 #include "subscription.h"
14 #include "canned_responses.h"
18 yajl_gen_config yajl_c = { 0, 0 };
20 int check_auth(const char *username) {
21 if (username == NULL || username[0] == 0) {
26 const char *given_token = cgi_getcookie("auth");
27 if (!auth_check_token(username, given_token)) {
35 void respond_for_range(struct blerg *b, uint64_t from, uint64_t to) {
36 const unsigned char *ybuf;
40 uint64_t record_count = blerg_get_record_count(b);
42 printf("Content-type: application/json\r\n\r\n");
44 if (from > to || from >= record_count || to >= record_count || to - from > 99) {
45 respond_JSON_Failure();
49 g = yajl_gen_alloc(&yajl_c, NULL);
50 yajl_gen_array_open(g);
52 for (i = to; i != from - 1; i--) {
53 json_generate_one_record(g, NULL, b, i, 0);
54 yajl_gen_get_buf(g, &ybuf, &len);
55 fwrite(ybuf, len, 1, stdout);
59 yajl_gen_array_close(g);
60 yajl_gen_get_buf(g, &ybuf, &len);
61 fwrite(ybuf, len, 1, stdout);
65 void respond_blergref_list(struct blergref * results, int i) {
66 const unsigned char *ybuf;
73 printf("Content-type: application/json\r\n\r\n");
74 g = yajl_gen_alloc(&yajl_c, NULL);
76 yajl_gen_array_open(g);
79 b = blerg_open(results[i].author);
81 json_generate_one_record(g, results[i].author, b, results[i].record, 0);
84 yajl_gen_get_buf(g, &ybuf, &len);
85 fwrite(ybuf, len, 1, stdout);
91 yajl_gen_array_close(g);
92 yajl_gen_get_buf(g, &ybuf, &len);
93 fwrite(ybuf, len, 1, stdout);
97 int main(int argc, char *argv[]) {
101 struct url_info info;
107 if (cgi_init() != CGIERR_NONE)
110 path = getenv("PATH_INFO");
115 request_method = getenv("REQUEST_METHOD");
116 if (request_method == NULL) {
117 fprintf(stderr, "Request method is null!?\n");
121 if (strncmp(path, "/get", 4) == 0 && strlen(path) > 4) {
122 if (strncmp(request_method, "GET", 4) != 0) {
127 if (path[4] != '/') {
132 ret = parse_url_info(path + 5, &info);
133 if ((ret & URL_INFO_NAME) == 0) {
138 if (!blerg_exists(info.name)) {
143 struct blerg *b = blerg_open(info.name);
145 if ((ret & URL_INFO_RECORD) && (ret & URL_INFO_RECORD_TO)) {
146 respond_for_range(b, info.record, info.record_to);
147 } else if (ret & URL_INFO_RECORD) {
148 ret = blerg_fetch(b, info.record, &data, &len);
154 respond_simple_data(data, len);
156 uint64_t record_count, from, to;
157 record_count = blerg_get_record_count(b);
158 if (record_count == 0) {
159 respond_simple_data("[]", 2);
161 to = record_count - 1;
162 from = (record_count > 50 ? to - 49 : 0);
163 respond_for_range(b, from, to);
168 } else if (strncmp(path, "/tag", 4) == 0 && strlen(path) > 4) {
169 if (strcmp(request_method, "GET") != 0) {
174 if (path[4] != '/') {
179 ret = parse_url_info(path + 5, &info);
180 if ((ret & URL_INFO_NAME) == 0) {
185 if (info.name[0] == 'H')
187 if (!tag_exists(info.name)) {
193 struct blergref *taglist = tag_list(info.name, 0, &recs, -1);
196 respond_simple_data("[]", 2);
198 respond_blergref_list(taglist, recs);
200 } else if (strncmp(path, "/put", 4) == 0) {
201 if (strcmp(request_method, "POST") != 0) {
206 const char *username = cgi_getentrystr("username");
207 if (!check_auth(username))
210 if (path[4] == '/') {
215 const char *data = cgi_getentrystr("data");
216 if (data == NULL || data[0] == 0) {
217 respond_JSON_Failure();
221 struct blerg *b = blerg_open(username);
223 respond_JSON_Failure();
226 ret = blerg_store(b, data, strlen(data));
229 respond_JSON_Failure();
233 respond_JSON_Success();
234 } else if (strncmp(path, "/info", 5) == 0) {
235 if (strcmp(request_method, "GET") != 0) {
240 if (path[5] != '/') {
245 ret = parse_url_info(path + 6, &info);
246 if ((ret & URL_INFO_NAME) == 0) {
251 if (!blerg_exists(info.name)) {
256 struct blerg *b = blerg_open(info.name);
257 uint64_t record_count = blerg_get_record_count(b);
261 yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
262 yajl_gen_map_open(g);
263 yajl_gen_string(g, (unsigned char *)"record_count", 12);
264 snprintf(number, 21, "%llu", record_count);
265 yajl_gen_string(g, (unsigned char *)number, strlen(number));
266 yajl_gen_map_close(g);
268 const unsigned char *ybuf;
269 unsigned int content_len;
270 yajl_gen_get_buf(g, &ybuf, &content_len);
272 printf("Content-type: application/json\r\n");
273 printf("Content-length: %d\r\n\r\n", content_len);
274 fwrite(ybuf, content_len, 1, stdout);
277 } else if (strncmp(path, "/create", 8) == 0) {
278 if (strcmp(request_method, "POST") != 0) {
283 const char *username = cgi_getentrystr("username");
284 const char *password = cgi_getentrystr("password");
285 if (username == NULL || username[0] == 0 ||
286 password == NULL || password[0] == 0) {
287 respond_JSON_Failure();
291 if (blerg_exists(username)) {
292 respond_JSON_Failure();
296 struct blerg *b = blerg_open(username);
298 auth_set_password(username, password);
300 respond_JSON_Success();
301 } else if (strncmp(path, "/login", 7) == 0) {
302 if (strcmp(request_method, "POST") != 0) {
307 const char *username = cgi_getentrystr("username");
308 const char *password = cgi_getentrystr("password");
309 if (username == NULL || username[0] == 0 ||
310 password == NULL || password[0] == 0) {
311 respond_JSON_Failure();
315 char *token = auth_login(username, password);
317 respond_JSON_Failure();
321 printf("Set-Cookie: auth=%s\r\n", token);
324 respond_JSON_Success();
325 } else if (strncmp(path, "/logout", 8) == 0) {
326 if (strcmp(request_method, "POST") != 0) {
331 const char *username = cgi_getentrystr("username");
332 if (!check_auth(username))
335 const char *given_token = cgi_getcookie("auth");
336 auth_logout(username, given_token);
337 respond_JSON_Success();
338 } else if (strncmp(path, "/subscribe", 10) == 0 || strncmp(path, "/unsubscribe", 12) == 0) {
339 const char *username = cgi_getentrystr("username");
340 if (!check_auth(username))
343 if (path[1] == 'u') {
344 if (path[12] != '/') {
349 ret = parse_url_info(path + 13, &info);
350 if ((ret & URL_INFO_NAME) == 0) {
355 subscription_remove(username, info.name);
357 if (path[10] != '/') {
362 ret = parse_url_info(path + 11, &info);
363 if ((ret & URL_INFO_NAME) == 0) {
368 subscription_add(username, info.name);
370 respond_JSON_Success();
371 } else if (strncmp(path, "/feed", 6) == 0) {
372 const char *username = cgi_getentrystr("username");
373 if (!check_auth(username))
377 struct blergref *feedlist = subscription_list(username, 0, &recs, -1);
380 respond_simple_data("[]", 2);
382 respond_blergref_list(feedlist, recs);
385 struct blerg *b = blerg_open(username);
386 blerg_set_subscription_mark(b);
388 } else if (strncmp(path, "/feedinfo", 9) == 0) {
389 const char *username = cgi_getentrystr("username");
390 if (!check_auth(username))
393 yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
394 yajl_gen_map_open(g);
396 struct blerg *b = blerg_open(username);
397 uint64_t subscription_mark = blerg_get_subscription_mark(b);
400 yajl_gen_string(g, (unsigned char *)"new", 3);
401 yajl_gen_integer(g, subscription_count_items(username) - subscription_mark);
403 yajl_gen_string(g, (unsigned char *)"subscribed", 10);
404 ret = parse_url_info(path + 10, &info);
405 if ((ret & URL_INFO_NAME) == 1) {
406 yajl_gen_bool(g, is_subscribed(username, info.name));
411 yajl_gen_map_close(g);
413 const unsigned char *ybuf;
414 unsigned int content_len;
415 yajl_gen_get_buf(g, &ybuf, &content_len);
417 printf("Content-type: application/json\r\n");
418 printf("Content-length: %d\r\n\r\n", content_len);
419 fwrite(ybuf, content_len, 1, stdout);
422 } else if (strncmp(path, "/passwd", 7) == 0) {
423 const char *username = cgi_getentrystr("username");
424 if (!check_auth(username))
427 const char *password = cgi_getentrystr("password");
428 const char *new_password = cgi_getentrystr("new_password");
429 if (password == NULL || new_password == NULL) {
430 respond_JSON_Failure();
432 if (auth_check_password(username, password)) {
433 auth_set_password(username, new_password);
434 respond_JSON_Success();
436 respond_JSON_Failure();