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);
299 auth_set_password(username, password);
301 respond_JSON_Success();
303 respond_JSON_Failure();
305 } else if (strncmp(path, "/login", 7) == 0) {
306 if (strcmp(request_method, "POST") != 0) {
311 const char *username = cgi_getentrystr("username");
312 const char *password = cgi_getentrystr("password");
313 if (username == NULL || username[0] == 0 ||
314 password == NULL || password[0] == 0) {
315 respond_JSON_Failure();
319 char *token = auth_login(username, password);
321 respond_JSON_Failure();
325 printf("Set-Cookie: auth=%s\r\n", token);
328 respond_JSON_Success();
329 } else if (strncmp(path, "/logout", 8) == 0) {
330 if (strcmp(request_method, "POST") != 0) {
335 const char *username = cgi_getentrystr("username");
336 if (!check_auth(username))
339 const char *given_token = cgi_getcookie("auth");
340 auth_logout(username, given_token);
341 respond_JSON_Success();
342 } else if (strncmp(path, "/subscribe", 10) == 0 || strncmp(path, "/unsubscribe", 12) == 0) {
343 const char *username = cgi_getentrystr("username");
344 if (!check_auth(username))
347 if (path[1] == 'u') {
348 if (path[12] != '/') {
353 ret = parse_url_info(path + 13, &info);
354 if ((ret & URL_INFO_NAME) == 0) {
359 subscription_remove(username, info.name);
361 if (path[10] != '/') {
366 ret = parse_url_info(path + 11, &info);
367 if ((ret & URL_INFO_NAME) == 0) {
372 subscription_add(username, info.name);
374 respond_JSON_Success();
375 } else if (strncmp(path, "/feed", 6) == 0) {
376 const char *username = cgi_getentrystr("username");
377 if (!check_auth(username))
381 struct blergref *feedlist = subscription_list(username, 0, &recs, -1);
384 respond_simple_data("[]", 2);
386 respond_blergref_list(feedlist, recs);
389 struct blerg *b = blerg_open(username);
390 blerg_set_subscription_mark(b);
392 } else if (strncmp(path, "/feedinfo", 9) == 0) {
393 const char *username = cgi_getentrystr("username");
394 if (!check_auth(username))
397 yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
398 yajl_gen_map_open(g);
400 struct blerg *b = blerg_open(username);
401 uint64_t subscription_mark = blerg_get_subscription_mark(b);
404 yajl_gen_string(g, (unsigned char *)"new", 3);
405 yajl_gen_integer(g, subscription_count_items(username) - subscription_mark);
407 yajl_gen_string(g, (unsigned char *)"subscribed", 10);
408 ret = parse_url_info(path + 10, &info);
409 if ((ret & URL_INFO_NAME) == 1) {
410 yajl_gen_bool(g, is_subscribed(username, info.name));
415 yajl_gen_map_close(g);
417 const unsigned char *ybuf;
418 unsigned int content_len;
419 yajl_gen_get_buf(g, &ybuf, &content_len);
421 printf("Content-type: application/json\r\n");
422 printf("Content-length: %d\r\n\r\n", content_len);
423 fwrite(ybuf, content_len, 1, stdout);
426 } else if (strncmp(path, "/passwd", 7) == 0) {
427 const char *username = cgi_getentrystr("username");
428 if (!check_auth(username))
431 const char *password = cgi_getentrystr("password");
432 const char *new_password = cgi_getentrystr("new_password");
433 if (password == NULL || new_password == NULL) {
434 respond_JSON_Failure();
436 if (auth_check_password(username, password)) {
437 auth_set_password(username, new_password);
438 respond_JSON_Success();
440 respond_JSON_Failure();