agoo 2.14.3 → 2.15.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/ext/agoo/con.c +2 -0
- data/ext/agoo/gqleval.c +14 -2
- data/ext/agoo/request.c +30 -1
- data/ext/agoo/rgraphql.c +24 -2
- data/ext/agoo/rserver.c +24 -10
- data/lib/agoo/version.rb +1 -1
- data/test/rack_handler_test.rb +18 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ad246b7aa0e634eff81c6c9bdec4d3567115a3beb8b6c237e25f87215fc2dbe3
|
|
4
|
+
data.tar.gz: 03b6217fd351024938607dd036dcfd437a0dd967b22eca2b51aa0ed8a041d969
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a244ea77e0f13688e2e6237c31eb320af4c0eeb9780f6023ef6337db7f64839ce543a27d5890155fb0908f0ce6567733b750be0d7b7c4de246430c54a736b6f4
|
|
7
|
+
data.tar.gz: abf7f274c15852b21b64ac6018b03264d08968902b9ad71d4f56d84a5ea34cf018b5e26daf6bde44f7f748da57a889c373435658cfb085ff537f3a683433c6d3
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All changes to the Agoo gem are documented here. Releases follow semantic versioning.
|
|
4
4
|
|
|
5
|
+
## [2.15.2] - 2022-06-21
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Request no longer crashes when `#env` is not called before `#set`.
|
|
10
|
+
|
|
11
|
+
## [2.15.1] - 2022-06-18
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Introspection can now be disabled with the `hide_schema` option to the Agoo server.
|
|
16
|
+
|
|
17
|
+
- If an exception raised from a GraphQL callback responds to `code`
|
|
18
|
+
that code will be used as the HTTP status.
|
|
19
|
+
|
|
20
|
+
- Added missing ability to set or add elements of a request argument
|
|
21
|
+
on GraphQL callback methods.
|
|
22
|
+
|
|
23
|
+
## [2.15.0] - 2022-05-20
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Support added for PATCH.
|
|
28
|
+
|
|
29
|
+
- A `:hide_schema` option has been added to show the graphql/schema as
|
|
30
|
+
not found unless added by with the handle method of the server.
|
|
31
|
+
|
|
32
|
+
- Raising an exception that responds to `code` in a graphql resolve
|
|
33
|
+
function will return that code as the HTTP status code.
|
|
34
|
+
|
|
5
35
|
## [2.14.3] - 2022-05-05
|
|
6
36
|
|
|
7
37
|
### Fixed
|
data/ext/agoo/con.c
CHANGED
|
@@ -327,6 +327,8 @@ con_header_read(agooCon c, size_t *mlenp) {
|
|
|
327
327
|
method = AGOO_PUT;
|
|
328
328
|
} else if (4 == b - c->buf && 0 == strncmp("POST", c->buf, 4)) {
|
|
329
329
|
method = AGOO_POST;
|
|
330
|
+
} else if (5 == b - c->buf && 0 == strncmp("PATCH", c->buf, 5)) {
|
|
331
|
+
method = AGOO_PATCH;
|
|
330
332
|
} else {
|
|
331
333
|
return bad_request(c, 400, __LINE__);
|
|
332
334
|
}
|
data/ext/agoo/gqleval.c
CHANGED
|
@@ -478,8 +478,14 @@ gql_eval_get_hook(agooReq req) {
|
|
|
478
478
|
result = gql_doc_eval_func(&err, doc);
|
|
479
479
|
}
|
|
480
480
|
if (NULL == result) {
|
|
481
|
+
int code = 500;
|
|
482
|
+
|
|
483
|
+
if (err.code < 0) {
|
|
484
|
+
code = -err.code;
|
|
485
|
+
}
|
|
486
|
+
err.code = AGOO_ERR_EVAL;
|
|
481
487
|
gql_doc_destroy(doc);
|
|
482
|
-
err_resp(req->res, &err,
|
|
488
|
+
err_resp(req->res, &err, code);
|
|
483
489
|
return;
|
|
484
490
|
}
|
|
485
491
|
if (GQL_SUBSCRIPTION == doc->op->kind) {
|
|
@@ -648,7 +654,13 @@ gql_eval_post_hook(agooReq req) {
|
|
|
648
654
|
indent = (int)strtol(s, NULL, 10);
|
|
649
655
|
}
|
|
650
656
|
if (NULL == (result = eval_post(&err, req)) && AGOO_ERR_OK != err.code) {
|
|
651
|
-
|
|
657
|
+
int code = 400;
|
|
658
|
+
|
|
659
|
+
if (err.code < 0) {
|
|
660
|
+
code = -err.code;
|
|
661
|
+
}
|
|
662
|
+
err.code = AGOO_ERR_EVAL;
|
|
663
|
+
err_resp(req->res, &err, code);
|
|
652
664
|
} else if (NULL == result) {
|
|
653
665
|
value_resp(req, result, 200, indent);
|
|
654
666
|
} else {
|
data/ext/agoo/request.c
CHANGED
|
@@ -684,10 +684,38 @@ call(VALUE self) {
|
|
|
684
684
|
return io;
|
|
685
685
|
}
|
|
686
686
|
|
|
687
|
+
/* Document-method: set
|
|
688
|
+
*
|
|
689
|
+
* call-seq: set()
|
|
690
|
+
*
|
|
691
|
+
* Sets an key value pair to the environment of the request.
|
|
692
|
+
*/
|
|
693
|
+
static VALUE
|
|
694
|
+
set(VALUE self, VALUE key, VALUE val) {
|
|
695
|
+
agooReq r = DATA_PTR(self);
|
|
696
|
+
|
|
697
|
+
if (NULL == r) {
|
|
698
|
+
rb_raise(rb_eArgError, "Request is no longer valid.");
|
|
699
|
+
}
|
|
700
|
+
request_env(r, self);
|
|
701
|
+
rb_hash_aset((VALUE)r->env, key, val);
|
|
702
|
+
|
|
703
|
+
return Qnil;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
static void
|
|
707
|
+
request_mark(void *ptr) {
|
|
708
|
+
agooReq r = (agooReq)ptr;
|
|
709
|
+
|
|
710
|
+
if (NULL != r->env && Qnil != (VALUE)r->env) {
|
|
711
|
+
rb_gc_mark((VALUE)r->env);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
687
715
|
VALUE
|
|
688
716
|
request_wrap(agooReq req) {
|
|
689
717
|
// freed from the C side of things
|
|
690
|
-
return Data_Wrap_Struct(req_class,
|
|
718
|
+
return Data_Wrap_Struct(req_class, request_mark, NULL, req);
|
|
691
719
|
}
|
|
692
720
|
|
|
693
721
|
/* Document-class: Agoo::Request
|
|
@@ -723,6 +751,7 @@ request_init(VALUE mod) {
|
|
|
723
751
|
rb_define_method(req_class, "body", body, 0);
|
|
724
752
|
rb_define_method(req_class, "rack_logger", rack_logger, 0);
|
|
725
753
|
rb_define_method(req_class, "call", call, 0);
|
|
754
|
+
rb_define_method(req_class, "set", set, 2);
|
|
726
755
|
|
|
727
756
|
new_id = rb_intern("new");
|
|
728
757
|
|
data/ext/agoo/rgraphql.c
CHANGED
|
@@ -58,8 +58,24 @@ make_ruby_use(agooErr err,
|
|
|
58
58
|
volatile VALUE v;
|
|
59
59
|
ID m = rb_intern(method);
|
|
60
60
|
|
|
61
|
-
if (!rb_respond_to(root, m)
|
|
62
|
-
|
|
61
|
+
if (!rb_respond_to(root, m)) {
|
|
62
|
+
return AGOO_ERR_OK;
|
|
63
|
+
}
|
|
64
|
+
switch (rb_obj_method_arity(root, m)) {
|
|
65
|
+
case 0:
|
|
66
|
+
v = rb_funcall(root, m, 0);
|
|
67
|
+
break;
|
|
68
|
+
case 1:
|
|
69
|
+
v = rb_funcall(root, m, 1, Qnil);
|
|
70
|
+
break;
|
|
71
|
+
case 2:
|
|
72
|
+
v = rb_funcall(root, m, 2, Qnil, Qnil);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
v = Qnil;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
if (Qnil == v) {
|
|
63
79
|
return AGOO_ERR_OK;
|
|
64
80
|
}
|
|
65
81
|
if (NULL == (type = gql_type_get(type_name))) {
|
|
@@ -89,7 +105,13 @@ rescue_error(VALUE x, VALUE ignore) {
|
|
|
89
105
|
const char *ms = rb_string_value_ptr(&msg);
|
|
90
106
|
|
|
91
107
|
agoo_err_set(eval->err, AGOO_ERR_EVAL, "%s: %s", classname, ms);
|
|
108
|
+
if (rb_respond_to(info, rb_intern("code"))) {
|
|
109
|
+
VALUE code = rb_funcall(info, rb_intern("code"), 0);
|
|
92
110
|
|
|
111
|
+
if (RUBY_T_FIXNUM == rb_type(code)) {
|
|
112
|
+
eval->err->code = -FIX2INT(code);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
93
115
|
return Qfalse;
|
|
94
116
|
}
|
|
95
117
|
|
data/ext/agoo/rserver.c
CHANGED
|
@@ -48,6 +48,7 @@ static VALUE options_sym;
|
|
|
48
48
|
static VALUE post_sym;
|
|
49
49
|
static VALUE push_env_key;
|
|
50
50
|
static VALUE put_sym;
|
|
51
|
+
static VALUE patch_sym;
|
|
51
52
|
|
|
52
53
|
static VALUE rserver;
|
|
53
54
|
|
|
@@ -207,12 +208,12 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
|
207
208
|
}
|
|
208
209
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("graphql"))))) {
|
|
209
210
|
const char *path;
|
|
210
|
-
agooHook dump_hook;
|
|
211
211
|
agooHook get_hook;
|
|
212
212
|
agooHook post_hook;
|
|
213
213
|
agooHook options_hook;
|
|
214
|
-
|
|
214
|
+
agooHook head = NULL;
|
|
215
215
|
long plen;
|
|
216
|
+
VALUE hide_schema = Qnil;
|
|
216
217
|
|
|
217
218
|
rb_check_type(v, T_STRING);
|
|
218
219
|
if (AGOO_ERR_OK != gql_init(err)) {
|
|
@@ -220,21 +221,29 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
|
220
221
|
}
|
|
221
222
|
path = StringValuePtr(v);
|
|
222
223
|
plen = (long)RSTRING_LEN(v);
|
|
223
|
-
if ((int)sizeof(schema_path) - 8 < plen) {
|
|
224
|
-
rb_raise(rb_eArgError, "A graphql schema path is limited to %d characters.", (int)(sizeof(schema_path) - 8));
|
|
225
|
-
}
|
|
226
|
-
memcpy(schema_path, path, plen);
|
|
227
|
-
memcpy(schema_path + plen, "/schema", 8);
|
|
228
224
|
|
|
229
|
-
dump_hook = agoo_hook_func_create(AGOO_GET, schema_path, gql_dump_hook, &agoo_server.eval_queue);
|
|
230
225
|
get_hook = agoo_hook_func_create(AGOO_GET, path, gql_eval_get_hook, &agoo_server.eval_queue);
|
|
231
226
|
post_hook = agoo_hook_func_create(AGOO_POST, path, gql_eval_post_hook, &agoo_server.eval_queue);
|
|
232
227
|
options_hook = agoo_hook_func_create(AGOO_OPTIONS, path, gql_eval_options_hook, &agoo_server.eval_queue);
|
|
233
|
-
|
|
228
|
+
if (Qnil != (hide_schema = rb_hash_lookup(options, ID2SYM(rb_intern("hide_schema")))) && Qtrue == hide_schema) {
|
|
229
|
+
head = get_hook;
|
|
230
|
+
} else {
|
|
231
|
+
char schema_path[256];
|
|
232
|
+
agooHook dump_hook;
|
|
233
|
+
|
|
234
|
+
if ((int)sizeof(schema_path) - 8 < plen) {
|
|
235
|
+
rb_raise(rb_eArgError, "A graphql schema path is limited to %d characters.", (int)(sizeof(schema_path) - 8));
|
|
236
|
+
}
|
|
237
|
+
memcpy(schema_path, path, plen);
|
|
238
|
+
memcpy(schema_path + plen, "/schema", 8);
|
|
239
|
+
dump_hook = agoo_hook_func_create(AGOO_GET, schema_path, gql_dump_hook, &agoo_server.eval_queue);
|
|
240
|
+
dump_hook->next = get_hook;
|
|
241
|
+
head = dump_hook;
|
|
242
|
+
}
|
|
234
243
|
get_hook->next = post_hook;
|
|
235
244
|
post_hook->next = options_hook;
|
|
236
245
|
options_hook->next = agoo_server.hooks;
|
|
237
|
-
agoo_server.hooks =
|
|
246
|
+
agoo_server.hooks = head;
|
|
238
247
|
}
|
|
239
248
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("quiet"))))) {
|
|
240
249
|
if (Qtrue == v) {
|
|
@@ -295,6 +304,8 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
|
295
304
|
* - *:ssl_sert* [_String_] filepath to the SSL certificate file.
|
|
296
305
|
*
|
|
297
306
|
* - *:ssl_key* [_String_] filepath to the SSL private key file.
|
|
307
|
+
*
|
|
308
|
+
* - *:hide_schema* [_true_|_false_] if true the graphql/schema path is handled.
|
|
298
309
|
*/
|
|
299
310
|
static VALUE
|
|
300
311
|
rserver_init(int argc, VALUE *argv, VALUE self) {
|
|
@@ -971,6 +982,8 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
|
|
971
982
|
meth = AGOO_POST;
|
|
972
983
|
} else if (put_sym == method) {
|
|
973
984
|
meth = AGOO_PUT;
|
|
985
|
+
} else if (patch_sym == method) {
|
|
986
|
+
meth = AGOO_PATCH;
|
|
974
987
|
} else if (Qnil == method) {
|
|
975
988
|
meth = AGOO_ALL;
|
|
976
989
|
} else {
|
|
@@ -1277,6 +1290,7 @@ server_init(VALUE mod) {
|
|
|
1277
1290
|
options_sym = ID2SYM(rb_intern("OPTIONS")); rb_gc_register_address(&options_sym);
|
|
1278
1291
|
post_sym = ID2SYM(rb_intern("POST")); rb_gc_register_address(&post_sym);
|
|
1279
1292
|
put_sym = ID2SYM(rb_intern("PUT")); rb_gc_register_address(&put_sym);
|
|
1293
|
+
patch_sym = ID2SYM(rb_intern("PATCH")); rb_gc_register_address(&patch_sym);
|
|
1280
1294
|
|
|
1281
1295
|
push_env_key = rb_str_new_cstr("rack.upgrade"); rb_gc_register_address(&push_env_key);
|
|
1282
1296
|
|
data/lib/agoo/version.rb
CHANGED
data/test/rack_handler_test.rb
CHANGED
|
@@ -33,7 +33,7 @@ size=big
|
|
|
33
33
|
]
|
|
34
34
|
elsif 'POST' == req['REQUEST_METHOD']
|
|
35
35
|
[ 204, { }, [] ]
|
|
36
|
-
elsif 'PUT' == req['REQUEST_METHOD']
|
|
36
|
+
elsif 'PUT' == req['REQUEST_METHOD'] || 'PATCH' == req['REQUEST_METHOD']
|
|
37
37
|
[ 201,
|
|
38
38
|
{ },
|
|
39
39
|
[ req['rack.input'].read ]
|
|
@@ -65,6 +65,7 @@ size=big
|
|
|
65
65
|
Agoo::Server.handle(:GET, "/tellme", handler)
|
|
66
66
|
Agoo::Server.handle(:POST, "/makeme", handler)
|
|
67
67
|
Agoo::Server.handle(:PUT, "/makeme", handler)
|
|
68
|
+
Agoo::Server.handle(:PATCH, "/makeme", handler)
|
|
68
69
|
|
|
69
70
|
Agoo::Server.start()
|
|
70
71
|
|
|
@@ -156,4 +157,20 @@ size=big
|
|
|
156
157
|
assert_equal('hello', res.body)
|
|
157
158
|
end
|
|
158
159
|
|
|
160
|
+
def test_patch
|
|
161
|
+
uri = URI('http://localhost:6467/makeme')
|
|
162
|
+
req = Net::HTTP::Patch.new(uri)
|
|
163
|
+
# Set the headers the way we want them.
|
|
164
|
+
req['Accept-Encoding'] = '*'
|
|
165
|
+
req['Accept'] = 'application/json'
|
|
166
|
+
req['User-Agent'] = 'Ruby'
|
|
167
|
+
req.body = 'hello'
|
|
168
|
+
|
|
169
|
+
res = Net::HTTP.start(uri.hostname, uri.port) { |h|
|
|
170
|
+
h.request(req)
|
|
171
|
+
}
|
|
172
|
+
assert_equal(Net::HTTPCreated, res.class)
|
|
173
|
+
assert_equal('hello', res.body)
|
|
174
|
+
end
|
|
175
|
+
|
|
159
176
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: agoo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.15.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Ohler
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-06-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: oj
|