agoo 2.2.2 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/ext/agoo/agoo.c +2 -2
- data/ext/agoo/con.c +65 -62
- data/ext/agoo/debug.c +3 -2
- data/ext/agoo/extconf.rb +4 -2
- data/ext/agoo/hook.c +15 -74
- data/ext/agoo/hook.h +20 -12
- data/ext/agoo/log.c +30 -466
- data/ext/agoo/log.h +6 -5
- data/ext/agoo/method.h +25 -0
- data/ext/agoo/request.c +27 -23
- data/ext/agoo/request.h +1 -0
- data/ext/agoo/response.c +0 -1
- data/ext/agoo/rhook.c +82 -0
- data/ext/agoo/rhook.h +13 -0
- data/ext/agoo/rlog.c +469 -0
- data/ext/agoo/rlog.h +11 -0
- data/ext/agoo/seg.h +11 -0
- data/ext/agoo/server.c +22 -8
- data/ext/agoo/server.h +1 -1
- data/ext/agoo/types.h +0 -19
- data/ext/agoo/upgraded.c +13 -1
- data/ext/agoo/upgraded.h +2 -1
- data/ext/agoo/websocket.c +3 -3
- data/lib/agoo/version.rb +1 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68f159d050def385814b8fecb4b3d28cd638bedaa658543881a74f2587957260
|
4
|
+
data.tar.gz: 72a2429c4eb44db0ddf7a033d7fde7a7fcdc112e032b9102340d7fb74a92f68b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc963d7748c0406fa4e82133af064ec1c97607e3cc6c1695939fc5869b35d83f134b7ae440386f06531e9b65d27fcdb9bbc7db9122bdc5fdb1987f5f049703b3
|
7
|
+
data.tar.gz: fe94670810539c14abba9cdaba57843e1cbd0c8425b72d18d9ac036ee83fc95d513263cac5b2e0156dd94a8a908d70ea26e1fadd50334b7faa7bf5b94c88e38d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
### 2.3.0 - 2018-06-29
|
4
|
+
|
5
|
+
- Added an `env` method to the upgrade (Websocket and SSE) client.
|
6
|
+
|
7
|
+
- Fixed Websocket bug where a pong caused a hang on the socket.
|
8
|
+
|
3
9
|
### 2.2.2 - 2018-06-05
|
4
10
|
|
5
11
|
- Fixed `bin/agoo` which had become out of date.
|
data/ext/agoo/agoo.c
CHANGED
@@ -7,11 +7,11 @@
|
|
7
7
|
|
8
8
|
#include "debug.h"
|
9
9
|
#include "error_stream.h"
|
10
|
-
#include "log.h"
|
11
10
|
#include "pub.h"
|
12
11
|
#include "rack_logger.h"
|
13
12
|
#include "request.h"
|
14
13
|
#include "response.h"
|
14
|
+
#include "rlog.h"
|
15
15
|
#include "server.h"
|
16
16
|
#include "upgraded.h"
|
17
17
|
|
@@ -89,7 +89,7 @@ void
|
|
89
89
|
Init_agoo() {
|
90
90
|
VALUE mod = rb_define_module("Agoo");
|
91
91
|
|
92
|
-
|
92
|
+
rlog_init(mod);
|
93
93
|
error_stream_init(mod);
|
94
94
|
rack_logger_init(mod);
|
95
95
|
request_init(mod);
|
data/ext/agoo/con.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
3
|
#include <ctype.h>
|
4
|
+
#include <netdb.h>
|
5
|
+
#include <stdio.h>
|
4
6
|
#include <string.h>
|
5
7
|
|
6
8
|
#include "con.h"
|
@@ -10,6 +12,7 @@
|
|
10
12
|
#include "http.h"
|
11
13
|
#include "pub.h"
|
12
14
|
#include "res.h"
|
15
|
+
#include "seg.h"
|
13
16
|
#include "server.h"
|
14
17
|
#include "sse.h"
|
15
18
|
#include "subject.h"
|
@@ -95,7 +98,7 @@ bad_request(Con c, int status, int line) {
|
|
95
98
|
const char *msg = http_code_message(status);
|
96
99
|
|
97
100
|
if (NULL == (res = res_create(c))) {
|
98
|
-
log_cat(&error_cat, "memory allocation of response failed on connection %llu @ %d.", c->id, line);
|
101
|
+
log_cat(&error_cat, "memory allocation of response failed on connection %llu @ %d.", (unsigned long long)c->id, line);
|
99
102
|
} else {
|
100
103
|
char buf[256];
|
101
104
|
int cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n", status, msg);
|
@@ -158,8 +161,7 @@ static long
|
|
158
161
|
con_header_read(Con c) {
|
159
162
|
char *hend = strstr(c->buf, "\r\n\r\n");
|
160
163
|
Method method;
|
161
|
-
|
162
|
-
char *pend;
|
164
|
+
struct _Seg path;
|
163
165
|
char *query = NULL;
|
164
166
|
char *qend;
|
165
167
|
char *b;
|
@@ -177,7 +179,7 @@ con_header_read(Con c) {
|
|
177
179
|
}
|
178
180
|
if (req_cat.on) {
|
179
181
|
*hend = '\0';
|
180
|
-
log_cat(&req_cat, "%llu: %s", c->id, c->buf);
|
182
|
+
log_cat(&req_cat, "%llu: %s", (unsigned long long)c->id, c->buf);
|
181
183
|
*hend = '\r';
|
182
184
|
}
|
183
185
|
for (b = c->buf; ' ' != *b; b++) {
|
@@ -245,11 +247,11 @@ con_header_read(Con c) {
|
|
245
247
|
return bad_request(c, 400, __LINE__);
|
246
248
|
}
|
247
249
|
}
|
248
|
-
path = b;
|
250
|
+
path.start = b;
|
249
251
|
for (; ' ' != *b; b++) {
|
250
252
|
switch (*b) {
|
251
253
|
case '?':
|
252
|
-
|
254
|
+
path.end = b;
|
253
255
|
query = b + 1;
|
254
256
|
break;
|
255
257
|
case '\0':
|
@@ -259,7 +261,7 @@ con_header_read(Con c) {
|
|
259
261
|
}
|
260
262
|
}
|
261
263
|
if (NULL == query) {
|
262
|
-
|
264
|
+
path.end = b;
|
263
265
|
query = b;
|
264
266
|
qend = b;
|
265
267
|
} else {
|
@@ -267,20 +269,20 @@ con_header_read(Con c) {
|
|
267
269
|
}
|
268
270
|
mlen = hend - c->buf + 4 + clen;
|
269
271
|
if (GET == method &&
|
270
|
-
NULL != (p = group_get(&err, &the_server.pages, path, (int)(
|
272
|
+
NULL != (p = group_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
|
271
273
|
if (page_response(c, p, hend)) {
|
272
274
|
return bad_request(c, 500, __LINE__);
|
273
275
|
}
|
274
276
|
return -mlen;
|
275
277
|
}
|
276
278
|
if (GET == method && the_server.root_first &&
|
277
|
-
NULL != (p = page_get(&err, &the_server.pages, path, (int)(
|
279
|
+
NULL != (p = page_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
|
278
280
|
if (page_response(c, p, hend)) {
|
279
281
|
return bad_request(c, 500, __LINE__);
|
280
282
|
}
|
281
283
|
return -mlen;
|
282
284
|
}
|
283
|
-
if (NULL == (hook = hook_find(the_server.hooks, method, path
|
285
|
+
if (NULL == (hook = hook_find(the_server.hooks, method, &path))) {
|
284
286
|
if (GET == method) {
|
285
287
|
if (the_server.root_first) { // already checked
|
286
288
|
if (NULL != the_server.hook404) {
|
@@ -291,7 +293,7 @@ con_header_read(Con c) {
|
|
291
293
|
}
|
292
294
|
return bad_request(c, 404, __LINE__);
|
293
295
|
}
|
294
|
-
if (NULL == (p = page_get(&err, &the_server.pages, path, (int)(
|
296
|
+
if (NULL == (p = page_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
|
295
297
|
if (NULL != the_server.hook404) {
|
296
298
|
// There would be too many parameters to pass to a
|
297
299
|
// separate function so just goto the hook processing.
|
@@ -323,8 +325,8 @@ HOOKED:
|
|
323
325
|
c->req->method = method;
|
324
326
|
c->req->upgrade = UP_NONE;
|
325
327
|
c->req->up = NULL;
|
326
|
-
c->req->path.start = c->req->msg + (path - c->buf);
|
327
|
-
c->req->path.len = (int)(
|
328
|
+
c->req->path.start = c->req->msg + (path.start - c->buf);
|
329
|
+
c->req->path.len = (int)(path.end - path.start);
|
328
330
|
c->req->query.start = c->req->msg + (query - c->buf);
|
329
331
|
c->req->query.len = (int)(qend - query);
|
330
332
|
c->req->body.start = c->req->msg + (hend - c->buf + 4);
|
@@ -334,7 +336,7 @@ HOOKED:
|
|
334
336
|
c->req->header.len = (unsigned int)(hend - b - 2);
|
335
337
|
c->req->res = NULL;
|
336
338
|
if (NULL != hook) {
|
337
|
-
c->req->handler = hook->handler;
|
339
|
+
c->req->handler = (VALUE)hook->handler;
|
338
340
|
c->req->handler_type = hook->type;
|
339
341
|
} else {
|
340
342
|
c->req->handler = Qnil;
|
@@ -388,7 +390,7 @@ con_http_read(Con c) {
|
|
388
390
|
// If nothing read then no need to complain. Just close.
|
389
391
|
if (0 < c->bcnt) {
|
390
392
|
if (0 == cnt) {
|
391
|
-
log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", c->id);
|
393
|
+
log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", (unsigned long long)c->id);
|
392
394
|
} else {
|
393
395
|
log_cat(&warn_cat, "Failed to read request. %s.", strerror(errno));
|
394
396
|
}
|
@@ -426,11 +428,11 @@ con_http_read(Con c) {
|
|
426
428
|
long mlen;
|
427
429
|
|
428
430
|
if (debug_cat.on && NULL != c->req && NULL != c->req->body.start) {
|
429
|
-
log_cat(&debug_cat, "request on %llu: %s", c->id, c->req->body.start);
|
431
|
+
log_cat(&debug_cat, "request on %llu: %s", (unsigned long long)c->id, c->req->body.start);
|
430
432
|
}
|
431
433
|
if (NULL == (res = res_create(c))) {
|
432
434
|
c->req = NULL;
|
433
|
-
log_cat(&error_cat, "memory allocation of response failed on connection %llu.", c->id);
|
435
|
+
log_cat(&error_cat, "memory allocation of response failed on connection %llu.", (unsigned long long)c->id);
|
434
436
|
return bad_request(c, 500, __LINE__);
|
435
437
|
} else {
|
436
438
|
if (NULL == c->res_tail) {
|
@@ -483,7 +485,7 @@ con_ws_read(Con c) {
|
|
483
485
|
// If nothing read then no need to complain. Just close.
|
484
486
|
if (0 < c->bcnt) {
|
485
487
|
if (0 == cnt) {
|
486
|
-
log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", c->id);
|
488
|
+
log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", (unsigned long long)c->id);
|
487
489
|
} else {
|
488
490
|
log_cat(&warn_cat, "Failed to read WebSocket message. %s.", strerror(errno));
|
489
491
|
}
|
@@ -511,14 +513,20 @@ con_ws_read(Con c) {
|
|
511
513
|
case WS_OP_CLOSE:
|
512
514
|
return true;
|
513
515
|
case WS_OP_PING:
|
514
|
-
|
516
|
+
if (mlen == (long)c->bcnt) {
|
517
|
+
ws_pong(c);
|
518
|
+
c->bcnt = 0;
|
519
|
+
}
|
515
520
|
break;
|
516
521
|
case WS_OP_PONG:
|
517
522
|
// ignore
|
523
|
+
if (mlen == (long)c->bcnt) {
|
524
|
+
c->bcnt = 0;
|
525
|
+
}
|
518
526
|
break;
|
519
527
|
case WS_OP_CONT:
|
520
528
|
default:
|
521
|
-
log_cat(&error_cat, "WebSocket op 0x%02x not supported on %llu.", op, c->id);
|
529
|
+
log_cat(&error_cat, "WebSocket op 0x%02x not supported on %llu.", op, (unsigned long long)c->id);
|
522
530
|
return true;
|
523
531
|
}
|
524
532
|
}
|
@@ -528,9 +536,9 @@ con_ws_read(Con c) {
|
|
528
536
|
if (mlen <= (long)c->bcnt) {
|
529
537
|
if (debug_cat.on) {
|
530
538
|
if (ON_MSG == c->req->method) {
|
531
|
-
log_cat(&debug_cat, "WebSocket message on %llu: %s", c->id, c->req->msg);
|
539
|
+
log_cat(&debug_cat, "WebSocket message on %llu: %s", (unsigned long long)c->id, c->req->msg);
|
532
540
|
} else {
|
533
|
-
log_cat(&debug_cat, "WebSocket binary message on %llu", c->id);
|
541
|
+
log_cat(&debug_cat, "WebSocket binary message on %llu", (unsigned long long)c->id);
|
534
542
|
}
|
535
543
|
}
|
536
544
|
}
|
@@ -587,17 +595,17 @@ con_http_write(Con c) {
|
|
587
595
|
}
|
588
596
|
memcpy(buf, message->text, hend - message->text);
|
589
597
|
buf[hend - message->text] = '\0';
|
590
|
-
log_cat(&resp_cat, "%llu: %s", c->id, buf);
|
598
|
+
log_cat(&resp_cat, "%llu: %s", (unsigned long long)c->id, buf);
|
591
599
|
}
|
592
600
|
if (debug_cat.on) {
|
593
|
-
log_cat(&debug_cat, "response on %llu: %s", c->id, message->text);
|
601
|
+
log_cat(&debug_cat, "response on %llu: %s", (unsigned long long)c->id, message->text);
|
594
602
|
}
|
595
603
|
}
|
596
604
|
if (0 > (cnt = send(c->sock, message->text + c->wcnt, message->len - c->wcnt, 0))) {
|
597
605
|
if (EAGAIN == errno) {
|
598
606
|
return false;
|
599
607
|
}
|
600
|
-
log_cat(&error_cat, "Socket error @ %llu.", c->id);
|
608
|
+
log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
601
609
|
|
602
610
|
return true;
|
603
611
|
}
|
@@ -633,7 +641,7 @@ con_ws_write(Con c) {
|
|
633
641
|
if (EAGAIN == errno) {
|
634
642
|
return false;
|
635
643
|
}
|
636
|
-
log_cat(&error_cat, "Socket error @ %llu.", c->id);
|
644
|
+
log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
637
645
|
ws_req_close(c);
|
638
646
|
res_destroy(res);
|
639
647
|
|
@@ -644,7 +652,7 @@ con_ws_write(Con c) {
|
|
644
652
|
if (EAGAIN == errno) {
|
645
653
|
return false;
|
646
654
|
}
|
647
|
-
log_cat(&error_cat, "Socket error @ %llu.", c->id);
|
655
|
+
log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
648
656
|
ws_req_close(c);
|
649
657
|
res_destroy(res);
|
650
658
|
|
@@ -671,9 +679,9 @@ con_ws_write(Con c) {
|
|
671
679
|
|
672
680
|
if (push_cat.on) {
|
673
681
|
if (message->bin) {
|
674
|
-
log_cat(&push_cat, "%llu binary", c->id);
|
682
|
+
log_cat(&push_cat, "%llu binary", (unsigned long long)c->id);
|
675
683
|
} else {
|
676
|
-
log_cat(&push_cat, "%llu: %s", c->id, message->text);
|
684
|
+
log_cat(&push_cat, "%llu: %s", (unsigned long long)c->id, message->text);
|
677
685
|
}
|
678
686
|
}
|
679
687
|
t = ws_expand(message);
|
@@ -686,7 +694,7 @@ con_ws_write(Con c) {
|
|
686
694
|
if (EAGAIN == errno) {
|
687
695
|
return false;
|
688
696
|
}
|
689
|
-
log_cat(&error_cat, "Socket error @ %llu.", c->id);
|
697
|
+
log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
690
698
|
ws_req_close(c);
|
691
699
|
|
692
700
|
return true;
|
@@ -695,7 +703,6 @@ con_ws_write(Con c) {
|
|
695
703
|
if (c->wcnt == message->len) { // finished
|
696
704
|
Res res = c->res_head;
|
697
705
|
bool done = res->close;
|
698
|
-
int pending;
|
699
706
|
|
700
707
|
c->res_head = res->next;
|
701
708
|
if (res == c->res_tail) {
|
@@ -703,18 +710,7 @@ con_ws_write(Con c) {
|
|
703
710
|
}
|
704
711
|
c->wcnt = 0;
|
705
712
|
res_destroy(res);
|
706
|
-
|
707
|
-
if (NULL != c->up && Qnil != c->up->handler && c->up->on_empty) {
|
708
|
-
Req req = request_create(0);
|
709
|
-
|
710
|
-
req->up = c->up;
|
711
|
-
req->method = ON_EMPTY;
|
712
|
-
req->handler_type = PUSH_HOOK;
|
713
|
-
req->handler = c->up->handler;
|
714
|
-
upgraded_ref(c->up);
|
715
|
-
queue_push(&the_server.eval_queue, (void*)req);
|
716
|
-
}
|
717
|
-
}
|
713
|
+
|
718
714
|
return done;
|
719
715
|
}
|
720
716
|
return false;
|
@@ -736,7 +732,7 @@ con_sse_write(Con c) {
|
|
736
732
|
Text t;
|
737
733
|
|
738
734
|
if (push_cat.on) {
|
739
|
-
log_cat(&push_cat, "%llu: %s", c->id, message->text);
|
735
|
+
log_cat(&push_cat, "%llu: %s", (unsigned long long)c->id, message->text);
|
740
736
|
}
|
741
737
|
t = sse_expand(message);
|
742
738
|
if (t != message) {
|
@@ -748,7 +744,7 @@ con_sse_write(Con c) {
|
|
748
744
|
if (EAGAIN == errno) {
|
749
745
|
return false;
|
750
746
|
}
|
751
|
-
log_cat(&error_cat, "Socket error @ %llu.", c->id);
|
747
|
+
log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
752
748
|
ws_req_close(c);
|
753
749
|
|
754
750
|
return true;
|
@@ -757,7 +753,6 @@ con_sse_write(Con c) {
|
|
757
753
|
if (c->wcnt == message->len) { // finished
|
758
754
|
Res res = c->res_head;
|
759
755
|
bool done = res->close;
|
760
|
-
int pending;
|
761
756
|
|
762
757
|
c->res_head = res->next;
|
763
758
|
if (res == c->res_tail) {
|
@@ -765,18 +760,7 @@ con_sse_write(Con c) {
|
|
765
760
|
}
|
766
761
|
c->wcnt = 0;
|
767
762
|
res_destroy(res);
|
768
|
-
|
769
|
-
if (NULL != c->up && Qnil != c->up->handler && c->up->on_empty) {
|
770
|
-
Req req = request_create(0);
|
771
|
-
|
772
|
-
req->up = c->up;
|
773
|
-
req->method = ON_EMPTY;
|
774
|
-
req->handler_type = PUSH_HOOK;
|
775
|
-
req->handler = c->up->handler;
|
776
|
-
upgraded_ref(c->up);
|
777
|
-
queue_push(&the_server.eval_queue, (void*)req);
|
778
|
-
}
|
779
|
-
}
|
763
|
+
|
780
764
|
return done;
|
781
765
|
}
|
782
766
|
return false;
|
@@ -816,7 +800,8 @@ static void
|
|
816
800
|
publish_pub(Pub pub) {
|
817
801
|
Upgraded up;
|
818
802
|
const char *sub = pub->subject->pattern;
|
819
|
-
|
803
|
+
int cnt = 0;
|
804
|
+
|
820
805
|
for (up = the_server.up_list; NULL != up; up = up->next) {
|
821
806
|
if (NULL != up->con && upgraded_match(up, sub)) {
|
822
807
|
Res res = res_create(up->con);
|
@@ -830,6 +815,7 @@ publish_pub(Pub pub) {
|
|
830
815
|
up->con->res_tail = res;
|
831
816
|
res->con_kind = CON_ANY;
|
832
817
|
res_set_message(res, text_dup(pub->msg));
|
818
|
+
cnt++;
|
833
819
|
}
|
834
820
|
}
|
835
821
|
}
|
@@ -852,6 +838,23 @@ static void
|
|
852
838
|
process_pub_con(Pub pub) {
|
853
839
|
Upgraded up = pub->up;
|
854
840
|
|
841
|
+
if (NULL != up) {
|
842
|
+
int pending;
|
843
|
+
|
844
|
+
// TBD Change pending to be based on length of con queue
|
845
|
+
if (1 == (pending = atomic_fetch_sub(&up->pending, 1))) {
|
846
|
+
if (NULL != up && Qnil != up->handler && up->on_empty) {
|
847
|
+
Req req = request_create(0);
|
848
|
+
|
849
|
+
req->up = up;
|
850
|
+
req->method = ON_EMPTY;
|
851
|
+
req->handler_type = PUSH_HOOK;
|
852
|
+
req->handler = up->handler;
|
853
|
+
upgraded_ref(up);
|
854
|
+
queue_push(&the_server.eval_queue, (void*)req);
|
855
|
+
}
|
856
|
+
}
|
857
|
+
}
|
855
858
|
switch (pub->kind) {
|
856
859
|
case PUB_CLOSE:
|
857
860
|
// An close after already closed is used to decrement the reference
|
@@ -1073,9 +1076,9 @@ con_loop(void *x) {
|
|
1073
1076
|
if (0 != (pp->revents & (POLLERR | POLLHUP | POLLNVAL))) {
|
1074
1077
|
if (0 < c->bcnt) {
|
1075
1078
|
if (0 != (pp->revents & (POLLHUP | POLLNVAL))) {
|
1076
|
-
log_cat(&error_cat, "Socket %llu closed.", c->id);
|
1079
|
+
log_cat(&error_cat, "Socket %llu closed.", (unsigned long long)c->id);
|
1077
1080
|
} else if (!c->closing) {
|
1078
|
-
log_cat(&error_cat, "Socket %llu error. %s", c->id, strerror(errno));
|
1081
|
+
log_cat(&error_cat, "Socket %llu error. %s", (unsigned long long)c->id, strerror(errno));
|
1079
1082
|
}
|
1080
1083
|
}
|
1081
1084
|
c->dead = true;
|
@@ -1113,7 +1116,7 @@ con_loop(void *x) {
|
|
1113
1116
|
prev->next = next;
|
1114
1117
|
}
|
1115
1118
|
ccnt--;
|
1116
|
-
log_cat(&con_cat, "Connection %llu closed.", c->id);
|
1119
|
+
log_cat(&con_cat, "Connection %llu closed.", (unsigned long long)c->id);
|
1117
1120
|
con_destroy(c);
|
1118
1121
|
}
|
1119
1122
|
}
|
data/ext/agoo/debug.c
CHANGED
data/ext/agoo/extconf.rb
CHANGED
@@ -5,8 +5,10 @@ extension_name = 'agoo'
|
|
5
5
|
dir_config(extension_name)
|
6
6
|
|
7
7
|
$CPPFLAGS += " -DPLATFORM_LINUX" if 'x86_64-linux' == RUBY_PLATFORM
|
8
|
-
|
9
|
-
#
|
8
|
+
|
9
|
+
# Adding the __attribute__ flag only works with gcc compilers and even then it
|
10
|
+
# does not work to check args with varargs s just remove the check.
|
11
|
+
CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
|
10
12
|
|
11
13
|
create_makefile(File.join(extension_name, extension_name))
|
12
14
|
|
data/ext/agoo/hook.c
CHANGED
@@ -6,52 +6,8 @@
|
|
6
6
|
#include "debug.h"
|
7
7
|
#include "hook.h"
|
8
8
|
|
9
|
-
static VALUE
|
10
|
-
resolve_classname(VALUE mod, const char *classname) {
|
11
|
-
VALUE clas;
|
12
|
-
ID ci = rb_intern(classname);
|
13
|
-
|
14
|
-
if (rb_const_defined_at(mod, ci)) {
|
15
|
-
clas = rb_const_get_at(mod, ci);
|
16
|
-
} else {
|
17
|
-
clas = Qundef;
|
18
|
-
}
|
19
|
-
return clas;
|
20
|
-
}
|
21
|
-
|
22
|
-
static VALUE
|
23
|
-
resolve_classpath(const char *name, size_t len) {
|
24
|
-
char class_name[1024];
|
25
|
-
VALUE clas;
|
26
|
-
char *end = class_name + sizeof(class_name) - 1;
|
27
|
-
char *s;
|
28
|
-
const char *n = name;
|
29
|
-
|
30
|
-
clas = rb_cObject;
|
31
|
-
for (s = class_name; 0 < len; n++, len--) {
|
32
|
-
if (':' == *n) {
|
33
|
-
*s = '\0';
|
34
|
-
n++;
|
35
|
-
len--;
|
36
|
-
if (':' != *n) {
|
37
|
-
return Qundef;
|
38
|
-
}
|
39
|
-
if (Qundef == (clas = resolve_classname(clas, class_name))) {
|
40
|
-
return Qundef;
|
41
|
-
}
|
42
|
-
s = class_name;
|
43
|
-
} else if (end <= s) {
|
44
|
-
return Qundef;
|
45
|
-
} else {
|
46
|
-
*s++ = *n;
|
47
|
-
}
|
48
|
-
}
|
49
|
-
*s = '\0';
|
50
|
-
return resolve_classname(clas, class_name);
|
51
|
-
}
|
52
|
-
|
53
9
|
Hook
|
54
|
-
hook_create(Method method, const char *pattern,
|
10
|
+
hook_create(Method method, const char *pattern, void *handler, HookType type) {
|
55
11
|
Hook hook = (Hook)malloc(sizeof(struct _Hook));
|
56
12
|
|
57
13
|
if (NULL != hook) {
|
@@ -60,67 +16,52 @@ hook_create(Method method, const char *pattern, VALUE handler) {
|
|
60
16
|
pattern = "";
|
61
17
|
}
|
62
18
|
hook->next = NULL;
|
63
|
-
if (T_STRING == rb_type(handler)) {
|
64
|
-
handler = resolve_classpath(StringValuePtr(handler), RSTRING_LEN(handler));
|
65
|
-
// TBD does class handle it or should an instance be made?
|
66
|
-
//
|
67
|
-
}
|
68
|
-
hook->handler = handler;
|
69
|
-
rb_gc_register_address(&handler);
|
70
19
|
hook->pattern = strdup(pattern);
|
71
20
|
DEBUG_ALLOC(mem_hook_pattern, hook->pattern)
|
72
21
|
hook->method = method;
|
73
|
-
|
74
|
-
|
75
|
-
} else if (rb_respond_to(handler, rb_intern("call"))) {
|
76
|
-
hook->type = RACK_HOOK;
|
77
|
-
} else if (rb_respond_to(handler, rb_intern("create")) &&
|
78
|
-
rb_respond_to(handler, rb_intern("read")) &&
|
79
|
-
rb_respond_to(handler, rb_intern("update")) &&
|
80
|
-
rb_respond_to(handler, rb_intern("delete"))) {
|
81
|
-
hook->type = WAB_HOOK;
|
82
|
-
} else {
|
83
|
-
rb_raise(rb_eArgError, "handler does not have a on_request, or call method nor is it a WAB::Controller");
|
84
|
-
}
|
22
|
+
hook->handler = handler;
|
23
|
+
hook->type = type;
|
85
24
|
}
|
86
25
|
return hook;
|
87
26
|
}
|
88
27
|
|
89
28
|
void
|
90
29
|
hook_destroy(Hook hook) {
|
91
|
-
DEBUG_FREE(mem_hook_pattern, hook->pattern)
|
92
|
-
|
30
|
+
DEBUG_FREE(mem_hook_pattern, hook->pattern);
|
31
|
+
DEBUG_FREE(mem_hook, hook)
|
93
32
|
free(hook->pattern);
|
94
33
|
free(hook);
|
95
34
|
}
|
96
35
|
|
97
36
|
bool
|
98
|
-
hook_match(Hook hook, Method method, const
|
37
|
+
hook_match(Hook hook, Method method, const Seg path) {
|
99
38
|
const char *pat = hook->pattern;
|
39
|
+
char *p = path->start;
|
40
|
+
char *end = path->end;
|
100
41
|
|
101
42
|
if (method != hook->method && ALL != hook->method) {
|
102
43
|
return false;
|
103
44
|
}
|
104
|
-
for (; '\0' != *pat &&
|
105
|
-
if (*
|
106
|
-
|
45
|
+
for (; '\0' != *pat && p < end; pat++) {
|
46
|
+
if (*p == *pat) {
|
47
|
+
p++;
|
107
48
|
} else if ('*' == *pat) {
|
108
49
|
if ('*' == *(pat + 1)) {
|
109
50
|
return true;
|
110
51
|
}
|
111
|
-
for (;
|
52
|
+
for (; p < end && '/' != *p; p++) {
|
112
53
|
}
|
113
54
|
} else {
|
114
55
|
break;
|
115
56
|
}
|
116
57
|
}
|
117
|
-
return '\0' == *pat &&
|
58
|
+
return '\0' == *pat && p == end;
|
118
59
|
}
|
119
60
|
|
120
61
|
Hook
|
121
|
-
hook_find(Hook hook, Method method, const
|
62
|
+
hook_find(Hook hook, Method method, const Seg path) {
|
122
63
|
for (; NULL != hook; hook = hook->next) {
|
123
|
-
if (hook_match(hook, method, path
|
64
|
+
if (hook_match(hook, method, path)) {
|
124
65
|
return hook;
|
125
66
|
}
|
126
67
|
}
|