diff options
Diffstat (limited to 'warteraum/main.c')
-rw-r--r-- | warteraum/main.c | 133 |
1 files changed, 89 insertions, 44 deletions
diff --git a/warteraum/main.c b/warteraum/main.c index ff360cf..8e6d8a5 100644 --- a/warteraum/main.c +++ b/warteraum/main.c @@ -6,11 +6,13 @@ #include <stdbool.h> #include <stdio.h> #include <string.h> +#include <time.h> #include "emitjson.h" #include "http_string.h" +#include "announcement.h" #include "queue.h" #include "routing.h" #include "form.h" @@ -40,38 +42,13 @@ static struct queue flip_queue; static struct http_server_s* server; -static struct http_string_s announcement; - -void delete_announcement(void) { - if(announcement.buf != NULL) { - free((void *) announcement.buf); - } - announcement.len = -1; - announcement.buf = NULL; -} - -bool set_announcement(http_string_t s) { - delete_announcement(); - - char *new_buf = malloc(s.len); - - if(new_buf == NULL) { - return false; - } - - memcpy(new_buf, s.buf, s.len); - - announcement.len = s.len; - announcement.buf = new_buf; - - return true; -} +static struct warteraum_announcement announcement; void cleanup(int signum) { if(signum == SIGTERM || signum == SIGINT) { queue_free(flip_queue); free(server); - delete_announcement(); + announcement_delete(&announcement); exit(EXIT_SUCCESS); } } @@ -399,18 +376,8 @@ enum warteraum_result response_queue_del(http_string_t id_str, enum warteraum_ve return WARTERAUM_UNAUTHORIZED; } - char *id_zero_terminated = malloc(sizeof(char) * (id_str.len + 1)); - if(id_zero_terminated == NULL) { - return WARTERAUM_INTERNAL_ERROR; - } - - memcpy(id_zero_terminated, id_str.buf, id_str.len); - id_zero_terminated[id_str.len] = '\0'; - errno = 0; - unsigned long int id = strtoul(id_zero_terminated, NULL, 10); - - free(id_zero_terminated); + unsigned long int id = http_string_to_uint(id_str); // check for conversion errors // also abort if id is greater than max id @@ -444,14 +411,21 @@ int make_announcement_response(struct ej_context *ctx) { ej_object(ctx); EJ_STATIC_BIND(ctx, "announcement"); - if(announcement.len > 0 && announcement.buf != NULL) { - ej_string(ctx, announcement.buf, announcement.len); + if(announcement.text.len > 0 && announcement.text.buf != NULL) { + ej_string(ctx, announcement.text.buf, announcement.text.len); status = 200; } else { ej_null(ctx); status = 404; } + EJ_STATIC_BIND(ctx, "expiry_utc"); + if(announcement.announcement_expires) { + ej_int(ctx, announcement.announcement_expiry); + } else { + ej_null(ctx); + } + ej_object_end(ctx); return status; @@ -461,6 +435,12 @@ int make_announcement_response(struct ej_context *ctx) { enum warteraum_result response_announcement(enum warteraum_version v, http_request_t *request, http_response_t *response) { (void) v; // surpress warnings + // instead of using a separate thread or something + // we check expiry every time it is requested + if(announcement_expired(announcement)) { + announcement_delete(&announcement); + } + http_string_t method = http_request_method(request); if(HTTP_STRING_IS(method, "GET") || HTTP_STRING_IS(method, "PUT")) { @@ -498,9 +478,12 @@ enum warteraum_result response_announcement(enum warteraum_version v, http_reque http_string_t text; http_string_t token; + http_string_t expiry_utc_str; + const struct form_field_spec text_body_spec[] = { { STATIC_HTTP_STRING("text"), FIELD_TYPE_STRING, &text }, { STATIC_HTTP_STRING("token"), FIELD_TYPE_STRING, &token }, + { STATIC_HTTP_STRING("expiry_utc"), FIELD_TYPE_OPTIONAL_STRING, &expiry_utc_str }, }; bool parse_result = STATIC_FORM_PARSE(body, text_body_spec); @@ -544,11 +527,72 @@ enum warteraum_result response_announcement(enum warteraum_version v, http_reque free(decoded_mem); fclose(out); free(buf); - return WARTERAUM_INTERNAL_ERROR; + return WARTERAUM_BAD_REQUEST; } - bool update_result = set_announcement(decoded) && - (make_announcement_response(&ctx) == 200); + bool update_result = false; + + // check if we have an expiry time + if(expiry_utc_str.len == -1) { + update_result = announcement_set(&announcement, decoded) && + (make_announcement_response(&ctx) == 200); + } else { + time_t expiry_utc; + + http_string_t expiry_utc_decoded; + char *expiry_utc_decoded_mem = malloc(expiry_utc_str.len); + + if(expiry_utc_decoded_mem == NULL) { + fclose(out); + free(buf); + free(decoded_mem); + return WARTERAUM_INTERNAL_ERROR; + } + + expiry_utc_decoded.len = urldecode(expiry_utc_str, expiry_utc_decoded_mem, (size_t) expiry_utc_str.len); + expiry_utc_decoded.buf = expiry_utc_decoded_mem; + + if(expiry_utc_decoded.len <= 0) { + free(decoded_mem); + free(expiry_utc_decoded_mem); + fclose(out); + free(buf); + return WARTERAUM_BAD_REQUEST; + } + + bool valid = true; + + // check if its a proper number + for(int i = 0; i < expiry_utc_decoded.len; i++) { + if(!isdigit(expiry_utc_decoded.buf[i])) { + valid = false; + } + } + + if(valid) { + errno = 0; + unsigned long long tmp = http_string_to_uint(expiry_utc_decoded); + + if(errno != 0 || tmp > LONG_MAX) { + valid = false; + } else { + expiry_utc = (time_t) tmp; + } + } + + if(!valid) { + free(decoded_mem); + free(expiry_utc_decoded_mem); + fclose(out); + free(buf); + return WARTERAUM_BAD_REQUEST; + } + + update_result = announcement_set_expiring(&announcement, decoded, expiry_utc) && + (make_announcement_response(&ctx) == 200); + + free(expiry_utc_decoded_mem); + } free(decoded_mem); @@ -602,7 +646,7 @@ enum warteraum_result response_announcement(enum warteraum_version v, http_reque return WARTERAUM_UNAUTHORIZED; } - delete_announcement(); + announcement_delete(&announcement); http_response_status(response, 204); http_respond(request, response); @@ -680,6 +724,7 @@ void handle_request(http_request_t *request) { int main(void) { queue_new(&flip_queue); + announcement_new(&announcement); signal(SIGTERM, cleanup); signal(SIGINT, cleanup); |