Refactor those ugly POST handlers
authorChip Black <bytex64@bytex64.net>
Sat, 26 Feb 2011 10:27:30 +0000 (04:27 -0600)
committerChip Black <bytex64@bytex64.net>
Sat, 26 Feb 2011 10:27:30 +0000 (04:27 -0600)
http/http_blerg.c

index 65a63d2..e6e04c5 100644 (file)
@@ -174,22 +174,6 @@ void GET_generate_blergref_list_free(void *cls) {
        free(bs);
 }
 
-int POST_auth_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
-       struct auth_state *as = cls;
-
-       if (strncmp(key, "username", 9) == 0) {
-               if (size > 32) size = 32;
-               memcpy(as->username, data, size);
-               as->username[size] = 0;
-       } else if (strncmp(key, "password", 9) == 0) {
-               if (size > 32) size = 32;
-               memcpy(as->password, data, size);
-               as->password[size] = 0;
-       }
-
-       return MHD_YES;
-}
-
 int POST_put_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
        struct put_state *ps = cls;
 
@@ -216,6 +200,46 @@ int POST_put_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const
        return MHD_YES;
 }
 
+int process_put(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) {
+       struct put_state *ps = (struct put_state *) *ptr;
+
+       if (ps == NULL) {
+               if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+                       return respond_405(connection);
+
+               *ptr = (void *) 1;
+
+               struct put_state *ps = malloc(sizeof(struct put_state));
+               ps->data = NULL;
+               ps->data_size = 0;
+               ps->pp = MHD_create_post_processor(connection, 16384, &POST_put_iterator, ps);
+               ps->username[0] = 0;
+               *ptr = ps;
+               return MHD_YES;
+       }
+
+       if (*upload_data_size) {
+               MHD_post_process(ps->pp, upload_data, *upload_data_size);
+               *upload_data_size = 0;
+               return MHD_YES;
+       }
+
+       return MHD_NO;
+}
+
+int process_and_check_put(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) {
+       struct put_state *ps = (struct put_state *) *ptr;
+
+       if (process_put(connection, method, upload_data, upload_data_size, ptr) == MHD_YES)
+               return MHD_YES;
+
+       const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
+       if (!auth_check_token(ps->username, given_token))
+               return respond_403(connection);
+
+       return MHD_NO;
+}
+
 int POST_subscribe_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
        struct subscribe_state *ss = cls;
 
@@ -232,6 +256,58 @@ int POST_subscribe_iterator(void *cls, enum MHD_ValueKind kind, const char *key,
        return MHD_YES;
 }
 
