From: Jeroen van der Heijden Date: Tue, 7 Jan 2020 15:31:23 +0000 (+0100) Subject: also did some json code X-Git-Tag: archive/raspbian/2.0.44-1+rpi1~1^2~3^2~5^2~38 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b79f9ded0a9a3b029518ea69a057b8b2e7514ccd;p=siridb-server.git also did some json code --- diff --git a/Debug/objects.mk b/Debug/objects.mk index 5a47d0bc..bc2d853e 100644 --- a/Debug/objects.mk +++ b/Debug/objects.mk @@ -1,4 +1,4 @@ USER_OBJS := -LIBS := -luv -lm -lpcre2-8 -lcleri +LIBS := -luv -lm -lpcre2-8 -lcleri -lyajl diff --git a/Release/objects.mk b/Release/objects.mk index 5a47d0bc..bc2d853e 100644 --- a/Release/objects.mk +++ b/Release/objects.mk @@ -1,4 +1,4 @@ USER_OBJS := -LIBS := -luv -lm -lpcre2-8 -lcleri +LIBS := -luv -lm -lpcre2-8 -lcleri -lyajl diff --git a/include/qpjson/qpjson.h b/include/qpjson/qpjson.h index e69de29b..b83a9345 100644 --- a/include/qpjson/qpjson.h +++ b/include/qpjson/qpjson.h @@ -0,0 +1,33 @@ +/* + * qpjson.h - Convert between QPack and JSON + */ +#ifndef QPJSON_H_ +#define QPJSON_H_ + +#include +#include +#include + +enum +{ + /* flags map to the API flags */ + QPJSON_FLAG_BEAUTIFY =1<<2, + QPJSON_FLAG_VALIDATE_UTF8 =1<<3, +}; + + +yajl_gen_status qpjson_qp_to_json( + const void * src, + size_t src_n, + unsigned char ** dst, + size_t * dst_n, + int flags); + +yajl_status qpjson_json_to_qp( + const void * src, + size_t src_n, + char ** dst, + size_t * dst_n); + + +#endif /* QPJSON_H_ */ diff --git a/include/siri/api.h b/include/siri/api.h index 8a57d4dc..901575f2 100644 --- a/include/siri/api.h +++ b/include/siri/api.h @@ -7,7 +7,6 @@ #include #include -#define SIRIDB_API_FLAG 1<<29 typedef enum { @@ -38,17 +37,19 @@ static inline _Bool siri_api_is_handle(uv_handle_t * handle); struct siri_api_request_s { - uint32_t ref_; /* maps to sirnet_stream_t for cleanup */ + uint32_t tp; /* maps to siridb_tee_t flags for cleanup */ + uint32_t ref; + on_data_cb_t on_data; + siridb_t * siridb; + void * origin; /* can be a user, server or NULL */ + char * buf; + size_t len; + size_t size; + uv_stream_t * stream; siridb_api_flags_t flags; siridb_api_state_t state; siridb_api_content_t content_type; - size_t content_n; - uv_write_t req; - uv_stream_t uvstream; http_parser parser; - char * content; - siridb_t * siridb; - siridb_user_t * user; }; static inline _Bool siri_api_is_handle(uv_handle_t * handle) diff --git a/include/siri/net/stream.h b/include/siri/net/stream.h index c99db466..16c79b3f 100644 --- a/include/siri/net/stream.h +++ b/include/siri/net/stream.h @@ -13,6 +13,7 @@ typedef enum STREAM_TCP_SERVER, STREAM_TCP_MANAGE, STREAM_PIPE_CLIENT, + STREAM_API_CLIENT, } sirinet_stream_tp_t; typedef struct sirinet_stream_s sirinet_stream_t; @@ -43,9 +44,6 @@ void sirinet__stream_free(uv_stream_t * uvclient); (uv_handle_t *) (client)->stream, \ (uv_close_cb) sirinet__stream_free) -#define sirinet_stream_is_pipe(client) \ - ((client)->tp == STREAM_PIPE_CLIENT) - struct sirinet_stream_s { uint32_t tp; /* maps to siridb_tee_t flags for cleanup */ diff --git a/src/qpjson/qpjson.c b/src/qpjson/qpjson.c index e69de29b..76eff9af 100644 --- a/src/qpjson/qpjson.c +++ b/src/qpjson/qpjson.c @@ -0,0 +1,12 @@ +/* + * qpjson.c - Convert between QPack and JSON + */ + +#include + +yajl_gen_status mpjson_mp_to_json( + const void * src, + size_t src_n, + unsigned char ** dst, + size_t * dst_n, + int flags) diff --git a/src/siri/api.c b/src/siri/api.c index 8e92dc88..1f30e6c1 100644 --- a/src/siri/api.c +++ b/src/siri/api.c @@ -62,17 +62,6 @@ static inline _Bool api__starts_with( return true; } -static void api__close_cb(uv_handle_t * handle) -{ - siri_api_request_t * ar = handle->data; - if (ar->siridb) - siridb_decref(ar->siridb); - if (ar->user) - siridb_user_decref(ar->user); - free(ar->content); - free(ar); -} - static void api__alloc_cb( uv_handle_t * UNUSED(handle), size_t UNUSED(sugsz), @@ -98,7 +87,8 @@ static void api__data_cb( if (n != UV_EOF) log_error(uv_strerror(n)); - ti_api_close(ar); + ar->flags |= SIRIDB_API_FLAG_IS_CLOSED; + sirinet_stream_decref(ar); goto done; } @@ -117,7 +107,8 @@ static void api__data_cb( else if (parsed != (size_t) n) { log_warning("error parsing HTTP API request"); - ti_api_close(ar); + ar->flags |= SIRIDB_API_FLAG_IS_CLOSED; + sirinet_stream_decref(ar); } done: @@ -128,11 +119,11 @@ static int api__headers_complete_cb(http_parser * parser) { siri_api_request_t * ar = parser->data; - assert (!ar->content); + assert (!ar->buf); - ar->content = malloc(parser->content_length); - if (ar->content) - ar->content_n = parser->content_length; + ar->buf = malloc(parser->content_length); + if (ar->len) + ar->len = parser->content_length; return 0; } @@ -166,13 +157,23 @@ static void api__connection_cb(uv_stream_t * server, int status) return; } - (void) uv_tcp_init(siri.loop, (uv_tcp_t *) &ar->uvstream); + ar->stream = malloc(sizeof(uv_tcp_t)); + if (!ar->stream) + { + free(ar); + ERR_ALLOC + return; + } + + ar->tp = STREAM_API_CLIENT; + ar->on_data = NULL; - ar->flags |= SIRIDB_API_FLAG; - ar->uvstream.data = ar; + (void) uv_tcp_init(siri.loop, (uv_tcp_t *) ar->stream); + + ar->stream->data = ar; ar->parser.data = ar; - rc = uv_accept(server, &ar->uvstream); + rc = uv_accept(server, ar->stream); if (rc) { log_error("cannot accept HTTP API request: `%s`", uv_strerror(rc)); @@ -182,7 +183,7 @@ static void api__connection_cb(uv_stream_t * server, int status) http_parser_init(&ar->parser, HTTP_REQUEST); - rc = uv_read_start(&ar->uvstream, api__alloc_cb, api__data_cb); + rc = uv_read_start(ar->stream, api__alloc_cb, api__data_cb); if (rc) { log_error("cannot read HTTP API request: `%s`", uv_strerror(rc)); @@ -244,11 +245,14 @@ static int api__header_value_cb(http_parser * parser, const char * at, size_t n) if (api__starts_with(&at, &n, "basic ", strlen("basic "))) { - ar->user = siridb_users_get_user_from_basic(ar->siridb, at, n); - - if (ar->user) - siridb_user_incref(ar->user); - + siridb_user_t * user; + user = siridb_users_get_user_from_basic(ar->siridb, at, n); + + if (user) + { + siridb_user_incref(user); + ar->origin = user; + } break; } @@ -263,12 +267,12 @@ static int api__body_cb(http_parser * parser, const char * at, size_t n) size_t offset; siri_api_request_t * ar = parser->data; - if (!n || !ar->content_n) + if (!n || !ar->len) return 0; - offset = ar->content_n - (parser->content_length + n); - assert (offset + n <= ar->content_n); - memcpy(ar->content + offset, at, n); + offset = ar->len - (parser->content_length + n); + assert (offset + n <= ar->len); + memcpy(ar->buf + offset, at, n); return 0; } @@ -280,7 +284,8 @@ static void api__write_cb(uv_write_t * req, int status) "error writing HTTP API response: `%s`", uv_strerror(status)); - ti_api_close((siri_api_request_t *) req->handle->data); + sirinet_stream_decref((siri_api_request_t *) req->handle->data); + free(req); } static int api__plain_response(siri_api_request_t * ar, const api__header_t ht) @@ -292,6 +297,9 @@ static int api__plain_response(siri_api_request_t * ar, const api__header_t ht) body_size = strlen(body); header_size = api__header(header, ht, SIRIDB_API_CT_TEXT, body_size); + + uv_write_t * req = malloc(sizeof(uv_write_t)); + if (header_size > 0) { uv_buf_t uvbufs[2] = { @@ -299,11 +307,7 @@ static int api__plain_response(siri_api_request_t * ar, const api__header_t ht) uv_buf_init((char *) body, body_size), }; - (void) uv_write( - &ar->req, - &ar->uvstream, - uvbufs, 2, - api__write_cb); + (void) uv_write(req, ar->stream, uvbufs, 2, api__write_cb); return 0; } return -1; @@ -313,7 +317,10 @@ static int api__message_complete_cb(http_parser * parser) { siri_api_request_t * ar = parser->data; - if (!ar->user) + if (!ar->siridb) + return api__plain_response(ar, E404_NOT_FOUND); + + if (!ar->origin) return api__plain_response(ar, E401_UNAUTHORIZED); switch (ar->content_type) @@ -322,12 +329,12 @@ static int api__message_complete_cb(http_parser * parser) { char * data; size_t size; - if (qpjson_json_to_qp(ar->content, ar->content_n, &data, &size)) + if (qpjson_json_to_qp(ar->buf, ar->len, &data, &size)) return api__plain_response(ar, E400_BAD_REQUEST); - free(ar->content); - ar->content = data; - ar->content_n = size; + free(ar->buf); + ar->buf = data; + ar->len = size; } } @@ -386,30 +393,3 @@ int siri_api_init(void) log_info("start listening for HTTP API requests on TCP port %u", port); return 0; } - -siri_api_request_t * siri_api_acquire(siri_api_request_t * ar) -{ - ar->flags |= SIRIDB_API_FLAG_IN_USE; - return ar; -} - -void ti_api_release(siri_api_request_t * ar) -{ - ar->flags &= ~SIRIDB_API_FLAG_IN_USE; - - if (ar->flags & SIRIDB_API_FLAG_IS_CLOSED) - uv_close((uv_handle_t *) &ar->uvstream, api__close_cb); -} - -void ti_api_close(siri_api_request_t * ar) -{ - if (!ar || (ar->flags & SIRIDB_API_FLAG_IS_CLOSED)) - return; - - ar->flags |= SIRIDB_API_FLAG_IS_CLOSED; - - if (ar->flags & SIRIDB_API_FLAG_IN_USE) - return; - - uv_close((uv_handle_t *) &ar->uvstream, api__close_cb); -} diff --git a/src/siri/net/stream.c b/src/siri/net/stream.c index f5d5a5c8..471bd452 100644 --- a/src/siri/net/stream.c +++ b/src/siri/net/stream.c @@ -51,6 +51,7 @@ sirinet_stream_t * sirinet_stream_new(sirinet_stream_tp_t tp, on_data_cb_t cb) switch(tp) { + case STREAM_API_CLIENT: case STREAM_TCP_CLIENT: case STREAM_TCP_BACKEND: case STREAM_TCP_SERVER: @@ -87,6 +88,7 @@ char * sirinet_stream_name(sirinet_stream_t * client) { switch ((sirinet_stream_tp_t) client->tp) { + case STREAM_API_CLIENT: case STREAM_TCP_CLIENT: case STREAM_TCP_BACKEND: case STREAM_TCP_SERVER: @@ -244,6 +246,7 @@ void sirinet__stream_free(uv_stream_t * uvclient) switch ((sirinet_stream_tp_t) client->tp) { + case STREAM_API_CLIENT: case STREAM_PIPE_CLIENT: case STREAM_TCP_CLIENT: /* listens to client connections */ log_debug("client connection lost");