agoo 2.15.8 → 2.15.10
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 +11 -0
- data/ext/agoo/con.c +19 -9
- data/ext/agoo/con.h +2 -0
- data/ext/agoo/req.c +7 -0
- data/ext/agoo/req.h +2 -0
- data/ext/agoo/request.c +29 -0
- data/ext/agoo/rserver.c +25 -0
- data/ext/agoo/rserver.h +1 -0
- data/ext/agoo/server.c +2 -2
- data/lib/agoo/version.rb +1 -1
- data/lib/agoo.rb +1 -0
- data/lib/rack/handler/agoo.rb +8 -2
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99f743f7259396ec783c42850172f11c99e3bfd067b65a10a1cfde0c44feda19
|
4
|
+
data.tar.gz: 314f7709e216fe0afc3190ab05a808b114b5766503e6fb0d82e8f65a77f140e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b85b630147884b41eb1eeda65b2278bbc491375ab193ec93c2989c2fe49aea4edec540353ff3cf4d3d63b383178f3949132e0f63e08d2bc220855d75efaaae9
|
7
|
+
data.tar.gz: eb537b2c220f3e6eceaf2a3c82de5dee1e883c5e321c5199c42cb22601a60a927212b49e885fa678a08343e7c6bc08fa67153518f78453b7149a7575e8d4b830
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
All changes to the Agoo gem are documented here. Releases follow semantic versioning.
|
4
4
|
|
5
|
+
## [2.15.10] - 2024-04-14
|
6
|
+
|
7
|
+
### Added
|
8
|
+
- Added metadata element to the gemspec file.
|
9
|
+
|
10
|
+
## [2.15.9] - 2024-02-26
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- Updated to support the most recent version of rack.
|
15
|
+
|
5
16
|
## [2.15.8] - 2023-10-07
|
6
17
|
|
7
18
|
### Fixed
|
data/ext/agoo/con.c
CHANGED
@@ -26,9 +26,10 @@
|
|
26
26
|
#include "upgraded.h"
|
27
27
|
#include "websocket.h"
|
28
28
|
|
29
|
-
#define CON_TIMEOUT 10.0
|
30
29
|
#define INITIAL_POLL_SIZE 1024
|
31
30
|
|
31
|
+
double con_timeout = 30.0;
|
32
|
+
|
32
33
|
typedef enum {
|
33
34
|
HEAD_AGAIN = 'A',
|
34
35
|
HEAD_ERR = 'E',
|
@@ -81,7 +82,7 @@ agoo_con_create(agooErr err, int sock, uint64_t id, agooBind b) {
|
|
81
82
|
}
|
82
83
|
c->sock = sock;
|
83
84
|
c->id = id;
|
84
|
-
c->timeout = dtime() +
|
85
|
+
c->timeout = dtime() + con_timeout;
|
85
86
|
c->bind = b;
|
86
87
|
c->loop = NULL;
|
87
88
|
pthread_mutex_init(&c->res_lock, 0);
|
@@ -289,6 +290,8 @@ con_header_read(agooCon c, size_t *mlenp) {
|
|
289
290
|
char *query = NULL;
|
290
291
|
char *qend;
|
291
292
|
char *b;
|
293
|
+
char *proto;
|
294
|
+
char *pend;
|
292
295
|
size_t clen = 0;
|
293
296
|
long mlen;
|
294
297
|
agooHook hook = NULL;
|
@@ -395,7 +398,12 @@ con_header_read(agooCon c, size_t *mlenp) {
|
|
395
398
|
}
|
396
399
|
mlen = hend - c->buf + 4 + clen;
|
397
400
|
*mlenp = mlen;
|
398
|
-
|
401
|
+
proto = qend;
|
402
|
+
for (; ' ' == *proto; proto++) {
|
403
|
+
}
|
404
|
+
pend = proto;
|
405
|
+
for (; '\r' != *pend; pend++) {
|
406
|
+
}
|
399
407
|
if (AGOO_GET == method) {
|
400
408
|
char root_buf[20148];
|
401
409
|
const char *root = NULL;
|
@@ -461,6 +469,8 @@ con_header_read(agooCon c, size_t *mlenp) {
|
|
461
469
|
c->req->query.start = c->req->msg + (query - c->buf);
|
462
470
|
c->req->query.len = (int)(qend - query);
|
463
471
|
c->req->query.start[c->req->query.len] = '\0';
|
472
|
+
c->req->protocol.start = proto;
|
473
|
+
c->req->protocol.len = (int)(pend - proto);
|
464
474
|
c->req->body.start = c->req->msg + (hend - c->buf + 4);
|
465
475
|
c->req->body.len = (unsigned int)clen;
|
466
476
|
b = strstr(b, "\r\n");
|
@@ -555,7 +565,7 @@ agoo_con_http_read(agooCon c) {
|
|
555
565
|
cnt = recv(c->sock, c->buf + c->bcnt, sizeof(c->buf) - c->bcnt - 1, 0);
|
556
566
|
}
|
557
567
|
}
|
558
|
-
c->timeout = dtime() +
|
568
|
+
c->timeout = dtime() + con_timeout;
|
559
569
|
if (0 >= cnt) {
|
560
570
|
// If nothing read then no need to complain. Just close.
|
561
571
|
if (0 < c->bcnt) {
|
@@ -658,7 +668,7 @@ agoo_con_http_write(agooCon c) {
|
|
658
668
|
if (NULL == message) {
|
659
669
|
return true;
|
660
670
|
}
|
661
|
-
c->timeout = dtime() +
|
671
|
+
c->timeout = dtime() + con_timeout;
|
662
672
|
if (0 == c->wcnt) {
|
663
673
|
if (agoo_resp_cat.on) {
|
664
674
|
char buf[4096];
|
@@ -736,7 +746,7 @@ con_ws_read(agooCon c) {
|
|
736
746
|
} else {
|
737
747
|
cnt = recv(c->sock, c->buf + c->bcnt, sizeof(c->buf) - c->bcnt - 1, 0);
|
738
748
|
}
|
739
|
-
c->timeout = dtime() +
|
749
|
+
c->timeout = dtime() + con_timeout;
|
740
750
|
if (0 >= cnt) {
|
741
751
|
// If nothing read then no need to complain. Just close.
|
742
752
|
if (0 < c->bcnt) {
|
@@ -883,7 +893,7 @@ con_ws_write(agooCon c) {
|
|
883
893
|
}
|
884
894
|
return true;
|
885
895
|
}
|
886
|
-
c->timeout = dtime() +
|
896
|
+
c->timeout = dtime() + con_timeout;
|
887
897
|
if (0 == c->wcnt) {
|
888
898
|
agooText t;
|
889
899
|
|
@@ -943,7 +953,7 @@ con_sse_write(agooCon c) {
|
|
943
953
|
|
944
954
|
return false;
|
945
955
|
}
|
946
|
-
c->timeout = dtime() +
|
956
|
+
c->timeout = dtime() + con_timeout *2;
|
947
957
|
if (0 == c->wcnt) {
|
948
958
|
agooText t;
|
949
959
|
|
@@ -1177,7 +1187,7 @@ con_ready_check(void *ctx, double now) {
|
|
1177
1187
|
return true;
|
1178
1188
|
}
|
1179
1189
|
} else if (AGOO_CON_WS == c->bind->kind || AGOO_CON_SSE == c->bind->kind) {
|
1180
|
-
c->timeout = dtime() +
|
1190
|
+
c->timeout = dtime() + con_timeout;
|
1181
1191
|
if (AGOO_CON_WS == c->bind->kind) {
|
1182
1192
|
agoo_ws_ping(c);
|
1183
1193
|
}
|
data/ext/agoo/con.h
CHANGED
data/ext/agoo/req.c
CHANGED
@@ -71,6 +71,13 @@ agoo_req_port(agooReq r) {
|
|
71
71
|
return (int)strtol(colon + 1, NULL, 10);
|
72
72
|
}
|
73
73
|
|
74
|
+
const char*
|
75
|
+
agoo_req_protocol(agooReq r, int *lenp) {
|
76
|
+
*lenp = r->protocol.len;
|
77
|
+
|
78
|
+
return r->protocol.start;
|
79
|
+
}
|
80
|
+
|
74
81
|
const char*
|
75
82
|
agoo_req_query_value(agooReq r, const char *key, int klen, int *vlenp) {
|
76
83
|
const char *value;
|
data/ext/agoo/req.h
CHANGED
@@ -31,6 +31,7 @@ typedef struct _agooReq {
|
|
31
31
|
struct _agooUpgraded *up;
|
32
32
|
struct _agooStr path;
|
33
33
|
struct _agooStr query;
|
34
|
+
struct _agooStr protocol;
|
34
35
|
struct _agooStr header;
|
35
36
|
struct _agooStr body;
|
36
37
|
char remote[INET6_ADDRSTRLEN];
|
@@ -43,6 +44,7 @@ typedef struct _agooReq {
|
|
43
44
|
extern agooReq agoo_req_create(size_t mlen);
|
44
45
|
extern void agoo_req_destroy(agooReq req);
|
45
46
|
extern const char* agoo_req_host(agooReq r, int *lenp);
|
47
|
+
extern const char* agoo_req_protocol(agooReq r, int *lenp);
|
46
48
|
extern int agoo_req_port(agooReq r);
|
47
49
|
extern const char* agoo_req_query_value(agooReq r, const char *key, int klen, int *vlenp);
|
48
50
|
extern int agoo_req_query_decode(char *s, int len);
|
data/ext/agoo/request.c
CHANGED
@@ -48,6 +48,7 @@ static VALUE request_method_val = Qundef;
|
|
48
48
|
static VALUE script_name_val = Qundef;
|
49
49
|
static VALUE server_name_val = Qundef;
|
50
50
|
static VALUE server_port_val = Qundef;
|
51
|
+
static VALUE server_protocol_val = Qundef;
|
51
52
|
static VALUE slash_val = Qundef;
|
52
53
|
|
53
54
|
static VALUE sse_sym;
|
@@ -218,6 +219,31 @@ server_name(VALUE self) {
|
|
218
219
|
return req_server_name((agooReq)DATA_PTR(self));
|
219
220
|
}
|
220
221
|
|
222
|
+
static VALUE
|
223
|
+
req_server_protocol(agooReq r) {
|
224
|
+
int len;
|
225
|
+
const char *protocol;
|
226
|
+
|
227
|
+
if (NULL == r) {
|
228
|
+
rb_raise(rb_eArgError, "Request is no longer valid.");
|
229
|
+
}
|
230
|
+
if (NULL == (protocol = agoo_req_protocol(r, &len))) {
|
231
|
+
return rb_str_new2("HTTP/1.1");
|
232
|
+
}
|
233
|
+
return rb_str_new(protocol, len);
|
234
|
+
}
|
235
|
+
|
236
|
+
/* Document-method: server_protocol
|
237
|
+
*
|
238
|
+
* call-seq: server_protocol()
|
239
|
+
*
|
240
|
+
* Returns the server or host protocol.
|
241
|
+
*/
|
242
|
+
static VALUE
|
243
|
+
server_protocol(VALUE self) {
|
244
|
+
return req_server_protocol((agooReq)DATA_PTR(self));
|
245
|
+
}
|
246
|
+
|
221
247
|
static VALUE
|
222
248
|
req_server_port(agooReq r) {
|
223
249
|
int len;
|
@@ -594,6 +620,7 @@ request_env(agooReq req, VALUE self) {
|
|
594
620
|
rb_hash_aset(env, remote_addr_val, req_remote_addr(req));
|
595
621
|
rb_hash_aset(env, server_port_val, req_server_port(req));
|
596
622
|
rb_hash_aset(env, server_name_val, req_server_name(req));
|
623
|
+
rb_hash_aset(env, server_protocol_val, req_server_protocol(req));
|
597
624
|
fill_headers(req, env);
|
598
625
|
rb_hash_aset(env, rack_version_val, rack_version_val_val);
|
599
626
|
rb_hash_aset(env, rack_url_scheme_val, req_rack_url_scheme(req));
|
@@ -739,6 +766,7 @@ request_init(VALUE mod) {
|
|
739
766
|
rb_define_method(req_class, "query_string", query_string, 0);
|
740
767
|
rb_define_method(req_class, "server_name", server_name, 0);
|
741
768
|
rb_define_method(req_class, "server_port", server_port, 0);
|
769
|
+
rb_define_method(req_class, "server_protocol", server_protocol, 0);
|
742
770
|
rb_define_method(req_class, "remote_addr", remote_addr, 0);
|
743
771
|
rb_define_method(req_class, "rack_version", rack_version, 0);
|
744
772
|
rb_define_method(req_class, "rack_url_scheme", rack_url_scheme, 0);
|
@@ -796,6 +824,7 @@ request_init(VALUE mod) {
|
|
796
824
|
script_name_val = rb_str_new_cstr("SCRIPT_NAME"); rb_gc_register_address(&script_name_val);
|
797
825
|
server_name_val = rb_str_new_cstr("SERVER_NAME"); rb_gc_register_address(&server_name_val);
|
798
826
|
server_port_val = rb_str_new_cstr("SERVER_PORT"); rb_gc_register_address(&server_port_val);
|
827
|
+
server_protocol_val = rb_str_new_cstr("SERVER_PROTOCOL"); rb_gc_register_address(&server_protocol_val);
|
799
828
|
slash_val = rb_str_new_cstr("/"); rb_gc_register_address(&slash_val);
|
800
829
|
|
801
830
|
sse_sym = ID2SYM(rb_intern("sse")); rb_gc_register_address(&sse_sym);
|
data/ext/agoo/rserver.c
CHANGED
@@ -104,6 +104,7 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
104
104
|
}
|
105
105
|
agoo_server.thread_cnt = 0;
|
106
106
|
the_rserver.worker_cnt = 1;
|
107
|
+
the_rserver.forker = Qnil;
|
107
108
|
the_rserver.uses = NULL;
|
108
109
|
atomic_init(&agoo_server.running, 0);
|
109
110
|
agoo_server.listen_thread = 0;
|
@@ -132,6 +133,8 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
132
133
|
rb_raise(rb_eArgError, "thread_count must be between 1 and %d.", MAX_WORKERS);
|
133
134
|
}
|
134
135
|
}
|
136
|
+
the_rserver.forker = rb_hash_lookup(options, ID2SYM(rb_intern("fork_wrap")));
|
137
|
+
|
135
138
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("poll_timeout"))))) {
|
136
139
|
double timeout = rb_num2dbl(v);
|
137
140
|
|
@@ -141,6 +144,15 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
141
144
|
rb_raise(rb_eArgError, "poll_timeout must be between 0.0001 and 1.0.");
|
142
145
|
}
|
143
146
|
}
|
147
|
+
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("connection_timeout"))))) {
|
148
|
+
double timeout = rb_num2dbl(v);
|
149
|
+
|
150
|
+
if (0.1 <= timeout) {
|
151
|
+
con_timeout = timeout;
|
152
|
+
} else {
|
153
|
+
rb_raise(rb_eArgError, "connection_timeout must be greater than 0.1 seconds.");
|
154
|
+
}
|
155
|
+
}
|
144
156
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("max_push_pending"))))) {
|
145
157
|
int mpp = FIX2INT(v);
|
146
158
|
|
@@ -295,6 +307,8 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
295
307
|
*
|
296
308
|
* - *:poll_timeout* [_Float_] timeout seconds when polling. Default is 0.1. Lower gives faster response times but uses more CPU.
|
297
309
|
*
|
310
|
+
* - *:connection_timeout* [_Float_] timeout seconds for connections. Default is 30.
|
311
|
+
*
|
298
312
|
* - *:bind* [_String_|_Array_] a binding or array of binds. Examples are: "http ://127.0.0.1:6464", "unix:///tmp/agoo.socket", "http ://[::1]:6464, or to not restrict the address "http ://:6464".
|
299
313
|
*
|
300
314
|
* - *:graphql* [_String_] path to GraphQL endpoint if support for GraphQL is desired.
|
@@ -805,6 +819,7 @@ rserver_start(VALUE self) {
|
|
805
819
|
struct _agooErr err = AGOO_ERR_INIT;
|
806
820
|
VALUE agoo = rb_const_get_at(rb_cObject, rb_intern("Agoo"));
|
807
821
|
VALUE v = rb_const_get_at(agoo, rb_intern("VERSION"));
|
822
|
+
ID after = rb_intern("after");
|
808
823
|
|
809
824
|
*the_rserver.worker_pids = getpid();
|
810
825
|
|
@@ -819,6 +834,13 @@ rserver_start(VALUE self) {
|
|
819
834
|
if (AGOO_ERR_OK != setup_listen(&err)) {
|
820
835
|
rb_raise(rb_eIOError, "%s", err.msg);
|
821
836
|
}
|
837
|
+
if (1 < the_rserver.worker_cnt && the_rserver.forker != Qnil) {
|
838
|
+
ID before = rb_intern("before");
|
839
|
+
|
840
|
+
if (rb_respond_to(the_rserver.forker, before)) {
|
841
|
+
rb_funcall(the_rserver.forker, before, 0);
|
842
|
+
}
|
843
|
+
}
|
822
844
|
for (i = 1; i < the_rserver.worker_cnt; i++) {
|
823
845
|
VALUE rpid = rb_funcall(rb_cObject, rb_intern("fork"), 0);
|
824
846
|
|
@@ -839,6 +861,9 @@ rserver_start(VALUE self) {
|
|
839
861
|
the_rserver.worker_pids[i] = pid;
|
840
862
|
}
|
841
863
|
}
|
864
|
+
if (1 < the_rserver.worker_cnt && the_rserver.forker != Qnil && rb_respond_to(the_rserver.forker, after)) {
|
865
|
+
rb_funcall(the_rserver.forker, after, 0);
|
866
|
+
}
|
842
867
|
if (AGOO_ERR_OK != agoo_server_start(&err, "Agoo", StringValuePtr(v))) {
|
843
868
|
rb_raise(rb_eStandardError, "%s", err.msg);
|
844
869
|
}
|
data/ext/agoo/rserver.h
CHANGED
data/ext/agoo/server.c
CHANGED
@@ -149,7 +149,7 @@ listen_loop(void *x) {
|
|
149
149
|
cnt--;
|
150
150
|
agoo_err_clear(&err);
|
151
151
|
} else {
|
152
|
-
int con_cnt;
|
152
|
+
// int con_cnt;
|
153
153
|
#ifdef OSX_OS
|
154
154
|
setsockopt(client_sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
155
155
|
#endif
|
@@ -163,8 +163,8 @@ listen_loop(void *x) {
|
|
163
163
|
agoo_log_cat(&agoo_con_cat, "Server with pid %d accepted connection %llu on %s [%d] from %s",
|
164
164
|
getpid(), (unsigned long long)cnt, b->id, con->sock, con->remote);
|
165
165
|
|
166
|
-
con_cnt = atomic_fetch_add(&agoo_server.con_cnt, 1);
|
167
166
|
/* TBD
|
167
|
+
con_cnt = atomic_fetch_add(&agoo_server.con_cnt, 1);
|
168
168
|
if (agoo_server.loop_max > agoo_server.loop_cnt && agoo_server.loop_cnt * LOOP_UP < con_cnt) {
|
169
169
|
add_con_loop();
|
170
170
|
}
|
data/lib/agoo/version.rb
CHANGED
data/lib/agoo.rb
CHANGED
data/lib/rack/handler/agoo.rb
CHANGED
@@ -177,8 +177,14 @@ using the -O NAME[=VALUE] option of rackup. Note that if binds are provided the
|
|
177
177
|
end
|
178
178
|
|
179
179
|
begin
|
180
|
-
::
|
181
|
-
::
|
180
|
+
::Rackup::Handler.register('agoo', Rack::Handler::Agoo)
|
181
|
+
::Rackup::Handler.register('Agoo', Rack::Handler::Agoo)
|
182
182
|
rescue Exception
|
183
|
+
begin
|
184
|
+
# try the old style
|
185
|
+
::Rack::Handler.register('agoo', 'Rack::Handler::Agoo')
|
186
|
+
::Rack::Handler.register('Agoo', 'Rack::Handler::Agoo')
|
187
|
+
rescue Exception
|
188
|
+
end
|
183
189
|
# Rack or Rack::Handler.register has not been required.
|
184
190
|
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.15.
|
4
|
+
version: 2.15.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -163,7 +163,10 @@ files:
|
|
163
163
|
homepage: https://github.com/ohler55/agoo
|
164
164
|
licenses:
|
165
165
|
- MIT
|
166
|
-
metadata:
|
166
|
+
metadata:
|
167
|
+
changelog_uri: https://github.com/ohler55/agoo/CHANGELOG.md
|
168
|
+
source_code_uri: https://github.com/ohler55/agoo
|
169
|
+
homepage: https://github.com/ohler55/agoo
|
167
170
|
post_install_message:
|
168
171
|
rdoc_options:
|
169
172
|
- "-t"
|