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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 843f3aa4a15a6ab57c7ff231930405c9ca55d3a6e33da3169a0677c420195fbe
4
- data.tar.gz: 03f6b8760c6f08c0a3f9b5f75c747b77d1d4666b00af20d7db231418dfeb3c69
3
+ metadata.gz: ad246b7aa0e634eff81c6c9bdec4d3567115a3beb8b6c237e25f87215fc2dbe3
4
+ data.tar.gz: 03b6217fd351024938607dd036dcfd437a0dd967b22eca2b51aa0ed8a041d969
5
5
  SHA512:
6
- metadata.gz: '0684900cea98fbe812e5ae973ccd15dfaa054218340238dedfde382c535340945aea9857b98366fe52b2ff865129b299af541e940112200f2191b3b2247dfd58'
7
- data.tar.gz: 95e68a0a7bc5a3eb8cd34b9853e8d89285ef9a1c78765bf970e80cdeb51f7f41f53db4948ca2885e29eef3fa7a6b738e015d01c4cbb25e41b2f50bac1fcb50a9
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, 500);
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
- err_resp(req->res, &err, 400);
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, NULL, NULL, req);
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
- Qnil == (v = rb_funcall(root, m, 0))) {
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
- char schema_path[256];
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
- dump_hook->next = get_hook;
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 = dump_hook;
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
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Agoo
3
3
  # Agoo version.
4
- VERSION = '2.14.3'
4
+ VERSION = '2.15.2'
5
5
  end
@@ -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.14.3
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-05-05 00:00:00.000000000 Z
11
+ date: 2022-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj