agoo 2.6.1 → 2.7.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 +8 -0
- data/ext/agoo/agoo.c +5 -1
- data/ext/agoo/bind.c +17 -18
- data/ext/agoo/con.c +14 -7
- data/ext/agoo/debug.c +113 -63
- data/ext/agoo/debug.h +3 -0
- data/ext/agoo/err.c +7 -0
- data/ext/agoo/err.h +4 -0
- data/ext/agoo/error_stream.c +6 -0
- data/ext/agoo/gqleval.c +1 -1
- data/ext/agoo/gqlvalue.c +10 -11
- data/ext/agoo/graphql.c +181 -105
- data/ext/agoo/graphql.h +9 -0
- data/ext/agoo/hook.c +17 -7
- data/ext/agoo/log.c +8 -10
- data/ext/agoo/log.h +1 -1
- data/ext/agoo/page.c +242 -31
- data/ext/agoo/page.h +4 -3
- data/ext/agoo/queue.c +10 -7
- data/ext/agoo/queue.h +3 -2
- data/ext/agoo/ready.c +8 -7
- data/ext/agoo/rgraphql.c +29 -25
- data/ext/agoo/rlog.c +2 -2
- data/ext/agoo/rresponse.c +6 -0
- data/ext/agoo/rserver.c +49 -8
- data/ext/agoo/sdl.c +82 -35
- data/ext/agoo/sdl.h +3 -1
- data/ext/agoo/server.c +10 -6
- data/ext/agoo/server.h +2 -1
- data/ext/agoo/upgraded.c +2 -3
- data/lib/agoo/version.rb +1 -1
- data/test/static_test.rb +6 -1
- metadata +2 -2
data/ext/agoo/page.h
CHANGED
@@ -30,17 +30,18 @@ typedef struct _agooGroup {
|
|
30
30
|
agooDir dirs;
|
31
31
|
} *agooGroup;
|
32
32
|
|
33
|
-
extern
|
34
|
-
extern
|
33
|
+
extern int agoo_pages_init(agooErr err);
|
34
|
+
extern int agoo_pages_set_root(agooErr err, const char *root);
|
35
35
|
extern void agoo_pages_cleanup();
|
36
36
|
|
37
37
|
extern agooGroup group_create(const char *path);
|
38
|
-
extern
|
38
|
+
extern agooDir group_add(agooErr err, agooGroup g, const char *dir);
|
39
39
|
extern agooPage group_get(agooErr err, const char *path, int plen);
|
40
40
|
|
41
41
|
extern agooPage agoo_page_create(const char *path);
|
42
42
|
extern agooPage agoo_page_immutable(agooErr err, const char *path, const char *content, int clen);
|
43
43
|
extern agooPage agoo_page_get(agooErr err, const char *path, int plen);
|
44
44
|
extern int mime_set(agooErr err, const char *key, const char *value);
|
45
|
+
extern int agoo_header_rule(agooErr err, const char *path, const char *mime, const char *key, const char *value);
|
45
46
|
|
46
47
|
#endif // AGOO_PAGE_H
|
data/ext/agoo/queue.c
CHANGED
@@ -26,20 +26,21 @@
|
|
26
26
|
// When head == tail the queue is full. This happens when tail catches up with head.
|
27
27
|
//
|
28
28
|
|
29
|
-
|
30
|
-
agoo_queue_init(agooQueue q, size_t qsize) {
|
31
|
-
agoo_queue_multi_init(q, qsize, false, false);
|
29
|
+
int
|
30
|
+
agoo_queue_init(agooErr err, agooQueue q, size_t qsize) {
|
31
|
+
return agoo_queue_multi_init(err, q, qsize, false, false);
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
agoo_queue_multi_init(agooQueue q, size_t qsize, bool multi_push, bool multi_pop) {
|
34
|
+
int
|
35
|
+
agoo_queue_multi_init(agooErr err, agooQueue q, size_t qsize, bool multi_push, bool multi_pop) {
|
36
36
|
if (qsize < 4) {
|
37
37
|
qsize = 4;
|
38
38
|
}
|
39
|
-
q->q = (agooQItem*)
|
39
|
+
if (NULL == (q->q = (agooQItem*)AGOO_CALLOC(qsize, sizeof(agooQItem)))) {
|
40
|
+
return AGOO_ERR_MEM(err, "Queue");
|
41
|
+
}
|
40
42
|
q->end = q->q + qsize;
|
41
43
|
|
42
|
-
memset(q->q, 0, sizeof(agooQItem) * qsize);
|
43
44
|
atomic_init(&q->head, q->q);
|
44
45
|
atomic_init(&q->tail, q->q + 1);
|
45
46
|
agoo_atomic_flag_init(&q->push_lock);
|
@@ -50,6 +51,8 @@ agoo_queue_multi_init(agooQueue q, size_t qsize, bool multi_push, bool multi_pop
|
|
50
51
|
// Create when/if needed.
|
51
52
|
q->rsock = 0;
|
52
53
|
q->wsock = 0;
|
54
|
+
|
55
|
+
return AGOO_ERR_OK;
|
53
56
|
}
|
54
57
|
|
55
58
|
void
|
data/ext/agoo/queue.h
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
#include <stdlib.h>
|
8
8
|
|
9
9
|
#include "atomic.h"
|
10
|
+
#include "err.h"
|
10
11
|
|
11
12
|
typedef void *agooQItem;
|
12
13
|
|
@@ -24,9 +25,9 @@ typedef struct _agooQueue {
|
|
24
25
|
int wsock;
|
25
26
|
} *agooQueue;
|
26
27
|
|
27
|
-
extern
|
28
|
+
extern int agoo_queue_init(agooErr err, agooQueue q, size_t qsize);
|
28
29
|
|
29
|
-
extern
|
30
|
+
extern int agoo_queue_multi_init(agooErr err, agooQueue q, size_t qsize, bool multi_push, bool multi_pop);
|
30
31
|
|
31
32
|
extern void agoo_queue_cleanup(agooQueue q);
|
32
33
|
extern void agoo_queue_push(agooQueue q, agooQItem item);
|
data/ext/agoo/ready.c
CHANGED
@@ -59,7 +59,7 @@ link_create(agooErr err, int fd, void *ctx, agooHandler handler) {
|
|
59
59
|
Link link = (Link)AGOO_MALLOC(sizeof(struct _link));
|
60
60
|
|
61
61
|
if (NULL == link) {
|
62
|
-
|
62
|
+
AGOO_ERR_MEM(err, "Connection Link");
|
63
63
|
} else {
|
64
64
|
//DEBUG_ALLOC(mem_???, c);
|
65
65
|
link->next = NULL;
|
@@ -76,7 +76,7 @@ agoo_ready_create(agooErr err) {
|
|
76
76
|
agooReady ready = (agooReady)AGOO_MALLOC(sizeof(struct _agooReady));
|
77
77
|
|
78
78
|
if (NULL == ready) {
|
79
|
-
|
79
|
+
AGOO_ERR_MEM(err, "Connection Manager");
|
80
80
|
} else {
|
81
81
|
//DEBUG_ALLOC(mem_???, c);
|
82
82
|
ready->links = NULL;
|
@@ -126,7 +126,7 @@ agoo_ready_add(agooErr err,
|
|
126
126
|
agooHandler handler,
|
127
127
|
void *ctx) {
|
128
128
|
Link link;
|
129
|
-
|
129
|
+
|
130
130
|
if (NULL == (link = link_create(err, fd, ctx, handler))) {
|
131
131
|
return err->code;
|
132
132
|
}
|
@@ -155,9 +155,9 @@ agoo_ready_add(agooErr err,
|
|
155
155
|
if (ready->pend - ready->pa <= ready->lcnt) {
|
156
156
|
size_t cnt = (ready->pend - ready->pa) * 2;
|
157
157
|
size_t size = cnt * sizeof(struct pollfd);
|
158
|
-
|
158
|
+
|
159
159
|
if (NULL == (ready->pa = (struct pollfd*)AGOO_REALLOC(ready->pa, size))) {
|
160
|
-
|
160
|
+
AGOO_ERR_MEM(err, "Connection Pool");
|
161
161
|
agoo_log_cat(&agoo_error_cat, "Out of memory.");
|
162
162
|
agoo_log_close();
|
163
163
|
exit(EXIT_FAILURE);
|
@@ -206,7 +206,7 @@ agoo_ready_go(agooErr err, agooReady ready) {
|
|
206
206
|
double now;
|
207
207
|
Link link;
|
208
208
|
Link next;
|
209
|
-
|
209
|
+
|
210
210
|
#if HAVE_SYS_EPOLL_H
|
211
211
|
struct epoll_event events[EPOLL_SIZE];
|
212
212
|
struct epoll_event *ep;
|
@@ -271,7 +271,7 @@ agoo_ready_go(agooErr err, agooReady ready) {
|
|
271
271
|
#else
|
272
272
|
struct pollfd *pp;
|
273
273
|
int i;
|
274
|
-
|
274
|
+
|
275
275
|
// Setup the poll events.
|
276
276
|
for (link = ready->links, pp = ready->pa; NULL != link; link = link->next, pp++) {
|
277
277
|
pp->fd = link->fd;
|
@@ -290,6 +290,7 @@ agoo_ready_go(agooErr err, agooReady ready) {
|
|
290
290
|
case AGOO_READY_NONE:
|
291
291
|
default:
|
292
292
|
// ignore, either dead or closing
|
293
|
+
link->pp = NULL;
|
293
294
|
pp--;
|
294
295
|
break;
|
295
296
|
}
|
data/ext/agoo/rgraphql.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#include <ruby.h>
|
7
7
|
#include <ruby/thread.h>
|
8
8
|
|
9
|
+
#include "debug.h"
|
9
10
|
#include "err.h"
|
10
11
|
#include "gqleval.h"
|
11
12
|
#include "gqlintro.h"
|
@@ -90,7 +91,7 @@ eval_wrap(agooErr err, gqlDoc doc) {
|
|
90
91
|
.err = err,
|
91
92
|
.value = NULL,
|
92
93
|
};
|
93
|
-
|
94
|
+
|
94
95
|
rb_thread_call_with_gvl(protect_eval, &eval);
|
95
96
|
|
96
97
|
return eval.value;
|
@@ -123,7 +124,7 @@ gval_to_ruby(gqlValue value) {
|
|
123
124
|
break;
|
124
125
|
case GQL_SCALAR_TIME: {
|
125
126
|
time_t secs = (time_t)(value->time / 1000000000LL);
|
126
|
-
|
127
|
+
|
127
128
|
rval = rb_time_nano_new(secs, (long)(value->time - secs * 1000000000LL));
|
128
129
|
break;
|
129
130
|
}
|
@@ -141,7 +142,7 @@ gval_to_ruby(gqlValue value) {
|
|
141
142
|
}
|
142
143
|
case GQL_SCALAR_LIST: {
|
143
144
|
gqlLink link;
|
144
|
-
|
145
|
+
|
145
146
|
rval = rb_ary_new();
|
146
147
|
for (link = value->members; NULL != link; link = link->next) {
|
147
148
|
rb_ary_push(rval, gval_to_ruby(link->value));
|
@@ -150,11 +151,11 @@ gval_to_ruby(gqlValue value) {
|
|
150
151
|
}
|
151
152
|
case GQL_SCALAR_OBJECT: {
|
152
153
|
gqlLink link;
|
153
|
-
|
154
|
+
|
154
155
|
rval = rb_hash_new();
|
155
156
|
for (link = value->members; NULL != link; link = link->next) {
|
156
157
|
rb_hash_aset(rval, rb_str_new_cstr(link->key), gval_to_ruby(link->value));
|
157
|
-
|
158
|
+
|
158
159
|
}
|
159
160
|
break;
|
160
161
|
}
|
@@ -170,7 +171,7 @@ gval_to_ruby(gqlValue value) {
|
|
170
171
|
static VALUE
|
171
172
|
ref_to_string(gqlRef ref) {
|
172
173
|
volatile VALUE value;
|
173
|
-
|
174
|
+
|
174
175
|
if (T_STRING == rb_type((VALUE)ref)) {
|
175
176
|
value = (VALUE)ref;
|
176
177
|
} else {
|
@@ -344,7 +345,7 @@ ref_type(gqlRef ref) {
|
|
344
345
|
if (NULL != type_class_map) {
|
345
346
|
TypeClass tc;
|
346
347
|
const char *classname = rb_obj_classname((VALUE)ref);
|
347
|
-
|
348
|
+
|
348
349
|
for (tc = type_class_map; NULL != tc->type; tc++) {
|
349
350
|
if (0 == strcmp(classname, tc->classname)) {
|
350
351
|
type = tc->type;
|
@@ -383,10 +384,10 @@ resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlV
|
|
383
384
|
if (NULL == sel->args) {
|
384
385
|
child = rb_funcall(obj, rb_intern(sel->name), 0);
|
385
386
|
} else {
|
386
|
-
volatile VALUE rargs = rb_hash_new();
|
387
|
+
volatile VALUE rargs = rb_hash_new();
|
387
388
|
gqlSelArg sa;
|
388
389
|
gqlValue v;
|
389
|
-
|
390
|
+
|
390
391
|
for (sa = sel->args; NULL != sa; sa = sa->next) {
|
391
392
|
if (NULL != sa->var) {
|
392
393
|
v = sa->var->value;
|
@@ -395,7 +396,7 @@ resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlV
|
|
395
396
|
}
|
396
397
|
if (NULL != field) {
|
397
398
|
gqlArg fa;
|
398
|
-
|
399
|
+
|
399
400
|
for (fa = field->args; NULL != fa; fa = fa->next) {
|
400
401
|
if (0 == strcmp(sa->name, fa->name)) {
|
401
402
|
if (v->type != fa->type && GQL_SCALAR_VAR != v->type->scalar_kind) {
|
@@ -418,7 +419,7 @@ resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlV
|
|
418
419
|
gqlValue list;
|
419
420
|
int cnt;
|
420
421
|
int i;
|
421
|
-
|
422
|
+
|
422
423
|
rb_check_type(child, RUBY_T_ARRAY);
|
423
424
|
if (NULL == (list = gql_list_create(err, NULL))) {
|
424
425
|
return err->code;
|
@@ -452,7 +453,7 @@ resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlV
|
|
452
453
|
}
|
453
454
|
} else if (NULL == sel->sels) {
|
454
455
|
gqlValue cv;
|
455
|
-
|
456
|
+
|
456
457
|
if (NULL == (cv = coerce(err, (gqlRef)child, sel->type)) ||
|
457
458
|
AGOO_ERR_OK != gql_object_set(err, result, key, cv)) {
|
458
459
|
return err->code;
|
@@ -482,7 +483,7 @@ ruby_types_cb(gqlType type, void *ctx) {
|
|
482
483
|
if (NULL != type_class_map) {
|
483
484
|
TypeClass tc = &type_class_map[*(int*)ctx];
|
484
485
|
gqlLink arg;
|
485
|
-
|
486
|
+
|
486
487
|
tc->type = type;
|
487
488
|
for (arg = dir->args; NULL != arg; arg = arg->next) {
|
488
489
|
if (0 == strcmp("class", arg->key)) {
|
@@ -498,16 +499,15 @@ ruby_types_cb(gqlType type, void *ctx) {
|
|
498
499
|
static int
|
499
500
|
build_type_class_map(agooErr err) {
|
500
501
|
int cnt = 0;
|
501
|
-
|
502
|
-
|
502
|
+
|
503
|
+
AGOO_FREE(type_class_map);
|
503
504
|
type_class_map = NULL;
|
504
505
|
|
505
506
|
gql_type_iterate(ruby_types_cb, &cnt);
|
506
507
|
|
507
|
-
if (NULL == (type_class_map = (TypeClass)
|
508
|
-
return
|
508
|
+
if (NULL == (type_class_map = (TypeClass)AGOO_CALLOC(cnt + 1, sizeof(struct _typeClass)))) {
|
509
|
+
return AGOO_ERR_MEM(err, "GraphQL Class map");
|
509
510
|
}
|
510
|
-
memset(type_class_map, 0, sizeof(struct _typeClass) * (cnt + 1));
|
511
511
|
cnt = 0;
|
512
512
|
gql_type_iterate(ruby_types_cb, &cnt);
|
513
513
|
|
@@ -657,9 +657,9 @@ static VALUE
|
|
657
657
|
graphql_load_file(VALUE self, VALUE path) {
|
658
658
|
struct _agooErr err = AGOO_ERR_INIT;
|
659
659
|
FILE *f;
|
660
|
-
|
660
|
+
long len;
|
661
661
|
char *sdl;
|
662
|
-
|
662
|
+
|
663
663
|
if (NULL == gql_root) {
|
664
664
|
rb_raise(rb_eStandardError, "GraphQL root not set. Use Agoo::GraphQL.schema.");
|
665
665
|
}
|
@@ -670,10 +670,14 @@ graphql_load_file(VALUE self, VALUE path) {
|
|
670
670
|
if (0 != fseek(f, 0, SEEK_END)) {
|
671
671
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
672
672
|
}
|
673
|
-
len = ftell(f)
|
673
|
+
if (0 > (len = ftell(f))) {
|
674
|
+
rb_raise(rb_eIOError, "%s", strerror(errno));
|
675
|
+
}
|
674
676
|
sdl = ALLOC_N(char, len + 1);
|
675
|
-
fseek(f, 0, SEEK_SET)
|
676
|
-
|
677
|
+
if (0 != fseek(f, 0, SEEK_SET)) {
|
678
|
+
rb_raise(rb_eIOError, "%s", strerror(errno));
|
679
|
+
}
|
680
|
+
if (len != (long)fread(sdl, 1, len, f)) {
|
677
681
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
678
682
|
} else {
|
679
683
|
sdl[len] = '\0';
|
@@ -711,7 +715,7 @@ graphql_sdl_dump(VALUE self, VALUE options) {
|
|
711
715
|
VALUE v;
|
712
716
|
bool with_desc = true;
|
713
717
|
bool all = false;
|
714
|
-
|
718
|
+
|
715
719
|
Check_Type(options, T_HASH);
|
716
720
|
|
717
721
|
v = rb_hash_aref(options, ID2SYM(rb_intern("with_descriptions")));
|
@@ -726,7 +730,7 @@ graphql_sdl_dump(VALUE self, VALUE options) {
|
|
726
730
|
|
727
731
|
dump = rb_str_new(t->text, t->len);
|
728
732
|
agoo_text_release(t);
|
729
|
-
|
733
|
+
|
730
734
|
return dump;
|
731
735
|
}
|
732
736
|
|
data/ext/agoo/rlog.c
CHANGED
@@ -468,8 +468,8 @@ rlog_init(VALUE mod) {
|
|
468
468
|
|
469
469
|
agoo_log.on_error = on_error;
|
470
470
|
|
471
|
-
agoo_log_init("agoo")
|
472
|
-
|
471
|
+
if (AGOO_ERR_OK != agoo_log_init(&err, "agoo") ||
|
472
|
+
AGOO_ERR_OK != agoo_log_start(&err, false)) {
|
473
473
|
rb_raise(rb_eStandardError, "%s", err.msg);
|
474
474
|
}
|
475
475
|
}
|
data/ext/agoo/rresponse.c
CHANGED
@@ -28,6 +28,9 @@ VALUE
|
|
28
28
|
response_new() {
|
29
29
|
agooResponse res = (agooResponse)AGOO_MALLOC(sizeof(struct _agooResponse));
|
30
30
|
|
31
|
+
if (NULL == res) {
|
32
|
+
return Qnil;
|
33
|
+
}
|
31
34
|
memset(res, 0, sizeof(struct _agooResponse));
|
32
35
|
res->code = 200;
|
33
36
|
|
@@ -46,6 +49,9 @@ to_s(VALUE self) {
|
|
46
49
|
int len = agoo_response_len(res);
|
47
50
|
char *s = (char*)AGOO_MALLOC(len + 1);
|
48
51
|
|
52
|
+
if (NULL == s) {
|
53
|
+
rb_raise(rb_eNoMemError, "out of memory");
|
54
|
+
}
|
49
55
|
agoo_response_fill(res, s);
|
50
56
|
|
51
57
|
return rb_str_new(s, len);
|
data/ext/agoo/rserver.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <netinet/tcp.h>
|
5
5
|
#include <signal.h>
|
6
6
|
#include <stdio.h>
|
7
|
+
#include <string.h>
|
7
8
|
#include <sys/wait.h>
|
8
9
|
|
9
10
|
#include <ruby.h>
|
@@ -93,7 +94,9 @@ url_bind(VALUE rurl) {
|
|
93
94
|
|
94
95
|
static int
|
95
96
|
configure(agooErr err, int port, const char *root, VALUE options) {
|
96
|
-
agoo_pages_set_root(root)
|
97
|
+
if (AGOO_ERR_OK != agoo_pages_set_root(err, root)) {
|
98
|
+
return err->code;
|
99
|
+
}
|
97
100
|
agoo_server.thread_cnt = 0;
|
98
101
|
the_rserver.worker_cnt = 1;
|
99
102
|
atomic_init(&agoo_server.running, 0);
|
@@ -236,9 +239,10 @@ configure(agooErr err, int port, const char *root, VALUE options) {
|
|
236
239
|
* call-seq: init(port, root, options)
|
237
240
|
*
|
238
241
|
* Configures the server that will listen on the designated _port_ and using
|
239
|
-
* the _root_ as the root of the static resources.
|
240
|
-
*
|
241
|
-
*
|
242
|
+
* the _root_ as the root of the static resources. This must be called before
|
243
|
+
* using other server methods. Logging is feature based and not level based
|
244
|
+
* and the options reflect that approach. If bind option is to be used instead
|
245
|
+
* of the port then set the port to zero.
|
242
246
|
*
|
243
247
|
* - *options* [_Hash_] server options
|
244
248
|
*
|
@@ -268,7 +272,9 @@ rserver_init(int argc, VALUE *argv, VALUE self) {
|
|
268
272
|
if (3 <= argc) {
|
269
273
|
options = argv[2];
|
270
274
|
}
|
271
|
-
agoo_server_setup()
|
275
|
+
if (AGOO_ERR_OK != agoo_server_setup(&err)) {
|
276
|
+
rb_raise(rb_eStandardError, "%s", err.msg);
|
277
|
+
}
|
272
278
|
agoo_server.ctx_nil_value = (void*)Qnil;
|
273
279
|
agoo_server.env_nil_value = (void*)Qnil;
|
274
280
|
|
@@ -762,7 +768,7 @@ rserver_start(VALUE self) {
|
|
762
768
|
agooReq req;
|
763
769
|
|
764
770
|
while (agoo_server.active) {
|
765
|
-
if (NULL != (req = (agooReq)agoo_queue_pop(&agoo_server.eval_queue, 0.
|
771
|
+
if (NULL != (req = (agooReq)agoo_queue_pop(&agoo_server.eval_queue, 0.1))) {
|
766
772
|
handle_protected(req, false);
|
767
773
|
agoo_req_destroy(req);
|
768
774
|
} else {
|
@@ -998,7 +1004,8 @@ add_mime(VALUE self, VALUE suffix, VALUE type) {
|
|
998
1004
|
*/
|
999
1005
|
static VALUE
|
1000
1006
|
path_group(VALUE self, VALUE path, VALUE dirs) {
|
1001
|
-
|
1007
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
1008
|
+
agooGroup g;
|
1002
1009
|
|
1003
1010
|
rb_check_type(path, T_STRING);
|
1004
1011
|
rb_check_type(dirs, T_ARRAY);
|
@@ -1013,12 +1020,45 @@ path_group(VALUE self, VALUE path, VALUE dirs) {
|
|
1013
1020
|
if (T_STRING != rb_type(entry)) {
|
1014
1021
|
entry = rb_funcall(entry, rb_intern("to_s"), 0);
|
1015
1022
|
}
|
1016
|
-
group_add(g, StringValuePtr(entry))
|
1023
|
+
if (NULL == group_add(&err, g, StringValuePtr(entry))) {
|
1024
|
+
rb_raise(rb_eStandardError, "%s", err.msg);
|
1025
|
+
}
|
1017
1026
|
}
|
1018
1027
|
}
|
1019
1028
|
return Qnil;
|
1020
1029
|
}
|
1021
1030
|
|
1031
|
+
/* Document-method: header_rule
|
1032
|
+
*
|
1033
|
+
* call-seq: header_rule(path, mime, key, value)
|
1034
|
+
*
|
1035
|
+
* Add a header rule. A header rule will add the key and value to the headers
|
1036
|
+
* of any static asset that matches the path and mime type specified. The path
|
1037
|
+
* pattern follows glob like rules in that a single * matches a single token
|
1038
|
+
* bounded by the `/` character and a double ** matches all remaining. The
|
1039
|
+
* mime can also be a * which matches all types. The mime argument will be
|
1040
|
+
* compared to the mine type as well as the file extension so
|
1041
|
+
* 'applicaiton/json', a mime type can be used as can 'json' as a file
|
1042
|
+
* extension. All rules that match add the header key and value to the header
|
1043
|
+
* of a static asset.
|
1044
|
+
*
|
1045
|
+
* Note that the server must be initialized before calling this method.
|
1046
|
+
*/
|
1047
|
+
static VALUE
|
1048
|
+
header_rule(VALUE self, VALUE path, VALUE mime, VALUE key, VALUE value) {
|
1049
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
1050
|
+
|
1051
|
+
rb_check_type(path, T_STRING);
|
1052
|
+
rb_check_type(mime, T_STRING);
|
1053
|
+
rb_check_type(key, T_STRING);
|
1054
|
+
rb_check_type(value, T_STRING);
|
1055
|
+
|
1056
|
+
if (AGOO_ERR_OK != agoo_header_rule(&err, StringValuePtr(path), StringValuePtr(mime), StringValuePtr(key), StringValuePtr(value))) {
|
1057
|
+
rb_raise(rb_eArgError, "%s", err.msg);
|
1058
|
+
}
|
1059
|
+
return Qnil;
|
1060
|
+
}
|
1061
|
+
|
1022
1062
|
/* Document-class: Agoo::Server
|
1023
1063
|
*
|
1024
1064
|
* An HTTP server that support the rack API as well as some other optimized
|
@@ -1036,6 +1076,7 @@ server_init(VALUE mod) {
|
|
1036
1076
|
rb_define_module_function(server_mod, "handle_not_found", handle_not_found, 1);
|
1037
1077
|
rb_define_module_function(server_mod, "add_mime", add_mime, 2);
|
1038
1078
|
rb_define_module_function(server_mod, "path_group", path_group, 2);
|
1079
|
+
rb_define_module_function(server_mod, "header_rule", header_rule, 4);
|
1039
1080
|
|
1040
1081
|
call_id = rb_intern("call");
|
1041
1082
|
each_id = rb_intern("each");
|