agoo 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/ext/agoo/con.c +104 -78
- data/ext/agoo/con.h +9 -4
- data/ext/agoo/debug.c +9 -9
- data/ext/agoo/debug.h +1 -0
- data/ext/agoo/error_stream.c +14 -6
- data/ext/agoo/gqleval.c +93 -14
- data/ext/agoo/gqlsub.c +37 -0
- data/ext/agoo/gqlsub.h +24 -0
- data/ext/agoo/gqlvalue.c +14 -0
- data/ext/agoo/gqlvalue.h +1 -0
- data/ext/agoo/graphql.c +13 -2
- data/ext/agoo/pub.c +0 -3
- data/ext/agoo/res.c +19 -5
- data/ext/agoo/res.h +1 -1
- data/ext/agoo/rgraphql.c +37 -0
- data/ext/agoo/rserver.c +26 -11
- data/ext/agoo/sdl.c +13 -13
- data/ext/agoo/sdl.h +2 -1
- data/ext/agoo/server.c +115 -0
- data/ext/agoo/server.h +8 -0
- data/ext/agoo/text.c +6 -4
- data/ext/agoo/websocket.c +9 -19
- data/lib/agoo/version.rb +1 -1
- data/test/rack_handler_test.rb +6 -1
- metadata +4 -2
data/ext/agoo/debug.c
CHANGED
@@ -53,7 +53,7 @@ agoo_malloc(size_t size, const char *file, int line) {
|
|
53
53
|
|
54
54
|
if (NULL != ptr) {
|
55
55
|
Rec r = (Rec)malloc(sizeof(struct _rec));
|
56
|
-
|
56
|
+
|
57
57
|
if (NULL != r) {
|
58
58
|
strcpy(((char*)ptr) + size, mem_pad);
|
59
59
|
r->ptr = ptr;
|
@@ -79,7 +79,7 @@ agoo_calloc(size_t count, size_t size, const char *file, int line) {
|
|
79
79
|
size *= count;
|
80
80
|
if (NULL != (ptr = malloc(size + sizeof(mem_pad)))) {
|
81
81
|
Rec r = (Rec)malloc(sizeof(struct _rec));
|
82
|
-
|
82
|
+
|
83
83
|
if (NULL != r) {
|
84
84
|
memset(ptr, 0, size);
|
85
85
|
strcpy(((char*)ptr) + size, mem_pad);
|
@@ -103,7 +103,7 @@ void*
|
|
103
103
|
agoo_realloc(void *orig, size_t size, const char *file, int line) {
|
104
104
|
void *ptr = realloc(orig, size + sizeof(mem_pad));
|
105
105
|
Rec r;
|
106
|
-
|
106
|
+
|
107
107
|
if (NULL != ptr) {
|
108
108
|
strcpy(((char*)ptr) + size, mem_pad);
|
109
109
|
pthread_mutex_lock(&lock);
|
@@ -131,7 +131,7 @@ agoo_strdup(const char *str, const char *file, int line) {
|
|
131
131
|
|
132
132
|
if (NULL != ptr) {
|
133
133
|
Rec r = (Rec)malloc(sizeof(struct _rec));
|
134
|
-
|
134
|
+
|
135
135
|
if (NULL != r) {
|
136
136
|
strcpy(ptr, str);
|
137
137
|
strcpy(((char*)ptr) + size, mem_pad);
|
@@ -158,7 +158,7 @@ agoo_strndup(const char *str, size_t len, const char *file, int line) {
|
|
158
158
|
|
159
159
|
if (NULL != ptr) {
|
160
160
|
Rec r = (Rec)malloc(sizeof(struct _rec));
|
161
|
-
|
161
|
+
|
162
162
|
if (NULL != r) {
|
163
163
|
memcpy(ptr, str, len);
|
164
164
|
ptr[len] = '\0';
|
@@ -183,7 +183,7 @@ void
|
|
183
183
|
agoo_mem_check(void *ptr, const char *file, int line) {
|
184
184
|
if (NULL != ptr) {
|
185
185
|
Rec r = NULL;
|
186
|
-
|
186
|
+
|
187
187
|
pthread_mutex_lock(&lock);
|
188
188
|
for (r = recs; NULL != r; r = r->next) {
|
189
189
|
if (ptr == r->ptr) {
|
@@ -199,7 +199,7 @@ agoo_mem_check(void *ptr, const char *file, int line) {
|
|
199
199
|
if (0 != strcmp(mem_pad, pad)) {
|
200
200
|
uint8_t *p;
|
201
201
|
uint8_t *end = (uint8_t*)pad + sizeof(mem_pad);
|
202
|
-
|
202
|
+
|
203
203
|
printf("Check - Memory at %s:%d (%p) write outside allocated.\n", file, line, ptr);
|
204
204
|
for (p = (uint8_t*)pad; p < end; p++) {
|
205
205
|
if (0x20 < *p && *p < 0x7f) {
|
@@ -219,7 +219,7 @@ agoo_freed(void *ptr, const char *file, int line) {
|
|
219
219
|
if (NULL != ptr) {
|
220
220
|
Rec r = NULL;
|
221
221
|
Rec prev = NULL;
|
222
|
-
|
222
|
+
|
223
223
|
pthread_mutex_lock(&lock);
|
224
224
|
for (r = recs; NULL != r; r = r->next) {
|
225
225
|
if (ptr == r->ptr) {
|
@@ -241,7 +241,7 @@ agoo_freed(void *ptr, const char *file, int line) {
|
|
241
241
|
if (0 != strcmp(mem_pad, pad)) {
|
242
242
|
uint8_t *p;
|
243
243
|
uint8_t *end = (uint8_t*)pad + sizeof(mem_pad);
|
244
|
-
|
244
|
+
|
245
245
|
printf("Memory at %s:%d (%p) write outside allocated.\n", file, line, ptr);
|
246
246
|
for (p = (uint8_t*)pad; p < end; p++) {
|
247
247
|
if (0x20 < *p && *p < 0x7f) {
|
data/ext/agoo/debug.h
CHANGED
data/ext/agoo/error_stream.c
CHANGED
@@ -30,9 +30,8 @@ error_stream_new() {
|
|
30
30
|
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream.");
|
31
31
|
}
|
32
32
|
es->server = NULL;
|
33
|
-
|
34
|
-
|
35
|
-
}
|
33
|
+
es->text = NULL;
|
34
|
+
|
36
35
|
return Data_Wrap_Struct(es_class, NULL, es_free, es);
|
37
36
|
}
|
38
37
|
|
@@ -50,6 +49,10 @@ es_puts(VALUE self, VALUE str) {
|
|
50
49
|
if (NULL == es) {
|
51
50
|
rb_raise(rb_eIOError, "error stream has been closed.");
|
52
51
|
}
|
52
|
+
if (NULL == es->text &&
|
53
|
+
NULL == (es->text = agoo_text_allocate(1024))) {
|
54
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream buffer.");
|
55
|
+
}
|
53
56
|
es->text = agoo_text_append(es->text, StringValuePtr(str), (int)RSTRING_LEN(str));
|
54
57
|
es->text = agoo_text_append(es->text, "\n", 1);
|
55
58
|
if (NULL == es->text) {
|
@@ -72,6 +75,10 @@ es_write(VALUE self, VALUE str) {
|
|
72
75
|
if (NULL == es) {
|
73
76
|
rb_raise(rb_eIOError, "error stream has been closed.");
|
74
77
|
}
|
78
|
+
if (NULL == es->text &&
|
79
|
+
NULL == (es->text = agoo_text_allocate(1024))) {
|
80
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream buffer.");
|
81
|
+
}
|
75
82
|
if (NULL == (es->text = agoo_text_append(es->text, StringValuePtr(str), cnt))) {
|
76
83
|
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream puts.");
|
77
84
|
}
|
@@ -91,9 +98,10 @@ es_flush(VALUE self) {
|
|
91
98
|
if (NULL == es) {
|
92
99
|
rb_raise(rb_eIOError, "error stream has been closed.");
|
93
100
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
101
|
+
if (NULL != es->text) {
|
102
|
+
agoo_log_cat(&agoo_error_cat, "%s", es->text->text);
|
103
|
+
es->text->len = 0;
|
104
|
+
}
|
97
105
|
return self;
|
98
106
|
}
|
99
107
|
|
data/ext/agoo/gqleval.c
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
#include "gqleval.h"
|
8
8
|
#include "gqlintro.h"
|
9
9
|
#include "gqljson.h"
|
10
|
+
#include "gqlsub.h"
|
10
11
|
#include "gqlvalue.h"
|
11
12
|
#include "graphql.h"
|
12
13
|
#include "http.h"
|
@@ -15,7 +16,9 @@
|
|
15
16
|
#include "res.h"
|
16
17
|
#include "sdl.h"
|
17
18
|
#include "sectime.h"
|
19
|
+
#include "sse.h"
|
18
20
|
#include "text.h"
|
21
|
+
#include "websocket.h"
|
19
22
|
|
20
23
|
#define MAX_RESOLVE_ARGS 16
|
21
24
|
|
@@ -30,6 +33,7 @@ static const char indent_str[] = "indent";
|
|
30
33
|
static const char json_content_type[] = "application/json";
|
31
34
|
static const char operation_name_str[] = "operationName";
|
32
35
|
static const char query_str[] = "query";
|
36
|
+
static const char subscription_str[] = "subscription";
|
33
37
|
static const char variables_str[] = "variables";
|
34
38
|
|
35
39
|
|
@@ -38,7 +42,7 @@ gqlValue (*gql_doc_eval_func)(agooErr err, gqlDoc doc) = NULL;
|
|
38
42
|
// TBD errors should have message, location, and path
|
39
43
|
static void
|
40
44
|
err_resp(agooRes res, agooErr err, int status) {
|
41
|
-
char buf[
|
45
|
+
char buf[1024];
|
42
46
|
int cnt;
|
43
47
|
int64_t now = agoo_now_nano();
|
44
48
|
time_t t = (time_t)(now / 1000000000LL);
|
@@ -54,11 +58,14 @@ err_resp(agooRes res, agooErr err, int status) {
|
|
54
58
|
code,
|
55
59
|
at.year, at.mon, at.day, at.hour, at.min, at.sec, frac);
|
56
60
|
|
57
|
-
agoo_res_message_push(res, agoo_text_create(buf, cnt)
|
61
|
+
agoo_res_message_push(res, agoo_text_create(buf, cnt));
|
58
62
|
}
|
59
63
|
|
64
|
+
static char ws_up[] = "HTTP/1.1 101 Switching Protocols\r\n";
|
65
|
+
|
60
66
|
static void
|
61
|
-
value_resp(
|
67
|
+
value_resp(agooReq req, gqlValue result, int status, int indent) {
|
68
|
+
agooRes res = req->res;
|
62
69
|
char buf[256];
|
63
70
|
struct _agooErr err = AGOO_ERR_INIT;
|
64
71
|
int cnt;
|
@@ -71,6 +78,27 @@ value_resp(agooRes res, gqlValue result, int status, int indent) {
|
|
71
78
|
gql_value_destroy(result);
|
72
79
|
return;
|
73
80
|
}
|
81
|
+
if (NULL == result) {
|
82
|
+
switch (status) {
|
83
|
+
case 101:
|
84
|
+
if (NULL == (text = agoo_text_append(text, ws_up, sizeof(ws_up) - 1)) ||
|
85
|
+
NULL == (text = agoo_ws_add_headers(req, text)) ||
|
86
|
+
NULL == (text = agoo_text_append(text, "\r\n", 2))) {
|
87
|
+
|
88
|
+
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
break;
|
92
|
+
case 200:
|
93
|
+
text = agoo_sse_upgrade(req, text);
|
94
|
+
break;
|
95
|
+
default:
|
96
|
+
agoo_log_cat(&agoo_error_cat, "Did not expect an HTTP status of %d.", status);
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
agoo_res_message_push(res, text);
|
100
|
+
return;
|
101
|
+
}
|
74
102
|
if (AGOO_ERR_OK != gql_object_set(&err, msg, "data", result)) {
|
75
103
|
err_resp(res, &err, 500);
|
76
104
|
gql_value_destroy(result);
|
@@ -84,7 +112,7 @@ value_resp(agooRes res, gqlValue result, int status, int indent) {
|
|
84
112
|
if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
|
85
113
|
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
86
114
|
}
|
87
|
-
agoo_res_message_push(res, text
|
115
|
+
agoo_res_message_push(res, text);
|
88
116
|
}
|
89
117
|
|
90
118
|
gqlValue
|
@@ -361,13 +389,17 @@ gql_eval_get_hook(agooReq req) {
|
|
361
389
|
gqlDoc doc;
|
362
390
|
gqlValue result;
|
363
391
|
gqlVar vars = NULL;
|
392
|
+
gqlOpKind default_kind = GQL_QUERY;
|
364
393
|
|
365
394
|
if (NULL != (gq = agoo_req_query_value(req, indent_str, sizeof(indent_str) - 1, &qlen))) {
|
366
395
|
indent = (int)strtol(gq, NULL, 10);
|
367
396
|
}
|
368
397
|
if (NULL == (gq = agoo_req_query_value(req, query_str, sizeof(query_str) - 1, &qlen))) {
|
369
|
-
|
370
|
-
|
398
|
+
if (NULL == (gq = agoo_req_query_value(req, subscription_str, sizeof(subscription_str) - 1, &qlen))) {
|
399
|
+
err_resp(req->res, &err, 500);
|
400
|
+
return;
|
401
|
+
}
|
402
|
+
default_kind = GQL_SUBSCRIPTION;
|
371
403
|
}
|
372
404
|
op_name = agoo_req_query_value(req, operation_name_str, sizeof(operation_name_str) - 1, &oplen);
|
373
405
|
var_json = agoo_req_query_value(req, variables_str, sizeof(variables_str) - 1, &vlen);
|
@@ -380,7 +412,7 @@ gql_eval_get_hook(agooReq req) {
|
|
380
412
|
}
|
381
413
|
// Only call after extracting the variables as it terminates the string with a \0.
|
382
414
|
qlen = agoo_req_query_decode((char*)gq, qlen);
|
383
|
-
if (NULL == (doc = sdl_parse_doc(&err, gq, qlen, vars))) {
|
415
|
+
if (NULL == (doc = sdl_parse_doc(&err, gq, qlen, vars, default_kind))) {
|
384
416
|
err_resp(req->res, &err, 500);
|
385
417
|
return;
|
386
418
|
}
|
@@ -391,12 +423,55 @@ gql_eval_get_hook(agooReq req) {
|
|
391
423
|
} else {
|
392
424
|
result = gql_doc_eval_func(&err, doc);
|
393
425
|
}
|
394
|
-
gql_doc_destroy(doc);
|
395
426
|
if (NULL == result) {
|
427
|
+
gql_doc_destroy(doc);
|
396
428
|
err_resp(req->res, &err, 500);
|
397
429
|
return;
|
398
430
|
}
|
399
|
-
|
431
|
+
if (GQL_SUBSCRIPTION == doc->op->kind) {
|
432
|
+
int status = 200;
|
433
|
+
gqlValue sv;
|
434
|
+
const char *subject;
|
435
|
+
gqlSub sub;
|
436
|
+
|
437
|
+
switch (req->res->con_kind) {
|
438
|
+
case AGOO_CON_WS:
|
439
|
+
status = 101;
|
440
|
+
break;
|
441
|
+
case AGOO_CON_SSE:
|
442
|
+
break;
|
443
|
+
default:
|
444
|
+
gql_doc_destroy(doc);
|
445
|
+
agoo_err_set(&err, AGOO_ERR_NETWORK, "An upgrade to Websockets or SSE is required for a GraphQL subscription.");
|
446
|
+
err_resp(req->res, &err, 426);
|
447
|
+
return;
|
448
|
+
}
|
449
|
+
if (NULL == (sv = gql_object_get(result, "subject"))) {
|
450
|
+
struct _agooErr e;
|
451
|
+
|
452
|
+
agoo_err_set(&e, AGOO_ERR_TYPE, "subscription did not return a subject");
|
453
|
+
err_resp(req->res, &e, 400);
|
454
|
+
gql_doc_destroy(doc);
|
455
|
+
return;
|
456
|
+
}
|
457
|
+
subject = gql_string_get(sv);
|
458
|
+
|
459
|
+
if (AGOO_CON_WS == req->res->con_kind) {
|
460
|
+
status = 101;
|
461
|
+
}
|
462
|
+
doc->op->kind = GQL_QUERY; // need so eval does the right thing
|
463
|
+
if (NULL == (sub = gql_sub_create(&err, req->res->con, subject, doc))) {
|
464
|
+
err_resp(req->res, &err, 400);
|
465
|
+
return;
|
466
|
+
}
|
467
|
+
agoo_server_add_gsub(sub);
|
468
|
+
|
469
|
+
value_resp(req, NULL, status, indent);
|
470
|
+
|
471
|
+
return;
|
472
|
+
}
|
473
|
+
gql_doc_destroy(doc);
|
474
|
+
value_resp(req, result, 200, indent);
|
400
475
|
}
|
401
476
|
|
402
477
|
static gqlValue
|
@@ -429,7 +504,7 @@ eval_post(agooErr err, agooReq req) {
|
|
429
504
|
return NULL;
|
430
505
|
}
|
431
506
|
if (0 == strncmp(graphql_content_type, s, sizeof(graphql_content_type) - 1)) {
|
432
|
-
if (NULL == (doc = sdl_parse_doc(err, req->body.start, req->body.len, vars))) {
|
507
|
+
if (NULL == (doc = sdl_parse_doc(err, req->body.start, req->body.len, vars, GQL_QUERY))) {
|
433
508
|
return NULL;
|
434
509
|
}
|
435
510
|
} else if (0 == strncmp(json_content_type, s, sizeof(json_content_type) - 1)) {
|
@@ -474,7 +549,7 @@ eval_post(agooErr err, agooReq req) {
|
|
474
549
|
}
|
475
550
|
}
|
476
551
|
}
|
477
|
-
if (NULL == (doc = sdl_parse_doc(err, query, qlen, vars))) {
|
552
|
+
if (NULL == (doc = sdl_parse_doc(err, query, qlen, vars, GQL_QUERY))) {
|
478
553
|
goto DONE;
|
479
554
|
}
|
480
555
|
} else {
|
@@ -491,7 +566,9 @@ eval_post(agooErr err, agooReq req) {
|
|
491
566
|
} else {
|
492
567
|
result = gql_doc_eval_func(err, doc);
|
493
568
|
}
|
494
|
-
|
569
|
+
if (GQL_SUBSCRIPTION == doc->op->kind) {
|
570
|
+
result = NULL;
|
571
|
+
}
|
495
572
|
DONE:
|
496
573
|
gql_doc_destroy(doc);
|
497
574
|
gql_value_destroy(j);
|
@@ -510,10 +587,12 @@ gql_eval_post_hook(agooReq req) {
|
|
510
587
|
if (NULL != (s = agoo_req_query_value(req, indent_str, sizeof(indent_str) - 1, &len))) {
|
511
588
|
indent = (int)strtol(s, NULL, 10);
|
512
589
|
}
|
513
|
-
if (NULL == (result = eval_post(&err, req))) {
|
590
|
+
if (NULL == (result = eval_post(&err, req)) && AGOO_ERR_OK != err.code) {
|
514
591
|
err_resp(req->res, &err, 400);
|
592
|
+
} else if (NULL == result) {
|
593
|
+
value_resp(req, result, 200, indent);
|
515
594
|
} else {
|
516
|
-
value_resp(req
|
595
|
+
value_resp(req, result, 200, indent);
|
517
596
|
}
|
518
597
|
}
|
519
598
|
|
data/ext/agoo/gqlsub.c
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
// Copyright (c) 2019, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include "con.h"
|
4
|
+
#include "debug.h"
|
5
|
+
#include "gqlsub.h"
|
6
|
+
#include "graphql.h"
|
7
|
+
|
8
|
+
gqlSub
|
9
|
+
gql_sub_create(agooErr err, agooCon con, const char *subject, struct _gqlDoc *query) {
|
10
|
+
gqlSub sub = (gqlSub)AGOO_MALLOC(sizeof(struct _gqlSub));
|
11
|
+
|
12
|
+
if (NULL == sub) {
|
13
|
+
AGOO_ERR_MEM(err, "gqlSub");
|
14
|
+
return NULL;
|
15
|
+
}
|
16
|
+
if (NULL == (sub->subject = AGOO_STRDUP(subject))) {
|
17
|
+
AGOO_ERR_MEM(err, "strdup()");
|
18
|
+
AGOO_FREE(sub);
|
19
|
+
return NULL;
|
20
|
+
}
|
21
|
+
sub->next = NULL;
|
22
|
+
sub->con = con;
|
23
|
+
con->gsub = sub;
|
24
|
+
sub->query = query;
|
25
|
+
|
26
|
+
return sub;
|
27
|
+
|
28
|
+
}
|
29
|
+
|
30
|
+
void
|
31
|
+
gql_sub_destroy(gqlSub sub) {
|
32
|
+
AGOO_FREE(sub->subject);
|
33
|
+
if (NULL != sub->query) {
|
34
|
+
gql_doc_destroy(sub->query);
|
35
|
+
}
|
36
|
+
AGOO_FREE(sub);
|
37
|
+
}
|
data/ext/agoo/gqlsub.h
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
// Copyright (c) 2019, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef AGOO_GQL_SUB_H
|
4
|
+
#define AGOO_GQL_SUB_H
|
5
|
+
|
6
|
+
#include <stdbool.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
|
9
|
+
#include "err.h"
|
10
|
+
|
11
|
+
struct _agooCon;
|
12
|
+
struct _gqlDoc;
|
13
|
+
|
14
|
+
typedef struct _gqlSub {
|
15
|
+
struct _gqlSub *next;
|
16
|
+
struct _agooCon *con;
|
17
|
+
char *subject;
|
18
|
+
struct _gqlDoc *query;
|
19
|
+
} *gqlSub;
|
20
|
+
|
21
|
+
extern gqlSub gql_sub_create(agooErr err, struct _agooCon *con, const char *subject, struct _gqlDoc *query);
|
22
|
+
extern void gql_sub_destroy(gqlSub sub);
|
23
|
+
|
24
|
+
#endif // AGOO_GQL_SUB_H
|
data/ext/agoo/gqlvalue.c
CHANGED
@@ -993,6 +993,20 @@ gql_object_set(agooErr err, gqlValue obj, const char *key, gqlValue item) {
|
|
993
993
|
return AGOO_ERR_OK;
|
994
994
|
}
|
995
995
|
|
996
|
+
gqlValue
|
997
|
+
gql_object_get(gqlValue obj, const char *key) {
|
998
|
+
if (NULL != obj && obj->type == &object_type) {
|
999
|
+
gqlLink link = obj->members;
|
1000
|
+
|
1001
|
+
for (; NULL != link; link = link->next) {
|
1002
|
+
if (0 == strcmp(link->key, key)) {
|
1003
|
+
return link->value;
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
return NULL;
|
1008
|
+
}
|
1009
|
+
|
996
1010
|
/// create functions //////////////////////////////////////////////////////////
|
997
1011
|
|
998
1012
|
static gqlValue
|
data/ext/agoo/gqlvalue.h
CHANGED
@@ -74,6 +74,7 @@ extern gqlValue gql_object_create(agooErr err);
|
|
74
74
|
extern int gql_list_append(agooErr err, gqlValue list, gqlValue item);
|
75
75
|
extern int gql_list_preend(agooErr err, gqlValue list, gqlValue item);
|
76
76
|
extern int gql_object_set(agooErr err, gqlValue obj, const char *key, gqlValue item);
|
77
|
+
extern gqlValue gql_object_get(gqlValue obj, const char *key);
|
77
78
|
|
78
79
|
extern void gql_int_set(gqlValue value, int32_t i);
|
79
80
|
extern void gql_i64_set(gqlValue value, int64_t i);
|
data/ext/agoo/graphql.c
CHANGED
@@ -1556,7 +1556,18 @@ static agooText
|
|
1556
1556
|
op_sdl(agooText text, gqlOp op) {
|
1557
1557
|
gqlSel sel;
|
1558
1558
|
|
1559
|
-
|
1559
|
+
switch (op->kind) {
|
1560
|
+
case GQL_MUTATION:
|
1561
|
+
text = agoo_text_append(text, "mutation", 8);
|
1562
|
+
break;
|
1563
|
+
case GQL_SUBSCRIPTION:
|
1564
|
+
text = agoo_text_append(text, "subscription", 12);
|
1565
|
+
break;
|
1566
|
+
case GQL_QUERY:
|
1567
|
+
default:
|
1568
|
+
text = agoo_text_append(text, "query", 5);
|
1569
|
+
break;
|
1570
|
+
}
|
1560
1571
|
if (NULL != op->name) {
|
1561
1572
|
text = agoo_text_append(text, " ", 1);
|
1562
1573
|
text = agoo_text_append(text, op->name, -1);
|
@@ -1647,7 +1658,7 @@ gql_dump_hook(agooReq req) {
|
|
1647
1658
|
if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
|
1648
1659
|
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a GraphQL dump.");
|
1649
1660
|
}
|
1650
|
-
agoo_res_message_push(req->res, text
|
1661
|
+
agoo_res_message_push(req->res, text);
|
1651
1662
|
}
|
1652
1663
|
|
1653
1664
|
gqlField
|