+int POST_auth_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
+       struct auth_state *as = cls;
+
+       if (strncmp(key, "username", 9) == 0) {
+               if (size > 32) size = 32;
+               memcpy(as->username, data, size);
+               as->username[size] = 0;
+       } else if (strncmp(key, "password", 9) == 0) {
+               if (size > 32) size = 32;
+               memcpy(as->password, data, size);
+               as->password[size] = 0;
+       }
+
+       return MHD_YES;
+}
+
+int process_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;
+       }
+
+       return MHD_NO;
+}
+
+int process_and_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 (process_auth(connection, method, upload_data, upload_data_size, ptr) == MHD_YES)
+               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;
+}
+
 struct MHD_Response *create_response_for_range(struct blerg *b, uint64_t from, uint64_t to) {
        struct MHD_Response *response;
        struct get_state *gs = malloc(sizeof(struct get_state));
@@ -266,32 +342,6 @@ 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) {
@@ -391,36 +441,16 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 
                return ret;
        } else if (strncmp(url, "/put", 4) == 0) {
-               struct put_state *ps = (struct put_state *) *ptr;
-               if (*ptr == NULL) {
-                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
-                               return respond_405(connection);
-
-                       if (url[4] == '/')
-                               return respond_404(connection);
-
-                       *ptr = (void *) 1;
-
-                       struct put_state *ps = malloc(sizeof(struct put_state));
-                       ps->data = NULL;
-                       ps->data_size = 0;
-                       ps->pp = MHD_create_post_processor(connection, 16384, &POST_put_iterator, ps);
-                       ps->username[0] = 0;
-                       *ptr = ps;
-                       return MHD_YES;
-               }
+               if (url[4] == '/')
+                       return respond_404(connection);
 
-               if (*upload_data_size) {
-                       MHD_post_process(ps->pp, upload_data, *upload_data_size);
-                       *upload_data_size = 0;
+               ret = process_and_check_put(connection, method, upload_data, upload_data_size, ptr);
+               if (ret == MHD_YES)
                        return MHD_YES;
-               }
 
-               if (ps->data == NULL || ps->data_size == 0 || ps->username[0] == 0)
-                       return respond_JSON_Failure(connection);
+               struct put_state *ps = (struct put_state *) *ptr;
 
-               const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
-               if (!auth_check_token(ps->username, given_token))
+               if (ps->data == NULL || ps->data_size == 0)
                        return respond_JSON_Failure(connection);
 
                struct blerg *b = blerg_open(ps->username);
@@ -482,24 +512,11 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 
                return ret;
        } else if (strncmp(url, "/create", 8) == 0) {
-               struct auth_state *as = (struct auth_state *) *ptr;
-
-               if (as == NULL) {
-                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
-                               return respond_405(connection);
-
-                       struct auth_state *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;
+               ret = process_auth(connection, method, upload_data, upload_data_size, ptr);
+               if (ret == MHD_YES)
                        return MHD_YES;
-               }
 
-               if (*upload_data_size) {
-                       MHD_post_process(as->pp, upload_data, *upload_data_size);
-                       *upload_data_size = 0;
-                       return MHD_YES;
-               }
+               struct auth_state *as = (struct auth_state *) *ptr;
 
                if (as->username[0] == 0 || as->password[0] == 0)
                        return respond_JSON_Failure(connection);
@@ -517,24 +534,11 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 
                return respond_JSON_Success(connection);
        } else if (strncmp(url, "/login", 7) == 0) {
-               struct auth_state *as = (struct auth_state *) *ptr;
-
-               if (as == NULL) {
-                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
-                               return respond_405(connection);
-
-                       struct auth_state *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;
+               ret = process_auth(connection, method, upload_data, upload_data_size, ptr);
+               if (ret == MHD_YES)
                        return MHD_YES;
-               }
 
-               if (*upload_data_size) {
-                       MHD_post_process(as->pp, upload_data, *upload_data_size);
-                       *upload_data_size = 0;
-                       return MHD_YES;
-               }
+               struct auth_state *as = (struct auth_state *) *ptr;
 
                if (as->username[0] == 0 || as->password[0] == 0)
                        return respond_JSON_Failure(connection);
@@ -560,32 +564,14 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
 
                return ret;
        } else if (strncmp(url, "/logout", 8) == 0) {
-               struct auth_state *as = (struct auth_state *) *ptr;
-
-               if (as == NULL) {
-                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
-                               return respond_405(connection);
-
-                       struct auth_state *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;
+               ret = process_and_check_auth(connection, method, upload_data, upload_data_size, ptr);
+               if (ret == MHD_YES)
                        return MHD_YES;
-               }
 
-               if (*upload_data_size) {
-                       MHD_post_process(as->pp, upload_data, *upload_data_size);
-                       *upload_data_size = 0;
-                       return MHD_YES;
-               }
+               struct auth_state *as = (struct auth_state *) *ptr;
 
-               const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
-               if (auth_check_token(as->username, given_token)) {
-                       auth_logout(as->username);
-                       return respond_JSON_Success(connection);
-               } else {
-                       return respond_JSON_Failure(connection);
-               }
+               auth_logout(as->username);
+               return respond_JSON_Success(connection);
        } else if (strncmp(url, "/subscribe", 11) == 0 || strncmp(url, "/unsubscribe", 13) == 0) {
                struct subscribe_state *ss = (struct subscribe_state *) *ptr;
 
@@ -618,48 +604,30 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c
                        return respond_JSON_Failure(connection);
                }
        } else if (strncmp(url, "/feed", 6) == 0) {
-               struct auth_state *as = (struct auth_state *) *ptr;
-
-               if (as == NULL) {
-                       if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
-                               return respond_405(connection);
-
-                       struct auth_state *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;
+               ret = process_and_check_auth(connection, method, upload_data, upload_data_size, ptr);
+               if (ret == MHD_YES)
                        return MHD_YES;
-               }
 
-               if (*upload_data_size) {
-                       MHD_post_process(as->pp, upload_data, *upload_data_size);
-                       *upload_data_size = 0;
-                       return MHD_YES;
-               }
+               struct auth_state *as = (struct auth_state *) *ptr;
 
-               const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
-               if (auth_check_token(as->username, given_token)) {
-                       int recs = 50;
-                       struct blergref *feedlist = subscription_list(as->username, 0, &recs, -1);
+               int recs = 50;
+               struct blergref *feedlist = subscription_list(as->username, 0, &recs, -1);
 
-                       if (recs == 0) {
-                               response = MHD_create_response_from_data(2, "[]", MHD_NO, MHD_NO);
-                       } else {
-                               response = create_blergref_response(feedlist, recs);
-                       }
+               if (recs == 0) {
+                       response = MHD_create_response_from_data(2, "[]", MHD_NO, MHD_NO);
+               } else {
+                       response = create_blergref_response(feedlist, recs);
+               }
 
-                       if (response == NULL)
-                               return respond_JSON_Failure(connection);
+               if (response == NULL)
+                       return respond_JSON_Failure(connection);
 
-                       ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-                       MHD_destroy_response(response);
+               ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+               MHD_destroy_response(response);
 
-                       return ret;
-               } else {
-                       return respond_JSON_Failure(connection);
-               }
+               return ret;
        } else if (strncmp(url, "/feedinfo", 9) == 0) {
-               ret = check_auth(connection, method, upload_data, upload_data_size, ptr);
+               ret = process_and_check_auth(connection, method, upload_data, upload_data_size, ptr);
                if (ret == MHD_YES)
                        return MHD_YES;