aboutsummaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c98
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);

Return to:

Send suggestions and report system problems to the System administrator.