diff options
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/src/server.c b/src/server.c index f326547..a0b0312 100644 --- a/src/server.c +++ b/src/server.c @@ -112,6 +112,22 @@ cb_not_found(void *cls, MHD_destroy_response(response); return ret; } + +static int +bad_request(struct MHD_Connection *connection) +{ + int ret; + struct MHD_Response *response; + static char errtext[] = "bad request"; + + response = MHD_create_response_from_buffer (strlen(errtext), + (void *) errtext, + MHD_RESPMEM_PERSISTENT); + ret = MHD_queue_response(connection, MHD_HTTP_BAD_REQUEST, response); + MHD_destroy_response(response); + return ret; +} + static int cb_bad_method(void *cls, @@ -132,13 +148,6 @@ cb_bad_method(void *cls, return ret; } -static void -json_writer(void *closure, char const *text, size_t len) -{ - grecs_txtacc_t acc = closure; - grecs_txtacc_grow(acc, text, len); -} - static int do_sync(void *cls, struct MHD_Connection *connection, @@ -147,37 +156,69 @@ do_sync(void *cls, const char *upload_data, size_t *upload_data_size, void **con_cls) { - int ret, rc; + int ret; struct MHD_Response *response; - struct json_value *json; - struct json_format fmt; - grecs_txtacc_t acc; char *buf; + grecs_txtacc_t acc = *con_cls; if (*url) return cb_not_found(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); - if (strcmp(method, "POST")) + if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) { + /* Nothing */; + } else if (strcmp(method, MHD_HTTP_METHOD_POST) == 0) { + if (!acc) { + char const *t = MHD_lookup_connection_value(connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_CONTENT_TYPE); + if (t && strcmp(t, "application/json")) + return bad_request(connection); + acc = grecs_txtacc_create(); + *con_cls = acc; + return MHD_YES; + } + if (*upload_data_size) { + grecs_txtacc_grow(acc, upload_data, *upload_data_size); + *upload_data_size = 0; + return MHD_YES; + } else { + /* Done with the data, serve the request now */ + char *p; + struct json_value *json; + + grecs_txtacc_grow_char(acc, 0); + p = grecs_txtacc_finish(acc, 0); + + if (*p) { + json = json_parse_string(p, strlen(p)); + } else + json = json_new_null(); + + grecs_txtacc_free(acc); + con_cls = NULL; + + if (!json) + return bad_request(connection); + + if (json->type == json_null) { + nssync_reschedule(0); + } else if (json->type == json_object) { + struct json_value *v; + if (json_object_get(json, "wait", &v) == 0 + && v->type == json_bool) { + nssync_reschedule(v->v.b); + } + } + json_value_free(json); + } + } else return cb_bad_method(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); - - rc = nssync(&json); - acc = grecs_txtacc_create(); - fmt.indent = 0; - fmt.precision = 0; - fmt.write = json_writer; - fmt.data = acc; - json_format_value(json, &fmt); - json_value_free(json); - - grecs_txtacc_grow_char(acc, 0); - buf = grecs_txtacc_finish(acc, 1); - grecs_txtacc_free(acc); - + buf = nssync_format_result(); response = MHD_create_response_from_buffer (strlen(buf), (void *) buf, MHD_RESPMEM_MUST_FREE); @@ -187,7 +228,6 @@ do_sync(void *cls, MHD_destroy_response(response); return ret; } - struct nssync_resource { char const *uri; @@ -251,6 +291,7 @@ nssync_server(void) sigset_t sigs; int i; int sn; + pthread_t thr; if (!server_addr) { if (grecs_str_to_sockaddr(&server_addr, DEFAULT_NSSYNC_ADDR, @@ -292,6 +333,9 @@ nssync_server(void) MHD_OPTION_LISTEN_SOCKET, fd, MHD_OPTION_EXTERNAL_LOGGER, nssync_mhd_logger, NULL, MHD_OPTION_END); + + pthread_create(&thr, NULL, nssync_timer, NULL); + /* Unblock only the fatal signals */ sigdelset(&sigs, SIGPIPE); pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); |