commit:28a7ca12adefd4a4db25ad0534638e085a9f0e12
author:Chip Black
committer:Chip Black
date:Sat Feb 26 03:45:36 2011 -0600
parents:ec8746b44dc85fd3e3b42835f779890684a9e90a
Add /feedinfo endpoint
diff --git a/common/app.h b/common/app.h
line changes: +1/-0
index b45f472..8156274
--- a/common/app.h
+++ b/common/app.h
@@ -11,6 +11,7 @@
 #define REALM "Blerg"
 
 #define CONTENT_401 "<html><head><title>401 Unauthorized</title></head><body><h1>401 Unauthorized</h1>DENIED</body></html>"
+#define CONTENT_403 "<html><head><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1>Go away.</body></html>"
 #define CONTENT_404 "<html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1>I couldn't find that.</body></html>"
 #define CONTENT_405 "<html><head><title>405 Method Not Allowed</title></head><body><h1>405 Method Not Allowed</h1>I'm sorry, Dave. I'm afraid I can't do that.</body></html>"
 #define JSON_SUCCESS "{\"status\": \"success\"}"

diff --git a/database/subscription.c b/database/subscription.c
line changes: +14/-0
index d67d31f..d3686ad
--- a/database/subscription.c
+++ b/database/subscription.c
@@ -128,3 +128,17 @@ subscription_list_open_failed:
 	*count = 0;
 	return NULL;
 }
+
+int is_subscribed(const char *from, const char *to) {
+	char filename[512];
+	struct stringbucket * sb;
+	int ret = 0;
+
+	snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from);
+	sb = stringbucket_open(filename);
+	if (stringbucket_find(sb, to) != -1)
+		ret = 1;
+	stringbucket_close(sb);
+
+	return ret;
+}

diff --git a/database/subscription.h b/database/subscription.h
line changes: +1/-0
index a7cf567..c07fc6d
--- a/database/subscription.h
+++ b/database/subscription.h
@@ -11,5 +11,6 @@ int subscription_add(const char *from, const char *to);
 int subscription_remove(const char *from, const char *to);
 int subscription_notify(const char *author, uint64_t record);
 struct blergref * subscription_list(const char *author, uint64_t offset, int *count, int direction);
+int is_subscribed(const char *from, const char *to);
 
 #endif /* _SUBSCRIPTION_H */

diff --git a/http/canned_responses.c b/http/canned_responses.c
line changes: +6/-1
index ee26799..3537907
--- a/http/canned_responses.c
+++ b/http/canned_responses.c
@@ -7,7 +7,8 @@
 #include "canned_responses.h"
 
 void init_responses() {
-	response_401 = MHD_create_response_from_data(strlen (CONTENT_401), CONTENT_401, MHD_NO, MHD_NO);  
+	response_401 = MHD_create_response_from_data(strlen(CONTENT_401), CONTENT_401, MHD_NO, MHD_NO);  
+	response_403 = MHD_create_response_from_data(strlen(CONTENT_403), CONTENT_403, MHD_NO, MHD_NO);
 	response_404 = MHD_create_response_from_data(strlen(CONTENT_404), CONTENT_404, MHD_NO, MHD_NO);
 	response_405 = MHD_create_response_from_data(strlen(CONTENT_405), CONTENT_405, MHD_NO, MHD_NO);
 	response_JSON_Success = MHD_create_response_from_data(strlen(JSON_SUCCESS), JSON_SUCCESS, MHD_NO, MHD_NO);
@@ -19,6 +20,10 @@ int respond_401(struct MHD_Connection *connection, int signal_stale) {
 	return MHD_queue_auth_fail_response(connection, REALM, OPAQUE, response_401, signal_stale);    
 }
 
+int respond_403(struct MHD_Connection *connection) {
+	return MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, response_403);
+}
+
 int respond_404(struct MHD_Connection *connection) {
 	return MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response_404);
 }

diff --git a/http/canned_responses.h b/http/canned_responses.h
line changes: +1/-0
index 7b3a0f5..3bb079f
--- a/http/canned_responses.h
+++ b/http/canned_responses.h
@@ -5,6 +5,7 @@
 #define _CANNED_RESPONSES
 
 struct MHD_Response *response_401;
+struct MHD_Response *response_403;
 struct MHD_Response *response_404;
 struct MHD_Response *response_405;
 struct MHD_Response *response_JSON_Success;

diff --git a/http/http_blerg.c b/http/http_blerg.c
line changes: +57/-0
index e205749..65a63d2
--- a/http/http_blerg.c
+++ b/http/http_blerg.c
@@ -266,6 +266,32 @@ struct MHD_Response *create_blergref_response(struct blergref *results, uint64_t
 	return MHD_create_response_from_callback(-1, 262144, &GET_generate_blergref_list, bs, &GET_generate_blergref_list_free);
 }
 
+int check_auth(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) {
+	struct auth_state *as = (struct auth_state *) *ptr;
+	if (as == NULL) {
+		if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+			return respond_405(connection);
+
+		as = malloc(sizeof(struct auth_state));
+		as->username[0] = as->password[0] = 0;
+		as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+		*ptr = as;
+		return MHD_YES;
+	}
+
+	if (*upload_data_size) {
+		MHD_post_process(as->pp, upload_data, *upload_data_size);
+		*upload_data_size = 0;
+		return MHD_YES;
+	}
+
+	const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
+	if (!auth_check_token(as->username, given_token))
+		return respond_403(connection);
+
+	return MHD_NO;
+}
+
 static int
 ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const char *method,
 	  const char *version, const char *upload_data, size_t *upload_data_size, void **ptr) {
@@ -632,6 +658,37 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 		} else {
 			return respond_JSON_Failure(connection);
 		}
+	} else if (strncmp(url, "/feedinfo", 9) == 0) {
+		ret = check_auth(connection, method, upload_data, upload_data_size, ptr);
+		if (ret == MHD_YES)
+			return MHD_YES;
+
+		struct auth_state *as = (struct auth_state *) *ptr;
+
+		if (url[9] != '/')
+			return respond_404(connection);
+
+		ret = parse_url_info(url + 10, &info);
+		if ((ret & URL_INFO_NAME) == 0)
+			return respond_404(connection);
+
+		yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
+		yajl_gen_map_open(g);
+		yajl_gen_string(g, "subscribed", 10);
+		yajl_gen_bool(g, is_subscribed(as->username, info.name));
+		yajl_gen_map_close(g);
+
+		const unsigned char *ybuf;
+		yajl_gen_get_buf(g, &ybuf, &len);
+
+		response = MHD_create_response_from_data(len, (void *)ybuf, MHD_NO, MHD_YES);
+		ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+		MHD_destroy_response(response);
+
+		yajl_gen_free(g);
+		free(as);
+
+		return ret;
 	} else {
 		return respond_404(connection);
 	}