agoo 2.8.4 → 2.9.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 +13 -0
- data/ext/agoo/agoo.c +2 -0
- data/ext/agoo/con.c +74 -43
- data/ext/agoo/debug.h +1 -0
- data/ext/agoo/domain.c +145 -0
- data/ext/agoo/domain.h +16 -0
- data/ext/agoo/early.c +28 -0
- data/ext/agoo/early.h +23 -0
- data/ext/agoo/early_hints.c +116 -0
- data/ext/agoo/early_hints.h +13 -0
- data/ext/agoo/gqleval.c +2 -2
- data/ext/agoo/graphql.c +1 -1
- data/ext/agoo/page.c +139 -52
- data/ext/agoo/page.h +4 -4
- data/ext/agoo/request.c +9 -1
- data/ext/agoo/res.c +65 -7
- data/ext/agoo/res.h +11 -8
- data/ext/agoo/rserver.c +75 -8
- data/ext/agoo/server.c +2 -0
- data/ext/agoo/server.h +1 -0
- data/ext/agoo/text.c +3 -0
- data/ext/agoo/text.h +6 -5
- data/lib/agoo/version.rb +1 -1
- data/test/domain_test.rb +84 -0
- data/test/early_hints_test.rb +104 -0
- data/test/rack_handler_test.rb +4 -4
- metadata +16 -6
data/ext/agoo/page.h
CHANGED
@@ -34,13 +34,13 @@ extern int agoo_pages_init(agooErr err);
|
|
34
34
|
extern int agoo_pages_set_root(agooErr err, const char *root);
|
35
35
|
extern void agoo_pages_cleanup();
|
36
36
|
|
37
|
-
extern agooGroup
|
38
|
-
extern agooDir
|
39
|
-
extern agooPage
|
37
|
+
extern agooGroup agoo_group_create(const char *path);
|
38
|
+
extern agooDir agoo_group_add(agooErr err, agooGroup g, const char *dir);
|
39
|
+
extern agooPage agoo_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
|
-
extern agooPage agoo_page_get(agooErr err, const char *path, int plen);
|
43
|
+
extern agooPage agoo_page_get(agooErr err, const char *path, int plen, const char *root);
|
44
44
|
extern int mime_set(agooErr err, const char *key, const char *value);
|
45
45
|
extern int agoo_header_rule(agooErr err, const char *path, const char *mime, const char *key, const char *value);
|
46
46
|
|
data/ext/agoo/request.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
#include "debug.h"
|
8
8
|
#include "con.h"
|
9
|
+
#include "early_hints.h"
|
9
10
|
#include "error_stream.h"
|
10
11
|
#include "rack_logger.h"
|
11
12
|
#include "request.h"
|
@@ -17,6 +18,7 @@ static VALUE connect_val = Qundef;
|
|
17
18
|
static VALUE content_length_val = Qundef;
|
18
19
|
static VALUE content_type_val = Qundef;
|
19
20
|
static VALUE delete_val = Qundef;
|
21
|
+
static VALUE early_hints_val = Qundef;
|
20
22
|
static VALUE empty_val = Qundef;
|
21
23
|
static VALUE get_val = Qundef;
|
22
24
|
static VALUE head_val = Qundef;
|
@@ -564,6 +566,11 @@ request_env(agooReq req, VALUE self) {
|
|
564
566
|
rb_hash_aset(env, rack_hijack_val, self);
|
565
567
|
rb_hash_aset(env, rack_hijack_io_val, Qnil);
|
566
568
|
|
569
|
+
if (agoo_server.rack_early_hints) {
|
570
|
+
volatile VALUE eh = agoo_early_hints_new(req);
|
571
|
+
|
572
|
+
rb_hash_aset(env, early_hints_val, eh);
|
573
|
+
}
|
567
574
|
req->env = (void*)env;
|
568
575
|
}
|
569
576
|
return (VALUE)req->env;
|
@@ -603,7 +610,7 @@ to_s(VALUE self) {
|
|
603
610
|
*
|
604
611
|
* call-seq: call()
|
605
612
|
*
|
606
|
-
* Returns an IO like object and
|
613
|
+
* Returns an IO like object and hijack the connection.
|
607
614
|
*/
|
608
615
|
static VALUE
|
609
616
|
call(VALUE self) {
|
@@ -679,6 +686,7 @@ request_init(VALUE mod) {
|
|
679
686
|
content_length_val = rb_str_new_cstr("CONTENT_LENGTH"); rb_gc_register_address(&content_length_val);
|
680
687
|
content_type_val = rb_str_new_cstr("CONTENT_TYPE"); rb_gc_register_address(&content_type_val);
|
681
688
|
delete_val = rb_str_new_cstr("DELETE"); rb_gc_register_address(&delete_val);
|
689
|
+
early_hints_val = rb_str_new_cstr("early_hints"); rb_gc_register_address(&early_hints_val);
|
682
690
|
empty_val = rb_str_new_cstr(""); rb_gc_register_address(&empty_val);
|
683
691
|
get_val = rb_str_new_cstr("GET"); rb_gc_register_address(&get_val);
|
684
692
|
head_val = rb_str_new_cstr("HEAD"); rb_gc_register_address(&head_val);
|
data/ext/agoo/res.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include <stdarg.h>
|
3
4
|
#include <stdio.h>
|
4
5
|
#include <stdlib.h>
|
5
6
|
|
@@ -26,9 +27,11 @@ agoo_res_create(agooCon con) {
|
|
26
27
|
}
|
27
28
|
}
|
28
29
|
res->next = NULL;
|
29
|
-
|
30
|
+
res->message = NULL;
|
31
|
+
pthread_mutex_init(&res->lock, NULL);
|
30
32
|
res->con = con;
|
31
33
|
res->con_kind = AGOO_CON_HTTP;
|
34
|
+
res->final = false;
|
32
35
|
res->close = false;
|
33
36
|
res->ping = false;
|
34
37
|
res->pong = false;
|
@@ -39,10 +42,8 @@ agoo_res_create(agooCon con) {
|
|
39
42
|
void
|
40
43
|
agoo_res_destroy(agooRes res) {
|
41
44
|
if (NULL != res) {
|
42
|
-
|
43
|
-
|
44
|
-
if (NULL != message) {
|
45
|
-
agoo_text_release(message);
|
45
|
+
if (NULL != res->message) {
|
46
|
+
agoo_text_release(res->message);
|
46
47
|
}
|
47
48
|
res->next = NULL;
|
48
49
|
pthread_mutex_lock(&res->con->loop->lock);
|
@@ -57,10 +58,67 @@ agoo_res_destroy(agooRes res) {
|
|
57
58
|
}
|
58
59
|
|
59
60
|
void
|
60
|
-
|
61
|
+
agoo_res_message_push(agooRes res, agooText t, bool final) {
|
61
62
|
if (NULL != t) {
|
62
63
|
agoo_text_ref(t);
|
63
64
|
}
|
64
|
-
|
65
|
+
pthread_mutex_lock(&res->lock);
|
66
|
+
if (!res->final) {
|
67
|
+
if (NULL == res->message) {
|
68
|
+
res->message = t;
|
69
|
+
} else {
|
70
|
+
agooText end = res->message;
|
71
|
+
|
72
|
+
for (; NULL != end->next; end = end->next) {
|
73
|
+
}
|
74
|
+
end->next = t;
|
75
|
+
}
|
76
|
+
res->final = final;
|
77
|
+
}
|
78
|
+
pthread_mutex_unlock(&res->lock);
|
79
|
+
}
|
80
|
+
|
81
|
+
static const char early_103[] = "HTTP/1.1 103 Early Hints\r\n";
|
82
|
+
|
83
|
+
void
|
84
|
+
agoo_res_add_early(agooRes res, agooEarly early) {
|
85
|
+
agooText t = agoo_text_allocate(1024);
|
86
|
+
|
87
|
+
t = agoo_text_append(t, early_103, sizeof(early_103) - 1);
|
88
|
+
for (; NULL != early; early = early->next) {
|
89
|
+
t = agoo_text_append(t, "Link: ", 6);
|
90
|
+
t = agoo_text_append(t, early->link, -1);
|
91
|
+
t = agoo_text_append(t, "\r\n", 2);
|
92
|
+
}
|
93
|
+
t = agoo_text_append(t, "\r\n", 2);
|
94
|
+
agoo_res_message_push(res, t, false);
|
95
|
+
}
|
96
|
+
|
97
|
+
agooText
|
98
|
+
agoo_res_message_peek(agooRes res) {
|
99
|
+
agooText t;
|
100
|
+
|
101
|
+
pthread_mutex_lock(&res->lock);
|
102
|
+
t = res->message;
|
103
|
+
pthread_mutex_unlock(&res->lock);
|
104
|
+
|
105
|
+
return t;
|
65
106
|
}
|
66
107
|
|
108
|
+
agooText
|
109
|
+
agoo_res_message_next(agooRes res) {
|
110
|
+
agooText t;
|
111
|
+
|
112
|
+
pthread_mutex_lock(&res->lock);
|
113
|
+
if (NULL != res->message) {
|
114
|
+
agooText t2 = res->message;
|
115
|
+
|
116
|
+
res->message = res->message->next;
|
117
|
+
// TBD make sure it is not release by the called, change code if it is
|
118
|
+
agoo_text_release(t2);
|
119
|
+
}
|
120
|
+
t = res->message;
|
121
|
+
pthread_mutex_unlock(&res->lock);
|
122
|
+
|
123
|
+
return t;
|
124
|
+
}
|
data/ext/agoo/res.h
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
#ifndef AGOO_RES_H
|
4
4
|
#define AGOO_RES_H
|
5
5
|
|
6
|
+
#include <pthread.h>
|
6
7
|
#include <stdbool.h>
|
7
8
|
|
8
9
|
#include "atomic.h"
|
9
10
|
#include "con.h"
|
11
|
+
#include "early.h"
|
10
12
|
#include "text.h"
|
11
13
|
|
12
14
|
struct _agooCon;
|
@@ -14,20 +16,21 @@ struct _agooCon;
|
|
14
16
|
typedef struct _agooRes {
|
15
17
|
struct _agooRes *next;
|
16
18
|
struct _agooCon *con;
|
17
|
-
|
19
|
+
volatile agooText message;
|
20
|
+
pthread_mutex_t lock; // a lock around message changes
|
21
|
+
volatile bool final;
|
18
22
|
agooConKind con_kind;
|
19
23
|
bool close;
|
20
24
|
bool ping;
|
21
25
|
bool pong;
|
22
26
|
} *agooRes;
|
23
27
|
|
24
|
-
extern agooRes
|
25
|
-
extern void
|
26
|
-
extern void agoo_res_set_message(agooRes res, agooText t);
|
28
|
+
extern agooRes agoo_res_create(struct _agooCon *con);
|
29
|
+
extern void agoo_res_destroy(agooRes res);
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
extern void agoo_res_message_push(agooRes res, agooText t, bool final);
|
32
|
+
extern void agoo_res_add_early(agooRes res, agooEarly early);
|
33
|
+
extern agooText agoo_res_message_peek(agooRes res);
|
34
|
+
extern agooText agoo_res_message_next(agooRes res);
|
32
35
|
|
33
36
|
#endif // AGOO_RES_H
|
data/ext/agoo/rserver.c
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
#include "bind.h"
|
16
16
|
#include "con.h"
|
17
17
|
#include "debug.h"
|
18
|
+
#include "domain.h"
|
18
19
|
#include "dtime.h"
|
19
20
|
#include "err.h"
|
20
21
|
#include "graphql.h"
|
@@ -311,7 +312,7 @@ rescue_error(VALUE x) {
|
|
311
312
|
message = agoo_text_create(buf, cnt);
|
312
313
|
|
313
314
|
req->res->close = true;
|
314
|
-
|
315
|
+
agoo_res_message_push(req->res, message, true);
|
315
316
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
316
317
|
} else {
|
317
318
|
/*
|
@@ -339,7 +340,7 @@ handle_base_inner(void *x) {
|
|
339
340
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
340
341
|
}
|
341
342
|
DATA_PTR(rr) = NULL;
|
342
|
-
|
343
|
+
agoo_res_message_push(req->res, response_text(rres), true);
|
343
344
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
344
345
|
|
345
346
|
return Qfalse;
|
@@ -514,7 +515,7 @@ handle_rack_inner(void *x) {
|
|
514
515
|
req->hook = agoo_hook_create(AGOO_NONE, NULL, (void*)handler, PUSH_HOOK, &agoo_server.eval_queue);
|
515
516
|
rupgraded_create(req->res->con, handler, request_env(req, Qnil));
|
516
517
|
t = agoo_sse_upgrade(req, t);
|
517
|
-
|
518
|
+
agoo_res_message_push(req->res, t, true);
|
518
519
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
519
520
|
return Qfalse;
|
520
521
|
default:
|
@@ -545,7 +546,7 @@ handle_rack_inner(void *x) {
|
|
545
546
|
rb_iterate(rb_each, bv, body_append_cb, (VALUE)&t);
|
546
547
|
}
|
547
548
|
}
|
548
|
-
|
549
|
+
agoo_res_message_push(req->res, t, true);
|
549
550
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
550
551
|
|
551
552
|
return Qfalse;
|
@@ -571,7 +572,7 @@ handle_wab_inner(void *x) {
|
|
571
572
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
572
573
|
}
|
573
574
|
DATA_PTR(rr) = NULL;
|
574
|
-
|
575
|
+
agoo_res_message_push(req->res, response_text(rres), true);
|
575
576
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
576
577
|
|
577
578
|
return Qfalse;
|
@@ -685,7 +686,7 @@ handle_protected(agooReq req, bool gvi) {
|
|
685
686
|
agooText message = agoo_text_create(buf, cnt);
|
686
687
|
|
687
688
|
req->res->close = true;
|
688
|
-
|
689
|
+
agoo_res_message_push(req->res, message, true);
|
689
690
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
690
691
|
break;
|
691
692
|
}
|
@@ -1023,7 +1024,7 @@ path_group(VALUE self, VALUE path, VALUE dirs) {
|
|
1023
1024
|
rb_check_type(path, T_STRING);
|
1024
1025
|
rb_check_type(dirs, T_ARRAY);
|
1025
1026
|
|
1026
|
-
if (NULL != (g =
|
1027
|
+
if (NULL != (g = agoo_group_create(StringValuePtr(path)))) {
|
1027
1028
|
int i;
|
1028
1029
|
int dcnt = (int)RARRAY_LEN(dirs);
|
1029
1030
|
VALUE entry;
|
@@ -1033,7 +1034,7 @@ path_group(VALUE self, VALUE path, VALUE dirs) {
|
|
1033
1034
|
if (T_STRING != rb_type(entry)) {
|
1034
1035
|
entry = rb_funcall(entry, rb_intern("to_s"), 0);
|
1035
1036
|
}
|
1036
|
-
if (NULL ==
|
1037
|
+
if (NULL == agoo_group_add(&err, g, StringValuePtr(entry))) {
|
1037
1038
|
rb_raise(rb_eStandardError, "%s", err.msg);
|
1038
1039
|
}
|
1039
1040
|
}
|
@@ -1072,6 +1073,69 @@ header_rule(VALUE self, VALUE path, VALUE mime, VALUE key, VALUE value) {
|
|
1072
1073
|
return Qnil;
|
1073
1074
|
}
|
1074
1075
|
|
1076
|
+
/* Document-method: domain
|
1077
|
+
*
|
1078
|
+
* call-seq: domain(host, path)
|
1079
|
+
*
|
1080
|
+
* Sets up a sub-domain. The first argument, _host_ should be either a String
|
1081
|
+
* or a Regexp that includes variable replacement elements. The _path_
|
1082
|
+
* argument should also be a string. If the _host_ argument is a Regex then
|
1083
|
+
* the $(n) sequence will be replaced by the matching variable in the Regex
|
1084
|
+
* result. The _path_ is the root of the sub-domain.
|
1085
|
+
*/
|
1086
|
+
static VALUE
|
1087
|
+
domain(VALUE self, VALUE host, VALUE path) {
|
1088
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
1089
|
+
|
1090
|
+
switch(rb_type(host)) {
|
1091
|
+
case RUBY_T_STRING:
|
1092
|
+
rb_check_type(path, T_STRING);
|
1093
|
+
if (AGOO_ERR_OK != agoo_domain_add(&err, rb_string_value_ptr((VALUE*)&host), rb_string_value_ptr((VALUE*)&path))) {
|
1094
|
+
rb_raise(rb_eArgError, "%s", err.msg);
|
1095
|
+
}
|
1096
|
+
break;
|
1097
|
+
case RUBY_T_REGEXP: {
|
1098
|
+
volatile VALUE v = rb_funcall(host, rb_intern("inspect"), 0);
|
1099
|
+
char rx[1024];
|
1100
|
+
|
1101
|
+
if (sizeof(rx) <= RSTRING_LEN(v)) {
|
1102
|
+
rb_raise(rb_eArgError, "host Regex limited to %ld characters", sizeof(rx));
|
1103
|
+
}
|
1104
|
+
strcpy(rx, rb_string_value_ptr((VALUE*)&v) + 1);
|
1105
|
+
rx[RSTRING_LEN(v) - 2] = '\0';
|
1106
|
+
if (AGOO_ERR_OK != agoo_domain_add_regex(&err, rx, rb_string_value_ptr((VALUE*)&path))) {
|
1107
|
+
rb_raise(rb_eArgError, "%s", err.msg);
|
1108
|
+
}
|
1109
|
+
break;
|
1110
|
+
}
|
1111
|
+
default:
|
1112
|
+
rb_raise(rb_eArgError, "host must be a String or Regex");
|
1113
|
+
break;
|
1114
|
+
}
|
1115
|
+
return Qnil;
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
/* Document-method: rack_early_hints
|
1119
|
+
*
|
1120
|
+
* call-seq: rack_early_hints(on)
|
1121
|
+
*
|
1122
|
+
* Turns on or off the inclusion of a early_hints object in the rack call env
|
1123
|
+
* Hash. If the argument is nil then the current value is returned.
|
1124
|
+
*/
|
1125
|
+
static VALUE
|
1126
|
+
rack_early_hints(VALUE self, VALUE on) {
|
1127
|
+
if (Qtrue == on) {
|
1128
|
+
agoo_server.rack_early_hints = true;
|
1129
|
+
} else if (Qfalse == on) {
|
1130
|
+
agoo_server.rack_early_hints = false;
|
1131
|
+
} else if (Qnil == on) {
|
1132
|
+
on = agoo_server.rack_early_hints ? Qtrue : Qfalse;
|
1133
|
+
} else {
|
1134
|
+
rb_raise(rb_eArgError, "rack_early_hints can only be set to true or false");
|
1135
|
+
}
|
1136
|
+
return on;
|
1137
|
+
}
|
1138
|
+
|
1075
1139
|
/* Document-class: Agoo::Server
|
1076
1140
|
*
|
1077
1141
|
* An HTTP server that support the rack API as well as some other optimized
|
@@ -1090,6 +1154,9 @@ server_init(VALUE mod) {
|
|
1090
1154
|
rb_define_module_function(server_mod, "add_mime", add_mime, 2);
|
1091
1155
|
rb_define_module_function(server_mod, "path_group", path_group, 2);
|
1092
1156
|
rb_define_module_function(server_mod, "header_rule", header_rule, 4);
|
1157
|
+
rb_define_module_function(server_mod, "domain", domain, 2);
|
1158
|
+
|
1159
|
+
rb_define_module_function(server_mod, "rack_early_hints", rack_early_hints, 1);
|
1093
1160
|
|
1094
1161
|
call_id = rb_intern("call");
|
1095
1162
|
each_id = rb_intern("each");
|
data/ext/agoo/server.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include <unistd.h>
|
11
11
|
|
12
12
|
#include "con.h"
|
13
|
+
#include "domain.h"
|
13
14
|
#include "dtime.h"
|
14
15
|
#include "http.h"
|
15
16
|
#include "hook.h"
|
@@ -247,6 +248,7 @@ agoo_server_shutdown(const char *app_name, void (*stop)()) {
|
|
247
248
|
|
248
249
|
agoo_pages_cleanup();
|
249
250
|
agoo_http_cleanup();
|
251
|
+
agoo_domain_cleanup();
|
250
252
|
}
|
251
253
|
}
|
252
254
|
|
data/ext/agoo/server.h
CHANGED
data/ext/agoo/text.c
CHANGED
@@ -47,6 +47,7 @@ agoo_text_create(const char *str, int len) {
|
|
47
47
|
agooText t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
|
48
48
|
|
49
49
|
if (NULL != t) {
|
50
|
+
t->next = NULL;
|
50
51
|
t->len = len;
|
51
52
|
t->alen = len;
|
52
53
|
t->bin = false;
|
@@ -63,6 +64,7 @@ agoo_text_dup(agooText t0) {
|
|
63
64
|
|
64
65
|
if (NULL != t0) {
|
65
66
|
if (NULL != (t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + t0->alen + 1))) {
|
67
|
+
t->next = NULL;
|
66
68
|
t->len = t0->len;
|
67
69
|
t->alen = t0->alen;
|
68
70
|
t->bin = false;
|
@@ -78,6 +80,7 @@ agoo_text_allocate(int len) {
|
|
78
80
|
agooText t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
|
79
81
|
|
80
82
|
if (NULL != t) {
|
83
|
+
t->next = NULL;
|
81
84
|
t->len = 0;
|
82
85
|
t->alen = len;
|
83
86
|
t->bin = false;
|
data/ext/agoo/text.h
CHANGED
@@ -10,11 +10,12 @@
|
|
10
10
|
#define AGOO_TEXT_MIN_SIZE 8
|
11
11
|
|
12
12
|
typedef struct _agooText {
|
13
|
-
|
14
|
-
long
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
struct _agooText *next;
|
14
|
+
long len; // length of valid text
|
15
|
+
long alen; // size of allocated text
|
16
|
+
atomic_int ref_cnt;
|
17
|
+
bool bin;
|
18
|
+
char text[AGOO_TEXT_MIN_SIZE];
|
18
19
|
} *agooText;
|
19
20
|
|
20
21
|
extern agooText agoo_text_create(const char *str, int len);
|
data/lib/agoo/version.rb
CHANGED
data/test/domain_test.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__)
|
4
|
+
$root_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
%w(lib ext).each do |dir|
|
6
|
+
$: << File.join($root_dir, dir)
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'minitest'
|
10
|
+
require 'minitest/autorun'
|
11
|
+
require 'net/http'
|
12
|
+
|
13
|
+
require 'agoo'
|
14
|
+
|
15
|
+
class StaticTest < Minitest::Test
|
16
|
+
@@server_started = false
|
17
|
+
|
18
|
+
def start_server
|
19
|
+
Agoo::Log.configure(dir: '',
|
20
|
+
console: true,
|
21
|
+
classic: true,
|
22
|
+
colorize: true,
|
23
|
+
states: {
|
24
|
+
INFO: false,
|
25
|
+
DEBUG: false,
|
26
|
+
connect: false,
|
27
|
+
request: false,
|
28
|
+
response: false,
|
29
|
+
eval: true,
|
30
|
+
})
|
31
|
+
|
32
|
+
Agoo::Server.init(6474, 'root', thread_count: 1)
|
33
|
+
Agoo::Server.domain('domain1.ohler.com', './domain1')
|
34
|
+
Agoo::Server.domain(/^domain([0-9]+).ohler.com$/, './domain$(1)')
|
35
|
+
Agoo::Server.start()
|
36
|
+
|
37
|
+
@@server_started = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup
|
41
|
+
unless @@server_started
|
42
|
+
start_server
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Minitest.after_run {
|
47
|
+
GC.start
|
48
|
+
Agoo::shutdown
|
49
|
+
}
|
50
|
+
|
51
|
+
def test_one
|
52
|
+
uri = URI('http://localhost:6474/name.txt')
|
53
|
+
req = Net::HTTP::Get.new(uri)
|
54
|
+
req['Host'] = 'domain1.ohler.com'
|
55
|
+
res = Net::HTTP.start(uri.hostname, uri.port) { |h|
|
56
|
+
h.request(req)
|
57
|
+
}
|
58
|
+
content = res.body
|
59
|
+
assert_equal('domain one
|
60
|
+
', content)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_two
|
64
|
+
uri = URI('http://localhost:6474/name.txt')
|
65
|
+
req = Net::HTTP::Get.new(uri)
|
66
|
+
req['Host'] = 'domain2.ohler.com'
|
67
|
+
res = Net::HTTP.start(uri.hostname, uri.port) { |h|
|
68
|
+
h.request(req)
|
69
|
+
}
|
70
|
+
content = res.body
|
71
|
+
assert_equal('domain two
|
72
|
+
', content)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_nothing
|
76
|
+
uri = URI('http://localhost:6474/name.txt')
|
77
|
+
req = Net::HTTP::Get.new(uri)
|
78
|
+
res = Net::HTTP.start(uri.hostname, uri.port) { |h|
|
79
|
+
h.request(req)
|
80
|
+
}
|
81
|
+
assert_equal("404", res.code)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|