agoo 2.5.1 → 2.5.2
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 +9 -1
- data/README.md +12 -1
- data/ext/agoo/agoo.c +4 -3
- data/ext/agoo/bind.c +51 -11
- data/ext/agoo/bind.h +9 -0
- data/ext/agoo/con.c +127 -89
- data/ext/agoo/con.h +24 -8
- data/ext/agoo/debug.c +2 -0
- data/ext/agoo/debug.h +1 -0
- data/ext/agoo/err.c +1 -1
- data/ext/agoo/err.h +2 -5
- data/ext/agoo/foo/agoo.c +109 -0
- data/ext/agoo/foo/con.c +1220 -0
- data/ext/agoo/foo/con.h +65 -0
- data/ext/agoo/foo/page.c +699 -0
- data/ext/agoo/foo/pub.c +131 -0
- data/ext/agoo/foo/pub.h +40 -0
- data/ext/agoo/foo/rserver.c +1016 -0
- data/ext/agoo/foo/server.c +303 -0
- data/ext/agoo/foo/server.h +67 -0
- data/ext/agoo/foo/upgraded.c +182 -0
- data/ext/agoo/hook.c +31 -0
- data/ext/agoo/hook.h +9 -10
- data/ext/agoo/{types.h → kinds.h} +3 -3
- data/ext/agoo/log.c +168 -83
- data/ext/agoo/log.h +6 -2
- data/ext/agoo/page.c +38 -32
- data/ext/agoo/pub.c +16 -0
- data/ext/agoo/pub.h +1 -0
- data/ext/agoo/queue.h +1 -0
- data/ext/agoo/req.c +95 -0
- data/ext/agoo/req.h +48 -0
- data/ext/agoo/request.c +10 -38
- data/ext/agoo/request.h +1 -34
- data/ext/agoo/res.h +1 -3
- data/ext/agoo/response.c +6 -248
- data/ext/agoo/response.h +2 -6
- data/ext/agoo/rlog.c +2 -1
- data/ext/agoo/rresponse.c +252 -0
- data/ext/agoo/rresponse.h +14 -0
- data/ext/agoo/rserver.c +43 -45
- data/ext/agoo/rserver.h +3 -24
- data/ext/agoo/rupgraded.c +303 -0
- data/ext/agoo/rupgraded.h +17 -0
- data/ext/agoo/server.c +125 -8
- data/ext/agoo/server.h +26 -4
- data/ext/agoo/sse.c +3 -1
- data/ext/agoo/upgraded.c +42 -280
- data/ext/agoo/upgraded.h +16 -8
- data/ext/agoo/websocket.c +13 -9
- data/lib/agoo/base.rb +84 -0
- data/lib/agoo/client.rb +25 -0
- data/lib/agoo/version.rb +1 -1
- data/test/bind_test.rb +2 -2
- metadata +22 -4
data/ext/agoo/log.h
CHANGED
@@ -58,11 +58,14 @@ typedef struct _LogEntry {
|
|
58
58
|
char *whatp;
|
59
59
|
char what[104];
|
60
60
|
volatile bool ready;
|
61
|
+
char *tidp;
|
62
|
+
char tid[40];
|
61
63
|
} *LogEntry;
|
62
64
|
|
63
65
|
struct _Log {
|
64
66
|
LogCat cats;
|
65
67
|
char dir[1024];
|
68
|
+
char app[16];
|
66
69
|
FILE *file; // current output file
|
67
70
|
int max_files;
|
68
71
|
int max_size;
|
@@ -102,7 +105,7 @@ extern struct _LogCat resp_cat;
|
|
102
105
|
extern struct _LogCat eval_cat;
|
103
106
|
extern struct _LogCat push_cat;
|
104
107
|
|
105
|
-
extern void log_init();
|
108
|
+
extern void log_init(const char *app);
|
106
109
|
extern void open_log_file();
|
107
110
|
|
108
111
|
extern void log_close();
|
@@ -115,7 +118,8 @@ extern LogCat log_cat_find(const char *label);
|
|
115
118
|
|
116
119
|
// Function to call to make a log entry.
|
117
120
|
extern void log_cat(LogCat cat, const char *fmt, ...);
|
118
|
-
extern void
|
121
|
+
extern void log_tid_cat(LogCat cat, const char *tid, const char *fmt, ...);
|
122
|
+
extern void log_catv(LogCat cat, const char *tid, const char *fmt, va_list ap);
|
119
123
|
|
120
124
|
extern void log_start(bool with_pid);
|
121
125
|
|
data/ext/agoo/page.c
CHANGED
@@ -275,7 +275,11 @@ pages_init() {
|
|
275
275
|
void
|
276
276
|
pages_set_root(const char *root) {
|
277
277
|
free(cache.root);
|
278
|
-
|
278
|
+
if (NULL == root) {
|
279
|
+
cache.root = NULL;
|
280
|
+
} else {
|
281
|
+
cache.root = strdup(root);
|
282
|
+
}
|
279
283
|
}
|
280
284
|
|
281
285
|
static void
|
@@ -380,7 +384,7 @@ page_immutable(Err err, const char *path, const char *content, int clen) {
|
|
380
384
|
p->path = NULL;
|
381
385
|
} else {
|
382
386
|
p->path = strdup(path);
|
383
|
-
plen = strlen(path);
|
387
|
+
plen = (int)strlen(path);
|
384
388
|
DEBUG_ALLOC(mem_page_path, p->path);
|
385
389
|
}
|
386
390
|
p->mtime = 0;
|
@@ -466,7 +470,7 @@ update_contents(Page p) {
|
|
466
470
|
fclose(f);
|
467
471
|
return false;
|
468
472
|
}
|
469
|
-
if (0
|
473
|
+
if (0 > (size = ftell(f))) {
|
470
474
|
fclose(f);
|
471
475
|
return false;
|
472
476
|
}
|
@@ -506,7 +510,7 @@ update_contents(Page p) {
|
|
506
510
|
|
507
511
|
static void
|
508
512
|
page_remove(Page p) {
|
509
|
-
int len = strlen(p->path);
|
513
|
+
int len = (int)strlen(p->path);
|
510
514
|
int64_t h = calc_hash(p->path, &len);
|
511
515
|
Slot *bucket = get_bucketp(h);
|
512
516
|
Slot s;
|
@@ -561,30 +565,32 @@ page_get(Err err, const char *path, int plen) {
|
|
561
565
|
return NULL;
|
562
566
|
}
|
563
567
|
if (NULL == (page = cache_get(path, plen))) {
|
564
|
-
|
565
|
-
|
566
|
-
|
568
|
+
if (NULL != cache.root) {
|
569
|
+
Page old;
|
570
|
+
char full_path[2048];
|
571
|
+
char *s = stpcpy(full_path, cache.root);
|
567
572
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
573
|
+
if ('/' != *cache.root && '/' != *path) {
|
574
|
+
*s++ = '/';
|
575
|
+
}
|
576
|
+
if ((int)sizeof(full_path) <= plen + (s - full_path)) {
|
577
|
+
err_set(err, ERR_MEMORY, "Failed to allocate memory for page path.");
|
578
|
+
return NULL;
|
579
|
+
}
|
580
|
+
strncpy(s, path, plen);
|
581
|
+
s[plen] = '\0';
|
582
|
+
if (NULL == (page = page_create(full_path))) {
|
583
|
+
err_set(err, ERR_MEMORY, "Failed to allocate memory for Page.");
|
584
|
+
return NULL;
|
585
|
+
}
|
586
|
+
if (!update_contents(page) || NULL == page->resp) {
|
587
|
+
page_destroy(page);
|
588
|
+
err_set(err, ERR_NOT_FOUND, "not found.");
|
589
|
+
return NULL;
|
590
|
+
}
|
591
|
+
if (NULL != (old = cache_set(path, plen, page))) {
|
592
|
+
page_destroy(old);
|
593
|
+
}
|
588
594
|
}
|
589
595
|
} else {
|
590
596
|
page = page_check(err, page);
|
@@ -597,7 +603,7 @@ group_get(Err err, const char *path, int plen) {
|
|
597
603
|
Page page = NULL;
|
598
604
|
Group g = NULL;
|
599
605
|
char full_path[2048];
|
600
|
-
char *s;
|
606
|
+
char *s = NULL;
|
601
607
|
Dir d;
|
602
608
|
|
603
609
|
if (NULL != strstr(path, "../")) {
|
@@ -619,7 +625,7 @@ group_get(Err err, const char *path, int plen) {
|
|
619
625
|
strncpy(s, path + g->plen, plen - g->plen);
|
620
626
|
s += plen - g->plen;
|
621
627
|
*s = '\0';
|
622
|
-
if (NULL != (page = cache_get(full_path, s - full_path))) {
|
628
|
+
if (NULL != (page = cache_get(full_path, (int)(s - full_path)))) {
|
623
629
|
break;
|
624
630
|
}
|
625
631
|
}
|
@@ -639,7 +645,7 @@ group_get(Err err, const char *path, int plen) {
|
|
639
645
|
if (NULL == d) {
|
640
646
|
return NULL;
|
641
647
|
}
|
642
|
-
plen = s - full_path;
|
648
|
+
plen = (int)(s - full_path);
|
643
649
|
path = full_path;
|
644
650
|
if (NULL == (page = cache_get(path, plen))) {
|
645
651
|
Page old;
|
@@ -671,7 +677,7 @@ group_create(const char *path) {
|
|
671
677
|
g->next = cache.groups;
|
672
678
|
cache.groups = g;
|
673
679
|
g->path = strdup(path);
|
674
|
-
g->plen = strlen(path);
|
680
|
+
g->plen = (int)strlen(path);
|
675
681
|
DEBUG_ALLOC(mem_group_path, g->path);
|
676
682
|
g->dirs = NULL;
|
677
683
|
}
|
@@ -687,7 +693,7 @@ group_add(Group g, const char *dir) {
|
|
687
693
|
d->next = g->dirs;
|
688
694
|
g->dirs = d;
|
689
695
|
d->path = strdup(dir);
|
690
|
-
d->plen = strlen(dir);
|
696
|
+
d->plen = (int)strlen(dir);
|
691
697
|
DEBUG_ALLOC(mem_dir_path, d->path);
|
692
698
|
}
|
693
699
|
}
|
data/ext/agoo/pub.c
CHANGED
@@ -98,6 +98,22 @@ pub_write(Upgraded up, const char *message, size_t mlen, bool bin) {
|
|
98
98
|
return p;
|
99
99
|
}
|
100
100
|
|
101
|
+
Pub
|
102
|
+
pub_dup(Pub src) {
|
103
|
+
Pub p = (Pub)malloc(sizeof(struct _Pub));
|
104
|
+
|
105
|
+
if (NULL != p) {
|
106
|
+
DEBUG_ALLOC(mem_pub, p);
|
107
|
+
p->next = NULL;
|
108
|
+
p->kind = src->kind;
|
109
|
+
p->up = src->up;
|
110
|
+
p->subject = subject_create(src->subject->pattern, strlen(src->subject->pattern));
|
111
|
+
p->msg = src->msg;
|
112
|
+
text_ref(p->msg);
|
113
|
+
}
|
114
|
+
return p;
|
115
|
+
}
|
116
|
+
|
101
117
|
void
|
102
118
|
pub_destroy(Pub pub) {
|
103
119
|
if (NULL != pub->msg) {
|
data/ext/agoo/pub.h
CHANGED
@@ -34,6 +34,7 @@ extern Pub pub_subscribe(struct _Upgraded *up, const char *subject, int slen);
|
|
34
34
|
extern Pub pub_unsubscribe(struct _Upgraded *up, const char *subject, int slen);
|
35
35
|
extern Pub pub_publish(const char *subject, int slen, const char *message, size_t mlen);
|
36
36
|
extern Pub pub_write(struct _Upgraded *up, const char *message, size_t mlen, bool bin);
|
37
|
+
extern Pub pub_dup(Pub src);
|
37
38
|
extern void pub_destroy(Pub pub);
|
38
39
|
|
39
40
|
#endif // __AGOO_PUB_H__
|
data/ext/agoo/queue.h
CHANGED
data/ext/agoo/req.c
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <string.h>
|
6
|
+
#include <ctype.h>
|
7
|
+
|
8
|
+
#include "con.h"
|
9
|
+
#include "debug.h"
|
10
|
+
#include "server.h"
|
11
|
+
#include "req.h"
|
12
|
+
|
13
|
+
Req
|
14
|
+
req_create(size_t mlen) {
|
15
|
+
size_t size = mlen + sizeof(struct _Req) - 7;
|
16
|
+
Req req = (Req)malloc(size);
|
17
|
+
|
18
|
+
if (NULL != req) {
|
19
|
+
DEBUG_ALLOC(mem_req, req);
|
20
|
+
memset(req, 0, size);
|
21
|
+
req->env = the_server.env_nil_value;
|
22
|
+
req->mlen = mlen;
|
23
|
+
req->hook = NULL;
|
24
|
+
}
|
25
|
+
return req;
|
26
|
+
}
|
27
|
+
|
28
|
+
void
|
29
|
+
req_destroy(Req req) {
|
30
|
+
DEBUG_FREE(mem_req, req);
|
31
|
+
if (NULL != req->hook && PUSH_HOOK == req->hook->type) {
|
32
|
+
free(req->hook);
|
33
|
+
}
|
34
|
+
free(req);
|
35
|
+
}
|
36
|
+
|
37
|
+
const char*
|
38
|
+
req_host(Req r, int *lenp) {
|
39
|
+
const char *host;
|
40
|
+
const char *colon;
|
41
|
+
|
42
|
+
if (NULL == (host = con_header_value(r->header.start, r->header.len, "Host", lenp))) {
|
43
|
+
return NULL;
|
44
|
+
}
|
45
|
+
for (colon = host + *lenp - 1; host < colon; colon--) {
|
46
|
+
if (':' == *colon) {
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
if (host < colon) {
|
51
|
+
*lenp = (int)(colon - host);
|
52
|
+
}
|
53
|
+
return host;
|
54
|
+
}
|
55
|
+
|
56
|
+
int
|
57
|
+
req_port(Req r) {
|
58
|
+
int len;
|
59
|
+
const char *host;
|
60
|
+
const char *colon;
|
61
|
+
|
62
|
+
if (NULL == (host = con_header_value(r->header.start, r->header.len, "Host", &len))) {
|
63
|
+
return 0;
|
64
|
+
}
|
65
|
+
for (colon = host + len - 1; host < colon; colon--) {
|
66
|
+
if (':' == *colon) {
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
if (host == colon) {
|
71
|
+
return 0;
|
72
|
+
}
|
73
|
+
return (int)strtol(colon + 1, NULL, 10);
|
74
|
+
}
|
75
|
+
|
76
|
+
const char*
|
77
|
+
req_query_value(Req r, const char *key, int klen, int *vlenp) {
|
78
|
+
const char *value;
|
79
|
+
|
80
|
+
if (NULL != (value = strstr(r->query.start, key))) {
|
81
|
+
char *end;
|
82
|
+
|
83
|
+
if (0 >= klen) {
|
84
|
+
klen = strlen(key);
|
85
|
+
}
|
86
|
+
value += klen + 1;
|
87
|
+
if (NULL == (end = index(value, '&'))) {
|
88
|
+
*vlenp = strlen(value);
|
89
|
+
} else {
|
90
|
+
*vlenp = (int)(end - value);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
return value;
|
94
|
+
}
|
95
|
+
|
data/ext/agoo/req.h
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef __AGOO_REQ_H__
|
4
|
+
#define __AGOO_REQ_H__
|
5
|
+
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
#include "hook.h"
|
9
|
+
#include "kinds.h"
|
10
|
+
|
11
|
+
struct _Server;
|
12
|
+
struct _Upgraded;
|
13
|
+
struct _Res;
|
14
|
+
|
15
|
+
typedef enum {
|
16
|
+
UP_NONE = '\0',
|
17
|
+
UP_WS = 'W',
|
18
|
+
UP_SSE = 'S',
|
19
|
+
} Upgrade;
|
20
|
+
|
21
|
+
typedef struct _Str {
|
22
|
+
char *start;
|
23
|
+
unsigned int len;
|
24
|
+
} *Str;
|
25
|
+
|
26
|
+
typedef struct _Req {
|
27
|
+
Method method;
|
28
|
+
struct _Res *res;
|
29
|
+
|
30
|
+
Upgrade upgrade;
|
31
|
+
struct _Upgraded *up;
|
32
|
+
struct _Str path;
|
33
|
+
struct _Str query;
|
34
|
+
struct _Str header;
|
35
|
+
struct _Str body;
|
36
|
+
void *env;
|
37
|
+
Hook hook;
|
38
|
+
size_t mlen; // allocated msg length
|
39
|
+
char msg[8]; // expanded to be full message
|
40
|
+
} *Req;
|
41
|
+
|
42
|
+
extern Req req_create(size_t mlen);
|
43
|
+
extern void req_destroy(Req req);
|
44
|
+
extern const char* req_host(Req r, int *lenp);
|
45
|
+
extern int req_port(Req r);
|
46
|
+
extern const char* req_query_value(Req r, const char *key, int klen, int *vlenp);
|
47
|
+
|
48
|
+
#endif // __AGOO_REQ_H__
|
data/ext/agoo/request.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
3
|
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
4
5
|
#include <ctype.h>
|
5
6
|
|
6
7
|
#include "debug.h"
|
@@ -8,6 +9,7 @@
|
|
8
9
|
#include "error_stream.h"
|
9
10
|
#include "rack_logger.h"
|
10
11
|
#include "request.h"
|
12
|
+
#include "res.h"
|
11
13
|
|
12
14
|
static VALUE req_class = Qundef;
|
13
15
|
|
@@ -59,21 +61,6 @@ static const char websocket_val[] = "websocket";
|
|
59
61
|
static const char accept_key[] = "Accept";
|
60
62
|
static const char event_stream_val[] = "text/event-stream";
|
61
63
|
|
62
|
-
Req
|
63
|
-
request_create(size_t mlen) {
|
64
|
-
size_t size = mlen + sizeof(struct _Req) - 7;
|
65
|
-
Req req = (Req)malloc(size);
|
66
|
-
|
67
|
-
if (NULL != req) {
|
68
|
-
DEBUG_ALLOC(mem_req, req);
|
69
|
-
memset(req, 0, size);
|
70
|
-
req->env = Qnil;
|
71
|
-
req->mlen = mlen;
|
72
|
-
req->hook = NULL;
|
73
|
-
}
|
74
|
-
return req;
|
75
|
-
}
|
76
|
-
|
77
64
|
static VALUE
|
78
65
|
req_method(Req r) {
|
79
66
|
VALUE m;
|
@@ -185,23 +172,14 @@ static VALUE
|
|
185
172
|
req_server_name(Req r) {
|
186
173
|
int len;
|
187
174
|
const char *host;
|
188
|
-
const char *colon;
|
189
175
|
|
190
176
|
if (NULL == r) {
|
191
177
|
rb_raise(rb_eArgError, "Request is no longer valid.");
|
192
178
|
}
|
193
|
-
if (NULL == (host =
|
179
|
+
if (NULL == (host = req_host(r, &len))) {
|
194
180
|
return rb_str_new2("unknown");
|
195
181
|
}
|
196
|
-
|
197
|
-
if (':' == *colon) {
|
198
|
-
break;
|
199
|
-
}
|
200
|
-
}
|
201
|
-
if (host == colon) {
|
202
|
-
return rb_str_new(host, len);
|
203
|
-
}
|
204
|
-
return rb_str_new(host, colon - host);
|
182
|
+
return rb_str_new(host, len);
|
205
183
|
}
|
206
184
|
|
207
185
|
/* Document-method: server_name
|
@@ -381,6 +359,7 @@ rack_run_once(VALUE self) {
|
|
381
359
|
return Qfalse;
|
382
360
|
}
|
383
361
|
|
362
|
+
// TBD req.c
|
384
363
|
static void
|
385
364
|
add_header_value(VALUE hh, const char *key, int klen, const char *val, int vlen) {
|
386
365
|
if (sizeof(content_type) - 1 == klen && 0 == strncasecmp(key, content_type, sizeof(content_type) - 1)) {
|
@@ -413,6 +392,7 @@ add_header_value(VALUE hh, const char *key, int klen, const char *val, int vlen)
|
|
413
392
|
}
|
414
393
|
}
|
415
394
|
|
395
|
+
// TBD req.c
|
416
396
|
static void
|
417
397
|
fill_headers(Req r, VALUE hash) {
|
418
398
|
char *h = r->header.start;
|
@@ -551,7 +531,7 @@ rack_logger(VALUE self) {
|
|
551
531
|
*/
|
552
532
|
VALUE
|
553
533
|
request_env(Req req, VALUE self) {
|
554
|
-
if (Qnil == req->env) {
|
534
|
+
if (Qnil == (VALUE)req->env) {
|
555
535
|
volatile VALUE env = rb_hash_new();
|
556
536
|
|
557
537
|
// As described by
|
@@ -586,9 +566,9 @@ request_env(Req req, VALUE self) {
|
|
586
566
|
rb_hash_aset(env, rack_hijack_val, self);
|
587
567
|
rb_hash_aset(env, rack_hijack_io_val, Qnil);
|
588
568
|
|
589
|
-
req->env = env;
|
569
|
+
req->env = (void*)env;
|
590
570
|
}
|
591
|
-
return req->env;
|
571
|
+
return (VALUE)req->env;
|
592
572
|
}
|
593
573
|
|
594
574
|
/* Document-method: to_h
|
@@ -644,18 +624,10 @@ call(VALUE self) {
|
|
644
624
|
args[0] = INT2NUM(r->res->con->sock);
|
645
625
|
|
646
626
|
io = rb_class_new_instance(1, args, rb_cIO);
|
647
|
-
rb_hash_aset(r->env, rack_hijack_io_val, io);
|
627
|
+
rb_hash_aset((VALUE)r->env, rack_hijack_io_val, io);
|
648
628
|
|
649
629
|
return io;
|
650
630
|
}
|
651
|
-
void
|
652
|
-
request_destroy(Req req) {
|
653
|
-
DEBUG_FREE(mem_req, req);
|
654
|
-
if (NULL != req->hook && PUSH_HOOK == req->hook->type) {
|
655
|
-
free(req->hook);
|
656
|
-
}
|
657
|
-
free(req);
|
658
|
-
}
|
659
631
|
|
660
632
|
VALUE
|
661
633
|
request_wrap(Req req) {
|