agoo 2.5.5 → 2.5.6
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.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/ext/agoo/agoo.c +4 -3
- data/ext/agoo/atomic.h +120 -0
- data/ext/agoo/bind.c +52 -52
- data/ext/agoo/bind.h +13 -13
- data/ext/agoo/con.c +499 -481
- data/ext/agoo/con.h +47 -39
- data/ext/agoo/debug.c +42 -42
- data/ext/agoo/debug.h +1 -1
- data/ext/agoo/doc.c +17 -17
- data/ext/agoo/doc.h +12 -12
- data/ext/agoo/err.c +18 -18
- data/ext/agoo/err.h +27 -27
- data/ext/agoo/error_stream.c +9 -9
- data/ext/agoo/extconf.rb +3 -0
- data/ext/agoo/gqlintro.c +43 -43
- data/ext/agoo/gqlintro.h +1 -1
- data/ext/agoo/gqlvalue.c +131 -131
- data/ext/agoo/gqlvalue.h +32 -32
- data/ext/agoo/graphql.c +158 -158
- data/ext/agoo/graphql.h +34 -33
- data/ext/agoo/hook.c +15 -14
- data/ext/agoo/hook.h +18 -14
- data/ext/agoo/http.c +14 -14
- data/ext/agoo/http.h +4 -4
- data/ext/agoo/kinds.h +5 -5
- data/ext/agoo/log.c +232 -224
- data/ext/agoo/log.h +93 -93
- data/ext/agoo/method.h +17 -17
- data/ext/agoo/page.c +88 -86
- data/ext/agoo/page.h +21 -21
- data/ext/agoo/pub.c +36 -36
- data/ext/agoo/pub.h +23 -23
- data/ext/agoo/queue.c +37 -38
- data/ext/agoo/queue.h +20 -19
- data/ext/agoo/rack_logger.c +13 -13
- data/ext/agoo/ready.c +357 -0
- data/ext/agoo/ready.h +41 -0
- data/ext/agoo/req.c +11 -11
- data/ext/agoo/req.h +30 -31
- data/ext/agoo/request.c +46 -46
- data/ext/agoo/request.h +2 -2
- data/ext/agoo/res.c +40 -18
- data/ext/agoo/res.h +14 -14
- data/ext/agoo/response.c +6 -6
- data/ext/agoo/response.h +9 -9
- data/ext/agoo/rhook.c +3 -3
- data/ext/agoo/rhook.h +1 -1
- data/ext/agoo/rlog.c +47 -42
- data/ext/agoo/rlog.h +0 -1
- data/ext/agoo/rresponse.c +33 -33
- data/ext/agoo/rresponse.h +1 -1
- data/ext/agoo/rserver.c +184 -175
- data/ext/agoo/rserver.h +2 -2
- data/ext/agoo/rupgraded.c +41 -41
- data/ext/agoo/rupgraded.h +3 -3
- data/ext/agoo/sdl.c +80 -80
- data/ext/agoo/sdl.h +1 -1
- data/ext/agoo/seg.h +2 -2
- data/ext/agoo/server.c +143 -117
- data/ext/agoo/server.h +43 -42
- data/ext/agoo/sse.c +7 -7
- data/ext/agoo/sse.h +4 -4
- data/ext/agoo/subject.c +5 -5
- data/ext/agoo/subject.h +6 -6
- data/ext/agoo/text.c +21 -21
- data/ext/agoo/text.h +14 -13
- data/ext/agoo/upgraded.c +41 -40
- data/ext/agoo/upgraded.h +41 -40
- data/ext/agoo/websocket.c +42 -42
- data/ext/agoo/websocket.h +16 -16
- data/lib/agoo/version.rb +1 -1
- data/test/static_test.rb +2 -0
- metadata +5 -5
- data/ext/agoo/log_queue.h +0 -30
- data/ext/agoo/sub.c +0 -111
- data/ext/agoo/sub.h +0 -36
data/ext/agoo/rlog.h
CHANGED
data/ext/agoo/rresponse.c
CHANGED
@@ -12,8 +12,8 @@ static VALUE res_class = Qundef;
|
|
12
12
|
|
13
13
|
static void
|
14
14
|
response_free(void *ptr) {
|
15
|
-
|
16
|
-
|
15
|
+
agooResponse res = (agooResponse)ptr;
|
16
|
+
agooHeader h;
|
17
17
|
|
18
18
|
while (NULL != (h = res->headers)) {
|
19
19
|
res->headers = h->next;
|
@@ -28,10 +28,10 @@ response_free(void *ptr) {
|
|
28
28
|
|
29
29
|
VALUE
|
30
30
|
response_new( ) {
|
31
|
-
|
31
|
+
agooResponse res = ALLOC(struct _agooResponse);
|
32
32
|
|
33
33
|
DEBUG_ALLOC(mem_response, res)
|
34
|
-
memset(res, 0, sizeof(struct
|
34
|
+
memset(res, 0, sizeof(struct _agooResponse));
|
35
35
|
res->code = 200;
|
36
36
|
|
37
37
|
return Data_Wrap_Struct(res_class, NULL, response_free, res);
|
@@ -45,12 +45,12 @@ response_new( ) {
|
|
45
45
|
*/
|
46
46
|
static VALUE
|
47
47
|
to_s(VALUE self) {
|
48
|
-
|
49
|
-
int
|
50
|
-
char
|
48
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
49
|
+
int len = agoo_response_len(res);
|
50
|
+
char *s = ALLOC_N(char, len + 1);
|
51
51
|
|
52
52
|
DEBUG_ALLOC(mem_to_s, s)
|
53
|
-
|
53
|
+
agoo_response_fill(res, s);
|
54
54
|
|
55
55
|
return rb_str_new(s, len);
|
56
56
|
}
|
@@ -70,7 +70,7 @@ to_s(VALUE self) {
|
|
70
70
|
*/
|
71
71
|
static VALUE
|
72
72
|
body_get(VALUE self) {
|
73
|
-
|
73
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
74
74
|
|
75
75
|
if (NULL == res->body) {
|
76
76
|
return Qnil;
|
@@ -93,7 +93,7 @@ body_get(VALUE self) {
|
|
93
93
|
*/
|
94
94
|
static VALUE
|
95
95
|
body_set(VALUE self, VALUE val) {
|
96
|
-
|
96
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
97
97
|
|
98
98
|
if (T_STRING == rb_type(val)) {
|
99
99
|
res->body = strdup(StringValuePtr(val));
|
@@ -114,7 +114,7 @@ body_set(VALUE self, VALUE val) {
|
|
114
114
|
*/
|
115
115
|
static VALUE
|
116
116
|
code_get(VALUE self) {
|
117
|
-
return INT2NUM(((
|
117
|
+
return INT2NUM(((agooResponse)DATA_PTR(self))->code);
|
118
118
|
}
|
119
119
|
|
120
120
|
/* Document-method: code=
|
@@ -128,7 +128,7 @@ code_set(VALUE self, VALUE val) {
|
|
128
128
|
int code = NUM2INT(val);
|
129
129
|
|
130
130
|
if (100 <= code && code < 600) {
|
131
|
-
((
|
131
|
+
((agooResponse)DATA_PTR(self))->code = code;
|
132
132
|
} else {
|
133
133
|
rb_raise(rb_eArgError, "%d is not a valid HTTP status code.", code);
|
134
134
|
}
|
@@ -143,10 +143,10 @@ code_set(VALUE self, VALUE val) {
|
|
143
143
|
*/
|
144
144
|
static VALUE
|
145
145
|
head_get(VALUE self, VALUE key) {
|
146
|
-
|
147
|
-
|
148
|
-
const char
|
149
|
-
int
|
146
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
147
|
+
agooHeader h;
|
148
|
+
const char *ks = StringValuePtr(key);
|
149
|
+
int klen = (int)RSTRING_LEN(key);
|
150
150
|
|
151
151
|
for (h = res->headers; NULL != h; h = h->next) {
|
152
152
|
if (0 == strncasecmp(h->text, ks, klen) && klen + 1 < h->len && ':' == h->text[klen]) {
|
@@ -164,14 +164,14 @@ head_get(VALUE self, VALUE key) {
|
|
164
164
|
*/
|
165
165
|
static VALUE
|
166
166
|
head_set(VALUE self, VALUE key, VALUE val) {
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
const char
|
171
|
-
const char
|
172
|
-
int
|
173
|
-
int
|
174
|
-
int
|
167
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
168
|
+
agooHeader h;
|
169
|
+
agooHeader prev = NULL;
|
170
|
+
const char *ks = StringValuePtr(key);
|
171
|
+
const char *vs;
|
172
|
+
int klen = (int)RSTRING_LEN(key);
|
173
|
+
int vlen;
|
174
|
+
int hlen;
|
175
175
|
|
176
176
|
for (h = res->headers; NULL != h; h = h->next) {
|
177
177
|
if (0 == strncasecmp(h->text, ks, klen) && klen + 1 < h->len && ':' == h->text[klen]) {
|
@@ -192,15 +192,15 @@ head_set(VALUE self, VALUE key, VALUE val) {
|
|
192
192
|
vs = StringValuePtr(val);
|
193
193
|
vlen = (int)RSTRING_LEN(val);
|
194
194
|
|
195
|
-
if (
|
196
|
-
struct
|
195
|
+
if (agoo_server.pedantic) {
|
196
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
197
197
|
|
198
|
-
if (
|
198
|
+
if (AGOO_ERR_OK != agoo_http_header_ok(&err, ks, klen, vs, vlen)) {
|
199
199
|
rb_raise(rb_eArgError, "%s", err.msg);
|
200
200
|
}
|
201
201
|
}
|
202
202
|
hlen = klen + vlen + 4;
|
203
|
-
h = (
|
203
|
+
h = (agooHeader)ALLOC_N(char, sizeof(struct _agooHeader) - 8 + hlen + 1);
|
204
204
|
DEBUG_ALLOC(mem_header, h)
|
205
205
|
|
206
206
|
h->next = NULL;
|
@@ -219,13 +219,13 @@ head_set(VALUE self, VALUE key, VALUE val) {
|
|
219
219
|
return Qnil;
|
220
220
|
}
|
221
221
|
|
222
|
-
|
222
|
+
agooText
|
223
223
|
response_text(VALUE self) {
|
224
|
-
|
225
|
-
int
|
226
|
-
|
224
|
+
agooResponse res = (agooResponse)DATA_PTR(self);
|
225
|
+
int len = agoo_response_len(res);
|
226
|
+
agooText t = agoo_text_allocate(len);
|
227
227
|
|
228
|
-
|
228
|
+
agoo_response_fill(res, t->text);
|
229
229
|
t->len = len;
|
230
230
|
|
231
231
|
return t;
|
data/ext/agoo/rresponse.h
CHANGED
data/ext/agoo/rserver.c
CHANGED
@@ -29,7 +29,6 @@
|
|
29
29
|
#include "rupgraded.h"
|
30
30
|
#include "server.h"
|
31
31
|
#include "sse.h"
|
32
|
-
#include "sub.h"
|
33
32
|
#include "upgraded.h"
|
34
33
|
#include "websocket.h"
|
35
34
|
|
@@ -59,15 +58,15 @@ static ID to_i_id;
|
|
59
58
|
|
60
59
|
static const char err500[] = "HTTP/1.1 500 Internal Server Error\r\n";
|
61
60
|
|
62
|
-
struct
|
61
|
+
struct _rServer the_rserver = {};
|
63
62
|
|
64
63
|
static void
|
65
64
|
server_mark(void *ptr) {
|
66
|
-
|
65
|
+
agooUpgraded up;
|
67
66
|
|
68
67
|
rb_gc_mark(rserver);
|
69
|
-
pthread_mutex_lock(&
|
70
|
-
for (up =
|
68
|
+
pthread_mutex_lock(&agoo_server.up_lock);
|
69
|
+
for (up = agoo_server.up_list; NULL != up; up = up->next) {
|
71
70
|
if (Qnil != (VALUE)up->ctx) {
|
72
71
|
rb_gc_mark((VALUE)up->ctx);
|
73
72
|
}
|
@@ -78,30 +77,30 @@ server_mark(void *ptr) {
|
|
78
77
|
rb_gc_mark((VALUE)up->wrap);
|
79
78
|
}
|
80
79
|
}
|
81
|
-
pthread_mutex_unlock(&
|
80
|
+
pthread_mutex_unlock(&agoo_server.up_lock);
|
82
81
|
}
|
83
82
|
|
84
83
|
static void
|
85
84
|
url_bind(VALUE rurl) {
|
86
|
-
struct
|
87
|
-
|
85
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
86
|
+
agooBind b = agoo_bind_url(&err, StringValuePtr(rurl));
|
88
87
|
|
89
|
-
if (
|
88
|
+
if (AGOO_ERR_OK != err.code) {
|
90
89
|
rb_raise(rb_eArgError, "%s", err.msg);
|
91
90
|
}
|
92
|
-
|
91
|
+
agoo_server_bind(b);
|
93
92
|
}
|
94
93
|
|
95
94
|
static int
|
96
|
-
configure(
|
97
|
-
|
98
|
-
|
95
|
+
configure(agooErr err, int port, const char *root, VALUE options) {
|
96
|
+
agoo_pages_set_root(root);
|
97
|
+
agoo_server.thread_cnt = 0;
|
99
98
|
the_rserver.worker_cnt = 1;
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
99
|
+
atomic_init(&agoo_server.running, 0);
|
100
|
+
agoo_server.listen_thread = 0;
|
101
|
+
agoo_server.con_loops = NULL;
|
102
|
+
agoo_server.root_first = false;
|
103
|
+
agoo_server.binds = NULL;
|
105
104
|
|
106
105
|
if (Qnil != options) {
|
107
106
|
VALUE v;
|
@@ -110,7 +109,7 @@ configure(Err err, int port, const char *root, VALUE options) {
|
|
110
109
|
int tc = FIX2INT(v);
|
111
110
|
|
112
111
|
if (1 <= tc || tc < 1000) {
|
113
|
-
|
112
|
+
agoo_server.thread_cnt = tc;
|
114
113
|
} else {
|
115
114
|
rb_raise(rb_eArgError, "thread_count must be between 1 and 1000.");
|
116
115
|
}
|
@@ -128,16 +127,16 @@ configure(Err err, int port, const char *root, VALUE options) {
|
|
128
127
|
int mpp = FIX2INT(v);
|
129
128
|
|
130
129
|
if (0 <= mpp || mpp < 1000) {
|
131
|
-
|
130
|
+
agoo_server.max_push_pending = mpp;
|
132
131
|
} else {
|
133
132
|
rb_raise(rb_eArgError, "max_push_pending must be between 0 and 1000.");
|
134
133
|
}
|
135
134
|
}
|
136
135
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("pedantic"))))) {
|
137
|
-
|
136
|
+
agoo_server.pedantic = (Qtrue == v);
|
138
137
|
}
|
139
138
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("root_first"))))) {
|
140
|
-
|
139
|
+
agoo_server.root_first = (Qtrue == v);
|
141
140
|
}
|
142
141
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("Port"))))) {
|
143
142
|
if (rb_cInteger == rb_obj_class(v)) {
|
@@ -176,12 +175,12 @@ configure(Err err, int port, const char *root, VALUE options) {
|
|
176
175
|
}
|
177
176
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("graphql"))))) {
|
178
177
|
const char *path;
|
179
|
-
|
178
|
+
agooHook hook;
|
180
179
|
char schema_path[256];
|
181
180
|
long plen;
|
182
181
|
|
183
182
|
rb_check_type(v, T_STRING);
|
184
|
-
if (
|
183
|
+
if (AGOO_ERR_OK != gql_init(err)) {
|
185
184
|
return err->code;
|
186
185
|
}
|
187
186
|
path = StringValuePtr(v);
|
@@ -192,42 +191,42 @@ configure(Err err, int port, const char *root, VALUE options) {
|
|
192
191
|
memcpy(schema_path, path, plen);
|
193
192
|
memcpy(schema_path + plen, "/schema", 8);
|
194
193
|
|
195
|
-
hook =
|
196
|
-
hook->next =
|
197
|
-
|
194
|
+
hook = agoo_hook_func_create(AGOO_GET, schema_path, gql_dump_hook, &agoo_server.eval_queue);
|
195
|
+
hook->next = agoo_server.hooks;
|
196
|
+
agoo_server.hooks = hook;
|
198
197
|
|
199
|
-
hook =
|
200
|
-
hook->next =
|
201
|
-
|
198
|
+
hook = agoo_hook_func_create(AGOO_GET, path, gql_eval_hook, &agoo_server.eval_queue);
|
199
|
+
hook->next = agoo_server.hooks;
|
200
|
+
agoo_server.hooks = hook;
|
202
201
|
}
|
203
202
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("quiet"))))) {
|
204
203
|
if (Qtrue == v) {
|
205
|
-
|
204
|
+
agoo_info_cat.on = false;
|
206
205
|
}
|
207
206
|
}
|
208
207
|
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("debug"))))) {
|
209
208
|
if (Qtrue == v) {
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
209
|
+
agoo_error_cat.on = true;
|
210
|
+
agoo_warn_cat.on = true;
|
211
|
+
agoo_info_cat.on = true;
|
212
|
+
agoo_debug_cat.on = true;
|
213
|
+
agoo_con_cat.on = true;
|
214
|
+
agoo_req_cat.on = true;
|
215
|
+
agoo_resp_cat.on = true;
|
216
|
+
agoo_eval_cat.on = true;
|
217
|
+
agoo_push_cat.on = true;
|
219
218
|
}
|
220
219
|
}
|
221
220
|
}
|
222
221
|
if (0 < port) {
|
223
|
-
|
222
|
+
agooBind b = agoo_bind_port(err, port);
|
224
223
|
|
225
|
-
if (
|
224
|
+
if (AGOO_ERR_OK != err->code) {
|
226
225
|
rb_raise(rb_eArgError, "%s", err->msg);
|
227
226
|
}
|
228
|
-
|
227
|
+
agoo_server_bind(b);
|
229
228
|
}
|
230
|
-
return
|
229
|
+
return AGOO_ERR_OK;
|
231
230
|
}
|
232
231
|
|
233
232
|
/* Document-method: init
|
@@ -247,14 +246,14 @@ configure(Err err, int port, const char *root, VALUE options) {
|
|
247
246
|
*
|
248
247
|
* - *:worker_count* [_Integer_] number of workers to fork. Defaults to one which is not to fork.
|
249
248
|
*
|
250
|
-
* - *: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".
|
249
|
+
* - *: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".
|
251
250
|
*/
|
252
251
|
static VALUE
|
253
252
|
rserver_init(int argc, VALUE *argv, VALUE self) {
|
254
|
-
struct
|
255
|
-
int
|
256
|
-
const char
|
257
|
-
VALUE
|
253
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
254
|
+
int port;
|
255
|
+
const char *root;
|
256
|
+
VALUE options = Qnil;
|
258
257
|
|
259
258
|
if (argc < 2 || 3 < argc) {
|
260
259
|
rb_raise(rb_eArgError, "Wrong number of arguments to Agoo::Server.configure.");
|
@@ -265,14 +264,14 @@ rserver_init(int argc, VALUE *argv, VALUE self) {
|
|
265
264
|
if (3 <= argc) {
|
266
265
|
options = argv[2];
|
267
266
|
}
|
268
|
-
|
269
|
-
|
270
|
-
|
267
|
+
agoo_server_setup();
|
268
|
+
agoo_server.ctx_nil_value = (void*)Qnil;
|
269
|
+
agoo_server.env_nil_value = (void*)Qnil;
|
271
270
|
|
272
|
-
if (
|
271
|
+
if (AGOO_ERR_OK != configure(&err, port, root, options)) {
|
273
272
|
rb_raise(rb_eArgError, "%s", err.msg);
|
274
273
|
}
|
275
|
-
|
274
|
+
agoo_server.inited = true;
|
276
275
|
|
277
276
|
return Qnil;
|
278
277
|
}
|
@@ -281,7 +280,7 @@ static const char bad500[] = "HTTP/1.1 500 Internal Error\r\nConnection: Close\r
|
|
281
280
|
|
282
281
|
static VALUE
|
283
282
|
rescue_error(VALUE x) {
|
284
|
-
|
283
|
+
agooReq req = (agooReq)x;
|
285
284
|
volatile VALUE info = rb_errinfo();
|
286
285
|
volatile VALUE msg = rb_funcall(info, rb_intern("message"), 0);
|
287
286
|
const char *classname = rb_obj_classname(info);
|
@@ -291,17 +290,17 @@ rescue_error(VALUE x) {
|
|
291
290
|
char buf[1024];
|
292
291
|
int len = (int)(strlen(classname) + 2 + strlen(ms));
|
293
292
|
int cnt;
|
294
|
-
|
293
|
+
agooText message;
|
295
294
|
|
296
295
|
if ((int)(sizeof(buf) - sizeof(bad500) + 7) <= len) {
|
297
296
|
len = sizeof(buf) - sizeof(bad500) + 7;
|
298
297
|
}
|
299
298
|
cnt = snprintf(buf, sizeof(buf), "%s%d\r\n\r\n%s: %s", bad500, len, classname, ms);
|
300
|
-
message =
|
299
|
+
message = agoo_text_create(buf, cnt);
|
301
300
|
|
302
301
|
req->res->close = true;
|
303
|
-
|
304
|
-
|
302
|
+
agoo_res_set_message(req->res, message);
|
303
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
305
304
|
} else {
|
306
305
|
/*
|
307
306
|
volatile VALUE bt = rb_funcall(info, rb_intern("backtrace"), 0);
|
@@ -313,14 +312,14 @@ rescue_error(VALUE x) {
|
|
313
312
|
rline = rb_ary_entry(bt, i);
|
314
313
|
}
|
315
314
|
*/
|
316
|
-
|
315
|
+
agoo_log_cat(&agoo_error_cat, "%s: %s", classname, ms);
|
317
316
|
}
|
318
317
|
return Qfalse;
|
319
318
|
}
|
320
319
|
|
321
320
|
static VALUE
|
322
321
|
handle_base_inner(void *x) {
|
323
|
-
|
322
|
+
agooReq req = (agooReq)x;
|
324
323
|
volatile VALUE rr = request_wrap(req);
|
325
324
|
volatile VALUE rres = response_new();
|
326
325
|
|
@@ -328,8 +327,8 @@ handle_base_inner(void *x) {
|
|
328
327
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
329
328
|
}
|
330
329
|
DATA_PTR(rr) = NULL;
|
331
|
-
|
332
|
-
|
330
|
+
agoo_res_set_message(req->res, response_text(rres));
|
331
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
333
332
|
|
334
333
|
return Qfalse;
|
335
334
|
}
|
@@ -342,29 +341,29 @@ handle_base(void *x) {
|
|
342
341
|
}
|
343
342
|
|
344
343
|
static int
|
345
|
-
header_cb(VALUE key, VALUE value,
|
346
|
-
const char
|
347
|
-
int
|
348
|
-
const char
|
349
|
-
int
|
350
|
-
struct
|
344
|
+
header_cb(VALUE key, VALUE value, agooText *tp) {
|
345
|
+
const char *ks = StringValuePtr(key);
|
346
|
+
int klen = (int)RSTRING_LEN(key);
|
347
|
+
const char *vs = StringValuePtr(value);
|
348
|
+
int vlen = (int)RSTRING_LEN(value);
|
349
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
351
350
|
|
352
|
-
if (
|
353
|
-
if (
|
351
|
+
if (agoo_server.pedantic) {
|
352
|
+
if (AGOO_ERR_OK != agoo_http_header_ok(&err, ks, klen, vs, vlen)) {
|
354
353
|
rb_raise(rb_eArgError, "%s", err.msg);
|
355
354
|
}
|
356
355
|
}
|
357
356
|
if (0 != strcasecmp("Content-Length", ks)) {
|
358
|
-
*tp =
|
359
|
-
*tp =
|
360
|
-
*tp =
|
361
|
-
*tp =
|
357
|
+
*tp = agoo_text_append(*tp, ks, klen);
|
358
|
+
*tp = agoo_text_append(*tp, ": ", 2);
|
359
|
+
*tp = agoo_text_append(*tp, vs, vlen);
|
360
|
+
*tp = agoo_text_append(*tp, "\r\n", 2);
|
362
361
|
}
|
363
362
|
return ST_CONTINUE;
|
364
363
|
}
|
365
364
|
|
366
365
|
static VALUE
|
367
|
-
header_each_cb(VALUE kv,
|
366
|
+
header_each_cb(VALUE kv, agooText *tp) {
|
368
367
|
header_cb(rb_ary_entry(kv, 0), rb_ary_entry(kv, 1), tp);
|
369
368
|
|
370
369
|
return Qnil;
|
@@ -378,16 +377,16 @@ body_len_cb(VALUE v, int *sizep) {
|
|
378
377
|
}
|
379
378
|
|
380
379
|
static VALUE
|
381
|
-
body_append_cb(VALUE v,
|
382
|
-
*tp =
|
380
|
+
body_append_cb(VALUE v, agooText *tp) {
|
381
|
+
*tp = agoo_text_append(*tp, StringValuePtr(v), (int)RSTRING_LEN(v));
|
383
382
|
|
384
383
|
return Qnil;
|
385
384
|
}
|
386
385
|
|
387
386
|
static VALUE
|
388
387
|
handle_rack_inner(void *x) {
|
389
|
-
|
390
|
-
|
388
|
+
agooReq req = (agooReq)x;
|
389
|
+
agooText t;
|
391
390
|
volatile VALUE env = request_env(req, request_wrap(req));
|
392
391
|
volatile VALUE res = Qnil;
|
393
392
|
volatile VALUE hv;
|
@@ -401,7 +400,7 @@ handle_rack_inner(void *x) {
|
|
401
400
|
}
|
402
401
|
res = rb_funcall((VALUE)req->hook->handler, call_id, 1, env);
|
403
402
|
if (req->res->con->hijacked) {
|
404
|
-
|
403
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
405
404
|
return Qfalse;
|
406
405
|
}
|
407
406
|
rb_check_type(res, T_ARRAY);
|
@@ -414,7 +413,7 @@ handle_rack_inner(void *x) {
|
|
414
413
|
} else {
|
415
414
|
code = NUM2INT(rb_funcall(hv, to_i_id, 0));
|
416
415
|
}
|
417
|
-
status_msg =
|
416
|
+
status_msg = agoo_http_code_message(code);
|
418
417
|
if ('\0' == *status_msg) {
|
419
418
|
rb_raise(rb_eArgError, "invalid rack call() response status code (%d).", code);
|
420
419
|
}
|
@@ -426,7 +425,7 @@ handle_rack_inner(void *x) {
|
|
426
425
|
if (!rb_respond_to(bv, each_id)) {
|
427
426
|
rb_raise(rb_eArgError, "invalid rack call() response body does not respond to each.");
|
428
427
|
}
|
429
|
-
if (NULL == (t =
|
428
|
+
if (NULL == (t = agoo_text_allocate(1024))) {
|
430
429
|
rb_raise(rb_eArgError, "failed to allocate response.");
|
431
430
|
}
|
432
431
|
if (T_ARRAY == rb_type(bv)) {
|
@@ -437,7 +436,7 @@ handle_rack_inner(void *x) {
|
|
437
436
|
bsize += (int)RSTRING_LEN(rb_ary_entry(bv, i));
|
438
437
|
}
|
439
438
|
} else {
|
440
|
-
if (
|
439
|
+
if (AGOO_HEAD == req->method) {
|
441
440
|
// Rack wraps the response in two layers, Rack::Lint and
|
442
441
|
// Rack::BodyProxy. It each is called on either with the HEAD
|
443
442
|
// method an exception is raised so the length can not be
|
@@ -481,37 +480,37 @@ handle_rack_inner(void *x) {
|
|
481
480
|
VALUE handler = Qnil;
|
482
481
|
|
483
482
|
switch (req->upgrade) {
|
484
|
-
case
|
485
|
-
if (
|
483
|
+
case AGOO_UP_WS:
|
484
|
+
if (AGOO_CON_WS != req->res->con_kind ||
|
486
485
|
Qnil == (handler = rb_hash_lookup(env, push_env_key))) {
|
487
486
|
strcpy(t->text, err500);
|
488
487
|
t->len = sizeof(err500) - 1;
|
489
488
|
break;
|
490
489
|
}
|
491
|
-
req->hook =
|
490
|
+
req->hook = agoo_hook_create(AGOO_NONE, NULL, (void*)handler, PUSH_HOOK, &agoo_server.eval_queue);
|
492
491
|
rupgraded_create(req->res->con, handler, request_env(req, Qnil));
|
493
492
|
|
494
493
|
t->len = snprintf(t->text, 1024, "HTTP/1.1 101 %s\r\n", status_msg);
|
495
|
-
t =
|
494
|
+
t = agoo_ws_add_headers(req, t);
|
496
495
|
break;
|
497
|
-
case
|
498
|
-
if (
|
496
|
+
case AGOO_UP_SSE:
|
497
|
+
if (AGOO_CON_SSE != req->res->con_kind ||
|
499
498
|
Qnil == (handler = rb_hash_lookup(env, push_env_key))) {
|
500
499
|
strcpy(t->text, err500);
|
501
500
|
t->len = sizeof(err500) - 1;
|
502
501
|
break;
|
503
502
|
}
|
504
|
-
req->hook =
|
503
|
+
req->hook = agoo_hook_create(AGOO_NONE, NULL, (void*)handler, PUSH_HOOK, &agoo_server.eval_queue);
|
505
504
|
rupgraded_create(req->res->con, handler, request_env(req, Qnil));
|
506
|
-
t =
|
507
|
-
|
508
|
-
|
505
|
+
t = agoo_sse_upgrade(req, t);
|
506
|
+
agoo_res_set_message(req->res, t);
|
507
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
509
508
|
return Qfalse;
|
510
509
|
default:
|
511
510
|
break;
|
512
511
|
}
|
513
512
|
}
|
514
|
-
if (
|
513
|
+
if (AGOO_HEAD == req->method) {
|
515
514
|
bsize = 0;
|
516
515
|
} else {
|
517
516
|
if (T_HASH == rb_type(hv)) {
|
@@ -520,7 +519,7 @@ handle_rack_inner(void *x) {
|
|
520
519
|
rb_iterate(rb_each, hv, header_each_cb, (VALUE)&t);
|
521
520
|
}
|
522
521
|
}
|
523
|
-
t =
|
522
|
+
t = agoo_text_append(t, "\r\n", 2);
|
524
523
|
if (0 < bsize) {
|
525
524
|
if (T_ARRAY == rb_type(bv)) {
|
526
525
|
VALUE v;
|
@@ -529,14 +528,14 @@ handle_rack_inner(void *x) {
|
|
529
528
|
|
530
529
|
for (i = 0; i < bcnt; i++) {
|
531
530
|
v = rb_ary_entry(bv, i);
|
532
|
-
t =
|
531
|
+
t = agoo_text_append(t, StringValuePtr(v), (int)RSTRING_LEN(v));
|
533
532
|
}
|
534
533
|
} else {
|
535
534
|
rb_iterate(rb_each, bv, body_append_cb, (VALUE)&t);
|
536
535
|
}
|
537
536
|
}
|
538
|
-
|
539
|
-
|
537
|
+
agoo_res_set_message(req->res, t);
|
538
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
540
539
|
|
541
540
|
return Qfalse;
|
542
541
|
}
|
@@ -553,7 +552,7 @@ handle_rack(void *x) {
|
|
553
552
|
|
554
553
|
static VALUE
|
555
554
|
handle_wab_inner(void *x) {
|
556
|
-
|
555
|
+
agooReq req = (agooReq)x;
|
557
556
|
volatile VALUE rr = request_wrap(req);
|
558
557
|
volatile VALUE rres = response_new();
|
559
558
|
|
@@ -561,8 +560,8 @@ handle_wab_inner(void *x) {
|
|
561
560
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
562
561
|
}
|
563
562
|
DATA_PTR(rr) = NULL;
|
564
|
-
|
565
|
-
|
563
|
+
agoo_res_set_message(req->res, response_text(rres));
|
564
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
566
565
|
|
567
566
|
return Qfalse;
|
568
567
|
}
|
@@ -576,15 +575,15 @@ handle_wab(void *x) {
|
|
576
575
|
|
577
576
|
static VALUE
|
578
577
|
handle_push_inner(void *x) {
|
579
|
-
|
578
|
+
agooReq req = (agooReq)x;
|
580
579
|
|
581
580
|
switch (req->method) {
|
582
|
-
case
|
581
|
+
case AGOO_ON_MSG:
|
583
582
|
if (req->up->on_msg && NULL != req->hook) {
|
584
583
|
rb_funcall((VALUE)req->hook->handler, on_message_id, 2, (VALUE)req->up->wrap, rb_str_new(req->msg, req->mlen));
|
585
584
|
}
|
586
585
|
break;
|
587
|
-
case
|
586
|
+
case AGOO_ON_BIN:
|
588
587
|
if (req->up->on_msg && NULL != req->hook) {
|
589
588
|
volatile VALUE rstr = rb_str_new(req->msg, req->mlen);
|
590
589
|
|
@@ -592,19 +591,19 @@ handle_push_inner(void *x) {
|
|
592
591
|
rb_funcall((VALUE)req->hook->handler, on_message_id, 2, (VALUE)req->up->wrap, rstr);
|
593
592
|
}
|
594
593
|
break;
|
595
|
-
case
|
596
|
-
|
597
|
-
|
594
|
+
case AGOO_ON_CLOSE:
|
595
|
+
agoo_upgraded_ref(req->up);
|
596
|
+
agoo_server_publish(agoo_pub_close(req->up));
|
598
597
|
if (req->up->on_close && NULL != req->hook) {
|
599
598
|
rb_funcall((VALUE)req->hook->handler, on_close_id, 1, (VALUE)req->up->wrap);
|
600
599
|
}
|
601
600
|
break;
|
602
|
-
case
|
601
|
+
case AGOO_ON_SHUTDOWN:
|
603
602
|
if (NULL != req->hook) {
|
604
603
|
rb_funcall((VALUE)req->hook->handler, rb_intern("on_shutdown"), 1, (VALUE)req->up->wrap);
|
605
604
|
}
|
606
605
|
break;
|
607
|
-
case
|
606
|
+
case AGOO_ON_ERROR:
|
608
607
|
if (req->up->on_error && NULL != req->hook) {
|
609
608
|
volatile VALUE rstr = rb_str_new(req->msg, req->mlen);
|
610
609
|
|
@@ -612,7 +611,7 @@ handle_push_inner(void *x) {
|
|
612
611
|
rb_funcall((VALUE)req->hook->handler, on_error_id, 2, (VALUE)req->up->wrap, rstr);
|
613
612
|
}
|
614
613
|
break;
|
615
|
-
case
|
614
|
+
case AGOO_ON_EMPTY:
|
616
615
|
if (req->up->on_empty && NULL != req->hook) {
|
617
616
|
rb_funcall((VALUE)req->hook->handler, on_drained_id, 1, (VALUE)req->up->wrap);
|
618
617
|
}
|
@@ -620,7 +619,7 @@ handle_push_inner(void *x) {
|
|
620
619
|
default:
|
621
620
|
break;
|
622
621
|
}
|
623
|
-
|
622
|
+
agoo_upgraded_release(req->up);
|
624
623
|
|
625
624
|
return Qfalse;
|
626
625
|
}
|
@@ -632,7 +631,7 @@ handle_push(void *x) {
|
|
632
631
|
}
|
633
632
|
|
634
633
|
static void
|
635
|
-
handle_protected(
|
634
|
+
handle_protected(agooReq req, bool gvi) {
|
636
635
|
if (NULL == req->hook) {
|
637
636
|
return;
|
638
637
|
}
|
@@ -667,16 +666,16 @@ handle_protected(Req req, bool gvi) {
|
|
667
666
|
break;
|
668
667
|
case FUNC_HOOK:
|
669
668
|
req->hook->func(req);
|
670
|
-
|
669
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
671
670
|
break;
|
672
671
|
default: {
|
673
672
|
char buf[256];
|
674
673
|
int cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 500 Internal Error\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n");
|
675
|
-
|
674
|
+
agooText message = agoo_text_create(buf, cnt);
|
676
675
|
|
677
676
|
req->res->close = true;
|
678
|
-
|
679
|
-
|
677
|
+
agoo_res_set_message(req->res, message);
|
678
|
+
agoo_queue_wakeup(&agoo_server.con_queue);
|
680
679
|
break;
|
681
680
|
}
|
682
681
|
}
|
@@ -684,16 +683,16 @@ handle_protected(Req req, bool gvi) {
|
|
684
683
|
|
685
684
|
static void*
|
686
685
|
process_loop(void *ptr) {
|
687
|
-
|
686
|
+
agooReq req;
|
688
687
|
|
689
|
-
atomic_fetch_add(&
|
690
|
-
while (
|
691
|
-
if (NULL != (req = (
|
688
|
+
atomic_fetch_add(&agoo_server.running, 1);
|
689
|
+
while (agoo_server.active) {
|
690
|
+
if (NULL != (req = (agooReq)agoo_queue_pop(&agoo_server.eval_queue, 0.1))) {
|
692
691
|
handle_protected(req, true);
|
693
|
-
|
692
|
+
agoo_req_destroy(req);
|
694
693
|
}
|
695
694
|
}
|
696
|
-
atomic_fetch_sub(&
|
695
|
+
atomic_fetch_sub(&agoo_server.running, 1);
|
697
696
|
|
698
697
|
return NULL;
|
699
698
|
}
|
@@ -712,17 +711,25 @@ wrap_process_loop(void *ptr) {
|
|
712
711
|
*/
|
713
712
|
static VALUE
|
714
713
|
rserver_start(VALUE self) {
|
715
|
-
VALUE
|
716
|
-
int
|
717
|
-
int
|
718
|
-
double
|
719
|
-
struct
|
720
|
-
VALUE
|
721
|
-
VALUE
|
714
|
+
VALUE *vp;
|
715
|
+
int i;
|
716
|
+
int pid;
|
717
|
+
double giveup;
|
718
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
719
|
+
VALUE agoo = rb_const_get_at(rb_cObject, rb_intern("Agoo"));
|
720
|
+
VALUE v = rb_const_get_at(agoo, rb_intern("VERSION"));
|
722
721
|
|
723
722
|
*the_rserver.worker_pids = getpid();
|
724
|
-
|
725
|
-
|
723
|
+
|
724
|
+
// If workers then set the loop_max based on the expected number of
|
725
|
+
// threads per worker.
|
726
|
+
if (1 < the_rserver.worker_cnt) {
|
727
|
+
agoo_server.loop_max /= the_rserver.worker_cnt;
|
728
|
+
if (agoo_server.loop_max < 1) {
|
729
|
+
agoo_server.loop_max = 1;
|
730
|
+
}
|
731
|
+
}
|
732
|
+
if (AGOO_ERR_OK != setup_listen(&err)) {
|
726
733
|
rb_raise(rb_eIOError, "%s", err.msg);
|
727
734
|
}
|
728
735
|
for (i = 1; i < the_rserver.worker_cnt; i++) {
|
@@ -734,35 +741,37 @@ rserver_start(VALUE self) {
|
|
734
741
|
pid = NUM2INT(rpid);
|
735
742
|
}
|
736
743
|
if (0 > pid) { // error, use single process
|
737
|
-
|
744
|
+
agoo_log_cat(&agoo_error_cat, "Failed to fork. %s.", strerror(errno));
|
738
745
|
break;
|
739
746
|
} else if (0 == pid) {
|
740
|
-
|
747
|
+
if (AGOO_ERR_OK != agoo_log_start(&err, true)) {
|
748
|
+
rb_raise(rb_eStandardError, "%s", err.msg);
|
749
|
+
}
|
741
750
|
break;
|
742
751
|
} else {
|
743
752
|
the_rserver.worker_pids[i] = pid;
|
744
753
|
}
|
745
754
|
}
|
746
|
-
if (
|
755
|
+
if (AGOO_ERR_OK != agoo_server_start(&err, "Agoo", StringValuePtr(v))) {
|
747
756
|
rb_raise(rb_eStandardError, "%s", err.msg);
|
748
757
|
}
|
749
|
-
if (0 >=
|
750
|
-
|
758
|
+
if (0 >= agoo_server.thread_cnt) {
|
759
|
+
agooReq req;
|
751
760
|
|
752
|
-
while (
|
753
|
-
if (NULL != (req = (
|
761
|
+
while (agoo_server.active) {
|
762
|
+
if (NULL != (req = (agooReq)agoo_queue_pop(&agoo_server.eval_queue, 0.1))) {
|
754
763
|
handle_protected(req, false);
|
755
|
-
|
764
|
+
agoo_req_destroy(req);
|
756
765
|
} else {
|
757
766
|
rb_thread_schedule();
|
758
767
|
}
|
759
768
|
|
760
769
|
}
|
761
770
|
} else {
|
762
|
-
the_rserver.eval_threads = (VALUE*)malloc(sizeof(VALUE) * (
|
763
|
-
DEBUG_ALLOC(mem_eval_threads,
|
771
|
+
the_rserver.eval_threads = (VALUE*)malloc(sizeof(VALUE) * (agoo_server.thread_cnt + 1));
|
772
|
+
DEBUG_ALLOC(mem_eval_threads, agoo_server.eval_threads);
|
764
773
|
|
765
|
-
for (i =
|
774
|
+
for (i = agoo_server.thread_cnt, vp = the_rserver.eval_threads; 0 < i; i--, vp++) {
|
766
775
|
*vp = rb_thread_create(wrap_process_loop, NULL);
|
767
776
|
}
|
768
777
|
*vp = Qnil;
|
@@ -773,7 +782,7 @@ rserver_start(VALUE self) {
|
|
773
782
|
// releases ownership so do that and then see if the threads has
|
774
783
|
// been started yet.
|
775
784
|
rb_thread_schedule();
|
776
|
-
if (2 +
|
785
|
+
if (2 + agoo_server.thread_cnt <= (long)atomic_load(&agoo_server.running)) {
|
777
786
|
break;
|
778
787
|
}
|
779
788
|
}
|
@@ -791,7 +800,7 @@ stop_runners() {
|
|
791
800
|
double timeout = dtime() + 2.0;
|
792
801
|
|
793
802
|
while (dtime() < timeout) {
|
794
|
-
if (0 >= atomic_load(&
|
803
|
+
if (0 >= (long)atomic_load(&agoo_server.running)) {
|
795
804
|
break;
|
796
805
|
}
|
797
806
|
dsleep(0.02);
|
@@ -810,8 +819,8 @@ stop_runners() {
|
|
810
819
|
*/
|
811
820
|
VALUE
|
812
821
|
rserver_shutdown(VALUE self) {
|
813
|
-
if (
|
814
|
-
|
822
|
+
if (agoo_server.inited) {
|
823
|
+
agoo_server_shutdown("Agoo", stop_runners);
|
815
824
|
|
816
825
|
if (1 < the_rserver.worker_cnt && getpid() == *the_rserver.worker_pids) {
|
817
826
|
int i;
|
@@ -829,11 +838,11 @@ rserver_shutdown(VALUE self) {
|
|
829
838
|
}
|
830
839
|
if (0 < waitpid(the_rserver.worker_pids[i], &status, WNOHANG)) {
|
831
840
|
if (WIFEXITED(status)) {
|
832
|
-
//printf("exited, status=%d for %d\n",
|
841
|
+
//printf("exited, status=%d for %d\n", agoo_server.worker_pids[i], WEXITSTATUS(status));
|
833
842
|
the_rserver.worker_pids[i] = 0;
|
834
843
|
exit_cnt++;
|
835
844
|
} else if (WIFSIGNALED(status)) {
|
836
|
-
//printf("*** killed by signal %d for %d\n",
|
845
|
+
//printf("*** killed by signal %d for %d\n", agoo_server.worker_pids[i], WTERMSIG(status));
|
837
846
|
the_rserver.worker_pids[i] = 0;
|
838
847
|
exit_cnt++;
|
839
848
|
}
|
@@ -862,8 +871,8 @@ rserver_shutdown(VALUE self) {
|
|
862
871
|
*/
|
863
872
|
static VALUE
|
864
873
|
handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
865
|
-
|
866
|
-
|
874
|
+
agooHook hook;
|
875
|
+
agooMethod meth = AGOO_ALL;
|
867
876
|
const char *pat;
|
868
877
|
ID static_id = rb_intern("static?");
|
869
878
|
|
@@ -871,21 +880,21 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
|
871
880
|
pat = StringValuePtr(pattern);
|
872
881
|
|
873
882
|
if (connect_sym == method) {
|
874
|
-
meth =
|
883
|
+
meth = AGOO_CONNECT;
|
875
884
|
} else if (delete_sym == method) {
|
876
|
-
meth =
|
885
|
+
meth = AGOO_DELETE;
|
877
886
|
} else if (get_sym == method) {
|
878
|
-
meth =
|
887
|
+
meth = AGOO_GET;
|
879
888
|
} else if (head_sym == method) {
|
880
|
-
meth =
|
889
|
+
meth = AGOO_HEAD;
|
881
890
|
} else if (options_sym == method) {
|
882
|
-
meth =
|
891
|
+
meth = AGOO_OPTIONS;
|
883
892
|
} else if (post_sym == method) {
|
884
|
-
meth =
|
893
|
+
meth = AGOO_POST;
|
885
894
|
} else if (put_sym == method) {
|
886
|
-
meth =
|
895
|
+
meth = AGOO_PUT;
|
887
896
|
} else if (Qnil == method) {
|
888
|
-
meth =
|
897
|
+
meth = AGOO_ALL;
|
889
898
|
} else {
|
890
899
|
rb_raise(rb_eArgError, "invalid method");
|
891
900
|
}
|
@@ -905,8 +914,8 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
|
905
914
|
if (T_ARRAY == rb_type(bv)) {
|
906
915
|
int i;
|
907
916
|
int bcnt = (int)RARRAY_LEN(bv);
|
908
|
-
|
909
|
-
struct
|
917
|
+
agooText t = agoo_text_allocate(1024);
|
918
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
910
919
|
VALUE v;
|
911
920
|
|
912
921
|
if (NULL == t) {
|
@@ -914,30 +923,30 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
|
914
923
|
}
|
915
924
|
for (i = 0; i < bcnt; i++) {
|
916
925
|
v = rb_ary_entry(bv, i);
|
917
|
-
t =
|
926
|
+
t = agoo_text_append(t, StringValuePtr(v), (int)RSTRING_LEN(v));
|
918
927
|
}
|
919
|
-
if (NULL ==
|
928
|
+
if (NULL == agoo_page_immutable(&err, pat, t->text, t->len)) {
|
920
929
|
rb_raise(rb_eArgError, "%s", err.msg);
|
921
930
|
}
|
922
|
-
|
931
|
+
agoo_text_release(t);
|
923
932
|
|
924
933
|
return Qnil;
|
925
934
|
}
|
926
935
|
}
|
927
936
|
}
|
928
|
-
if (NULL == (hook = rhook_create(meth, pat, handler, &
|
937
|
+
if (NULL == (hook = rhook_create(meth, pat, handler, &agoo_server.eval_queue))) {
|
929
938
|
rb_raise(rb_eStandardError, "out of memory.");
|
930
939
|
} else {
|
931
|
-
|
932
|
-
|
940
|
+
agooHook h;
|
941
|
+
agooHook prev = NULL;
|
933
942
|
|
934
|
-
for (h =
|
943
|
+
for (h = agoo_server.hooks; NULL != h; h = h->next) {
|
935
944
|
prev = h;
|
936
945
|
}
|
937
946
|
if (NULL != prev) {
|
938
947
|
prev->next = hook;
|
939
948
|
} else {
|
940
|
-
|
949
|
+
agoo_server.hooks = hook;
|
941
950
|
}
|
942
951
|
rb_gc_register_address((VALUE*)&hook->handler);
|
943
952
|
}
|
@@ -953,10 +962,10 @@ handle(VALUE self, VALUE method, VALUE pattern, VALUE handler) {
|
|
953
962
|
*/
|
954
963
|
static VALUE
|
955
964
|
handle_not_found(VALUE self, VALUE handler) {
|
956
|
-
if (NULL == (
|
965
|
+
if (NULL == (agoo_server.hook404 = rhook_create(AGOO_GET, "/", handler, &agoo_server.eval_queue))) {
|
957
966
|
rb_raise(rb_eStandardError, "out of memory.");
|
958
967
|
}
|
959
|
-
rb_gc_register_address((VALUE*)&
|
968
|
+
rb_gc_register_address((VALUE*)&agoo_server.hook404->handler);
|
960
969
|
|
961
970
|
return Qnil;
|
962
971
|
}
|
@@ -970,9 +979,9 @@ handle_not_found(VALUE self, VALUE handler) {
|
|
970
979
|
*/
|
971
980
|
static VALUE
|
972
981
|
add_mime(VALUE self, VALUE suffix, VALUE type) {
|
973
|
-
struct
|
982
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
974
983
|
|
975
|
-
if (
|
984
|
+
if (AGOO_ERR_OK != mime_set(&err, StringValuePtr(suffix), StringValuePtr(type))) {
|
976
985
|
rb_raise(rb_eArgError, "%s", err.msg);
|
977
986
|
}
|
978
987
|
return Qnil;
|
@@ -988,7 +997,7 @@ add_mime(VALUE self, VALUE suffix, VALUE type) {
|
|
988
997
|
*/
|
989
998
|
static VALUE
|
990
999
|
path_group(VALUE self, VALUE path, VALUE dirs) {
|
991
|
-
|
1000
|
+
agooGroup g;
|
992
1001
|
|
993
1002
|
rb_check_type(path, T_STRING);
|
994
1003
|
rb_check_type(dirs, T_ARRAY);
|
@@ -1049,5 +1058,5 @@ server_init(VALUE mod) {
|
|
1049
1058
|
rserver = Data_Wrap_Struct(rb_cObject, server_mark, NULL, strdup("dummy"));
|
1050
1059
|
rb_gc_register_address(&rserver);
|
1051
1060
|
|
1052
|
-
|
1061
|
+
agoo_http_init();
|
1053
1062
|
}
|