agoo 2.12.3 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
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