agoo 2.12.3 → 2.13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d0965efaeccced647216fb862b8dfbc08341340b11cf9f3844ad02d69689037
4
- data.tar.gz: 28214398cdde45c6ff314cca9fef6d59c52eb4602e1589d6e0ffcb2df20dea1e
3
+ metadata.gz: df42da153e97e018d4984fa75be78ac86a1c8b97aed6b48d62ec7fe5047d7099
4
+ data.tar.gz: e83a55eed4781bbb0ab08df41203509df6ec45d06817b87c9d61d25bca8a294a
5
5
  SHA512:
6
- metadata.gz: ca54ef2d81c61b6175853ddc45d14c1654c56a0aff3cb3ddfd89513c0422d6f0442e67b7fb77650b090b1ae3dd3a8784d15eb1fd8610923d5d1514873b7755a4
7
- data.tar.gz: bd950219f2e91ec4bdac217c646184c883ea789c8d7d6ab9a3b9f3459aab96c149aa6701a5b705f3e86f7786b5c0a634d1c1f41dce456a35d153aaeb656f20c8
6
+ metadata.gz: ac6e8d86a9b545d93c9ee033950422292b4ab2f740ba692f2c24940e928c42466b895dfae6ce5263040f2b53613a6c1241f5dfe5c0be21961f1ee885970ec220
7
+ data.tar.gz: 9dd8414c88948198bd1a22d5aac236ef8d5bf4251020b7fcfc4b94837d8a48433aa6774ba9e13df1dc36dc1e29f1697dfcc2c21e8ef1a9dc6897d223b72eb946
@@ -2,6 +2,16 @@
2
2
 
3
3
  All changes to the Agoo gem are documented here. Releases follow semantic versioning.
4
4
 
5
+ ## [2.13.0] - 2020-07-05
6
+
7
+ ### Added
8
+
9
+ - Agoo::Server.use() added. It works similar to the Rack use() function.
10
+
11
+ ### Fixed
12
+
13
+ - Header checks are now case insensitive to comply with RFC 7230.
14
+
5
15
  ## [2.12.3] - 2020-03-28
6
16
 
7
17
  rb_rescue2 termination
@@ -30,7 +30,7 @@ Example:
30
30
  @opts = OptionParser.new(usage)
31
31
  @opts.on('-h', '--help', 'show this display') { puts @opts.help; Process.exit!(0) }
32
32
  @opts.on('-v', '--verbose', 'verbose output') { @verbose = true }
33
- @opts.on('-s', '--single PATH', String, 'path to fiel for all stubs') { |s| @single = s }
33
+ @opts.on('-s', '--single PATH', String, 'path to file for all stubs') { |s| @single = s }
34
34
  @opts.on('-d', '--dir PATH', String, 'directory to write files into') { |d| @dir = d }
35
35
  @opts.on('-m', '--module STRING', String, 'module for the stub classes') { |m| @mod = m }
36
36
 
@@ -66,8 +66,8 @@ def write_type_stub(f, t, depth)
66
66
  next if field.args.nil?
67
67
  f.puts
68
68
  f.puts "#{indent} # #{field.description}" unless field.description.nil?
69
- args = field.args.map { |a| a.name }.join(', ')
70
- f.puts "#{indent} def #{field.name}(#{args})"
69
+ f.puts "#{indent} # args: #{field.args.map { |a| a.name }.join(', ')}"
70
+ f.puts "#{indent} def #{field.name}(args={})"
71
71
  f.puts "#{indent} end"
72
72
  }
73
73
  f.puts "#{indent}end"
@@ -223,25 +223,25 @@ url_ssl(agooErr err, const char *url) {
223
223
 
224
224
  agooBind
225
225
  agoo_bind_url(agooErr err, const char *url) {
226
- if (0 == strncmp("tcp://", url, 6)) {
226
+ if (0 == strncasecmp("tcp://", url, 6)) {
227
227
  if ('[' == url[6]) {
228
228
  return url_tcp6(err, url + 6, "tcp");
229
229
  }
230
230
  return url_tcp(err, url + 6, "tcp");
231
231
  }
232
- if (0 == strncmp("http://", url, 7)) {
232
+ if (0 == strncasecmp("http://", url, 7)) {
233
233
  if ('[' == url[7]) {
234
234
  return url_tcp6(err, url + 7, "http");
235
235
  }
236
236
  return url_tcp(err, url + 7, "http");
237
237
  }
238
- if (0 == strncmp("unix://", url, 7)) {
238
+ if (0 == strncasecmp("unix://", url, 7)) {
239
239
  return url_named(err, url + 7);
240
240
  }
241
- if (0 == strncmp("https://", url, 8)) {
241
+ if (0 == strncasecmp("https://", url, 8)) {
242
242
  return url_ssl(err, url + 8);
243
243
  }
244
- if (0 == strncmp("ssl://", url, 6)) {
244
+ if (0 == strncasecmp("ssl://", url, 6)) {
245
245
  return url_ssl(err, url + 6);
246
246
  }
247
247
  // All others assume http
@@ -173,7 +173,7 @@ agoo_con_header_value(const char *header, int hlen, const char *key, int *vlen)
173
173
  int klen = (int)strlen(key);
174
174
 
175
175
  while (h < hend) {
176
- if (0 == strncmp(key, h, klen) && ':' == h[klen]) {
176
+ if (0 == strncasecmp(key, h, klen) && ':' == h[klen]) {
177
177
  h += klen + 1;
178
178
  for (; ' ' == *h; h++) {
179
179
  }
@@ -551,11 +551,11 @@ eval_post(agooErr err, agooReq req) {
551
551
  agoo_err_set(err, AGOO_ERR_TYPE, "required Content-Type not in the HTTP header");
552
552
  return NULL;
553
553
  }
554
- if (0 == strncmp(graphql_content_type, s, sizeof(graphql_content_type) - 1)) {
554
+ if (0 == strncasecmp(graphql_content_type, s, sizeof(graphql_content_type) - 1)) {
555
555
  if (NULL == (doc = sdl_parse_doc(err, req->body.start, req->body.len, vars, GQL_QUERY))) {
556
556
  return NULL;
557
557
  }
558
- } else if (0 == strncmp(json_content_type, s, sizeof(json_content_type) - 1)) {
558
+ } else if (0 == strncasecmp(json_content_type, s, sizeof(json_content_type) - 1)) {
559
559
  gqlLink m;
560
560
 
561
561
  if (NULL != (j = gql_json_parse(err, req->body.start, req->body.len))) {
@@ -14,7 +14,7 @@ agooReq
14
14
  agoo_req_create(size_t mlen) {
15
15
  size_t size = mlen + sizeof(struct _agooReq) - 7;
16
16
  agooReq req = (agooReq)AGOO_MALLOC(size);
17
-
17
+
18
18
  if (NULL != req) {
19
19
  memset(req, 0, size);
20
20
  req->env = agoo_server.env_nil_value;
@@ -56,7 +56,7 @@ agoo_req_port(agooReq r) {
56
56
  int len;
57
57
  const char *host;
58
58
  const char *colon;
59
-
59
+
60
60
  if (NULL == (host = agoo_con_header_value(r->header.start, r->header.len, "Host", &len))) {
61
61
  return 0;
62
62
  }
@@ -94,7 +94,7 @@ agoo_req_query_value(agooReq r, const char *key, int klen, int *vlenp) {
94
94
  static int
95
95
  hexVal(int c) {
96
96
  int h = -1;
97
-
97
+
98
98
  if ('0' <= c && c <= '9') {
99
99
  h = c - '0';
100
100
  } else if ('a' <= c && c <= 'f') {
@@ -110,12 +110,12 @@ agoo_req_query_decode(char *s, int len) {
110
110
  char *sn = s;
111
111
  char *so = s;
112
112
  char *end = s + len;
113
-
113
+
114
114
  while (so < end) {
115
115
  if ('%' == *so) {
116
116
  int n;
117
117
  int c = 0;
118
-
118
+
119
119
  so++;
120
120
  if (0 > (c = hexVal(*so))) {
121
121
  *sn++ = '%';
@@ -133,7 +133,7 @@ agoo_req_query_decode(char *s, int len) {
133
133
  }
134
134
  }
135
135
  *sn = '\0';
136
-
136
+
137
137
  return (int)(sn - s);
138
138
  }
139
139
 
@@ -145,9 +145,9 @@ agoo_req_header_value(agooReq req, const char *key, int *vlen) {
145
145
  const char *hend = h + req->header.len;
146
146
  const char *value;
147
147
  int klen = (int)strlen(key);
148
-
148
+
149
149
  while (h < hend) {
150
- if (0 == strncmp(key, h, klen) && ':' == h[klen]) {
150
+ if (0 == strncasecmp(key, h, klen) && ':' == h[klen]) {
151
151
  h += klen + 1;
152
152
  for (; ' ' == *h; h++) {
153
153
  }
@@ -155,7 +155,7 @@ agoo_req_header_value(agooReq req, const char *key, int *vlen) {
155
155
  for (; '\r' != *h && '\0' != *h; h++) {
156
156
  }
157
157
  *vlen = (int)(h - value);
158
-
158
+
159
159
  return value;
160
160
  }
161
161
  for (; h < hend; h++) {
@@ -167,4 +167,3 @@ agoo_req_header_value(agooReq req, const char *key, int *vlen) {
167
167
  }
168
168
  return NULL;
169
169
  }
170
-
@@ -103,6 +103,7 @@ configure(agooErr err, int port, const char *root, VALUE options) {
103
103
  }
104
104
  agoo_server.thread_cnt = 0;
105
105
  the_rserver.worker_cnt = 1;
106
+ the_rserver.uses = NULL;
106
107
  atomic_init(&agoo_server.running, 0);
107
108
  agoo_server.listen_thread = 0;
108
109
  agoo_server.con_loops = NULL;
@@ -1014,6 +1015,14 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
1014
1015
  }
1015
1016
  }
1016
1017
  }
1018
+ if (NULL != the_rserver.uses) {
1019
+ RUse u;
1020
+
1021
+ for (u = the_rserver.uses; NULL != u; u = u->next) {
1022
+ u->argv[0] = handler;
1023
+ handler = rb_funcall2(u->clas, rb_intern("new"), u->argc, u->argv);
1024
+ }
1025
+ }
1017
1026
  if (NULL == (hook = rhook_create(meth, pat, handler, &agoo_server.eval_queue))) {
1018
1027
  rb_raise(rb_eStandardError, "out of memory.");
1019
1028
  } else {
@@ -1195,6 +1204,40 @@ rack_early_hints(VALUE self, VALUE on) {
1195
1204
  return on;
1196
1205
  }
1197
1206
 
1207
+ /* Document-method: use
1208
+ *
1209
+ * call-seq: use(middleware, *args)
1210
+ *
1211
+ * The use function must be called before the _handle_ functions. Any
1212
+ * invocations of _use_ apply only to handlers called after the call to use.
1213
+ */
1214
+ static VALUE
1215
+ use(int argc, VALUE *argv, VALUE self) {
1216
+ VALUE mc;
1217
+ RUse u;
1218
+
1219
+ if (argc < 1) { // at least the middleware class must be provided.
1220
+ rb_raise(rb_eArgError, "no middleware class provided");
1221
+ }
1222
+ mc = argv[0];
1223
+ if (T_CLASS != rb_type(mc)) {
1224
+ rb_raise(rb_eArgError, "the first argument to use must be a class");
1225
+ }
1226
+ if (NULL == (u = (RUse)AGOO_MALLOC(sizeof(struct _rUse)))) {
1227
+ rb_raise(rb_eNoMemError, "Failed to allocate memory for a middleware use.");
1228
+ }
1229
+ u->clas = mc;
1230
+ u->argc = argc;
1231
+ if (NULL == (u->argv = (VALUE*)AGOO_MALLOC(sizeof(VALUE) * u->argc))) {
1232
+ rb_raise(rb_eNoMemError, "Failed to allocate memory for a middleware use.");
1233
+ }
1234
+ memcpy(u->argv, argv, argc * sizeof(VALUE));
1235
+ u->next = the_rserver.uses;
1236
+ the_rserver.uses = u;
1237
+
1238
+ return Qnil;
1239
+ }
1240
+
1198
1241
  /* Document-class: Agoo::Server
1199
1242
  *
1200
1243
  * An HTTP server that support the rack API as well as some other optimized
@@ -1214,6 +1257,7 @@ server_init(VALUE mod) {
1214
1257
  rb_define_module_function(server_mod, "path_group", path_group, 2);
1215
1258
  rb_define_module_function(server_mod, "header_rule", header_rule, 4);
1216
1259
  rb_define_module_function(server_mod, "domain", domain, 2);
1260
+ rb_define_module_function(server_mod, "use", use, -1);
1217
1261
 
1218
1262
  rb_define_module_function(server_mod, "rack_early_hints", rack_early_hints, 1);
1219
1263
 
@@ -7,10 +7,18 @@
7
7
 
8
8
  #define MAX_WORKERS 32
9
9
 
10
+ typedef struct _rUse {
11
+ struct _rUse *next;
12
+ VALUE clas;
13
+ VALUE *argv;
14
+ int argc;
15
+ } *RUse;
16
+
10
17
  typedef struct _rServer {
11
18
  int worker_cnt;
12
19
  int worker_pids[MAX_WORKERS];
13
20
  VALUE *eval_threads; // Qnil terminated
21
+ RUse uses;
14
22
  } *RServer;
15
23
 
16
24
  extern struct _rServer the_rserver;
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Agoo
3
3
  # Agoo version.
4
- VERSION = '2.12.3'
4
+ VERSION = '2.13.0'
5
5
  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.12.3
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-28 00:00:00.000000000 Z
11
+ date: 2020-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj