agoo 2.4.0 → 2.5.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 +12 -0
- data/ext/agoo/agoo.c +4 -3
- data/ext/agoo/bind.c +275 -0
- data/ext/agoo/bind.h +35 -0
- data/ext/agoo/con.c +22 -25
- data/ext/agoo/debug.c +2 -0
- data/ext/agoo/debug.h +1 -0
- data/ext/agoo/error_stream.c +1 -0
- data/ext/agoo/hook.c +16 -6
- data/ext/agoo/hook.h +3 -1
- data/ext/agoo/http.c +7 -7
- data/ext/agoo/http.h +3 -1
- data/ext/agoo/log.h +1 -0
- data/ext/agoo/page.c +231 -104
- data/ext/agoo/page.h +10 -38
- data/ext/agoo/request.c +5 -1
- data/ext/agoo/request.h +1 -2
- data/ext/agoo/response.c +5 -1
- data/ext/agoo/rhook.c +2 -2
- data/ext/agoo/rhook.h +1 -1
- data/ext/agoo/rserver.c +991 -0
- data/ext/agoo/rserver.h +42 -0
- data/ext/agoo/server.c +95 -978
- data/ext/agoo/server.h +16 -27
- data/ext/agoo/upgraded.c +28 -20
- data/ext/agoo/websocket.c +4 -7
- data/lib/agoo/version.rb +1 -1
- data/test/bind_test.rb +134 -0
- data/test/named_client.rb +7 -0
- data/test/named_server.rb +13 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47d1801dcc95720dc1d86eca4a6e22d44ded5c3c4581493fb8026c9d3ff015d1
|
4
|
+
data.tar.gz: 473dfe0c24f99063efbb328ce857ef8ed77894c347445e2450cced56a5136a3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff2c2178fd44c3f752154835defc23568f37637730d53729f69fe31ab5d89233d4eeabe89f059825b333f4e314e6f25dfffbd0618a4b2006fddc90d11c3be8c4
|
7
|
+
data.tar.gz: 7c556c7fff8bd8f23e6f06332106d2b84b90e7df08b4129fa5fbe6452bc252dd5db90557dc079bd20368e552ad7161844f05ee5f98035d116c0cb8d54e1b0182
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
### 2.5.0 - 2018-08-10
|
4
|
+
|
5
|
+
The binding release with multiple options for connecting to the server.
|
6
|
+
|
7
|
+
- Multiple connection bindings now supported
|
8
|
+
|
9
|
+
- Binding to Unix named sockets support added.
|
10
|
+
|
11
|
+
- IPv6 now supported.
|
12
|
+
|
13
|
+
- Connection address now supported to restrict connection requests.
|
14
|
+
|
3
15
|
### 2.4.0 - 2018-07-04
|
4
16
|
|
5
17
|
- Rack hijack now supported.
|
data/ext/agoo/agoo.c
CHANGED
@@ -12,12 +12,13 @@
|
|
12
12
|
#include "request.h"
|
13
13
|
#include "response.h"
|
14
14
|
#include "rlog.h"
|
15
|
+
#include "rserver.h"
|
15
16
|
#include "server.h"
|
16
17
|
#include "upgraded.h"
|
17
18
|
|
18
19
|
void
|
19
20
|
agoo_shutdown() {
|
20
|
-
|
21
|
+
rserver_shutdown(Qnil);
|
21
22
|
log_close();
|
22
23
|
}
|
23
24
|
|
@@ -47,7 +48,7 @@ ragoo_publish(VALUE self, VALUE subject, VALUE message) {
|
|
47
48
|
const char *subj = extract_subject(subject, &slen);
|
48
49
|
|
49
50
|
rb_check_type(message, T_STRING);
|
50
|
-
queue_push(&
|
51
|
+
queue_push(&the_rserver.pub_queue, pub_publish(subj, slen, StringValuePtr(message), (int)RSTRING_LEN(message)));
|
51
52
|
|
52
53
|
return Qnil;
|
53
54
|
}
|
@@ -64,7 +65,7 @@ static VALUE
|
|
64
65
|
ragoo_unsubscribe(VALUE self, VALUE subject) {
|
65
66
|
rb_check_type(subject, T_STRING);
|
66
67
|
|
67
|
-
queue_push(&
|
68
|
+
queue_push(&the_rserver.pub_queue, pub_unsubscribe(NULL, StringValuePtr(subject), (int)RSTRING_LEN(subject)));
|
68
69
|
|
69
70
|
return Qnil;
|
70
71
|
}
|
data/ext/agoo/bind.c
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <netdb.h>
|
4
|
+
#include <netinet/tcp.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <sys/socket.h>
|
8
|
+
#include <sys/types.h>
|
9
|
+
#include <sys/un.h>
|
10
|
+
#include <unistd.h>
|
11
|
+
|
12
|
+
#include "bind.h"
|
13
|
+
#include "debug.h"
|
14
|
+
#include "log.h"
|
15
|
+
|
16
|
+
Bind
|
17
|
+
bind_port(Err err, int port) {
|
18
|
+
Bind b = (Bind)malloc(sizeof(struct _Bind));
|
19
|
+
|
20
|
+
if (NULL != b) {
|
21
|
+
char id[1024];
|
22
|
+
|
23
|
+
DEBUG_ALLOC(mem_bind, b);
|
24
|
+
memset(b, 0, sizeof(struct _Bind));
|
25
|
+
b->port = port;
|
26
|
+
b->family = AF_INET;
|
27
|
+
snprintf(id, sizeof(id) - 1, "http://:%d", port);
|
28
|
+
b->id = strdup(id);
|
29
|
+
}
|
30
|
+
return b;
|
31
|
+
}
|
32
|
+
|
33
|
+
static Bind
|
34
|
+
url_tcp(Err err, const char *url) {
|
35
|
+
char *colon = index(url, ':');
|
36
|
+
struct in_addr addr = { .s_addr = 0 };
|
37
|
+
int port;
|
38
|
+
Bind b;
|
39
|
+
|
40
|
+
if (NULL == colon) {
|
41
|
+
port = 80;
|
42
|
+
} else if (15 < colon - url) {
|
43
|
+
err_set(err, ERR_ARG, "tcp/http bind address is not valid. (%s)", url);
|
44
|
+
return NULL;
|
45
|
+
} else {
|
46
|
+
char buf[32];
|
47
|
+
|
48
|
+
strncpy(buf, url, colon - url);
|
49
|
+
buf[colon - url] = '\0';
|
50
|
+
if (0 == inet_aton(buf, &addr)) {
|
51
|
+
err_set(err, ERR_ARG, "tcp/http bind address is not valid. (%s)", url);
|
52
|
+
return NULL;
|
53
|
+
}
|
54
|
+
port = atoi(colon + 1);
|
55
|
+
}
|
56
|
+
if (NULL != (b = (Bind)malloc(sizeof(struct _Bind)))) {
|
57
|
+
char id[64];
|
58
|
+
|
59
|
+
DEBUG_ALLOC(mem_bind, b);
|
60
|
+
memset(b, 0, sizeof(struct _Bind));
|
61
|
+
|
62
|
+
b->port = port;
|
63
|
+
b->addr4 = addr;
|
64
|
+
b->family = AF_INET;
|
65
|
+
snprintf(id, sizeof(id), "http://%s:%d", inet_ntoa(addr), port);
|
66
|
+
b->id = strdup(id);
|
67
|
+
|
68
|
+
return b;
|
69
|
+
}
|
70
|
+
err_set(err, ERR_MEMORY, "Failed to allocate memory for a Bind.");
|
71
|
+
|
72
|
+
return b;
|
73
|
+
}
|
74
|
+
|
75
|
+
static Bind
|
76
|
+
url_tcp6(Err err, const char *url) {
|
77
|
+
struct in6_addr addr;
|
78
|
+
char *end = index(url, ']');
|
79
|
+
int port = 80;
|
80
|
+
char buf[256];
|
81
|
+
Bind b;
|
82
|
+
|
83
|
+
if (':' == *(end + 1)) {
|
84
|
+
port = atoi(end + 2);
|
85
|
+
}
|
86
|
+
memcpy(buf, url + 1, end - url - 1);
|
87
|
+
buf[end - url - 1] = '\0';
|
88
|
+
memset(&addr, 0, sizeof(addr));
|
89
|
+
if (0 == inet_pton(AF_INET6, buf, &addr)) {
|
90
|
+
err_set(err, ERR_ARG, "tcp/http bind address is not valid. (%s)", url);
|
91
|
+
return NULL;
|
92
|
+
}
|
93
|
+
if (NULL != (b = (Bind)malloc(sizeof(struct _Bind)))) {
|
94
|
+
char str[INET6_ADDRSTRLEN + 1];
|
95
|
+
|
96
|
+
DEBUG_ALLOC(mem_bind, b);
|
97
|
+
memset(b, 0, sizeof(struct _Bind));
|
98
|
+
|
99
|
+
b->port = port;
|
100
|
+
b->addr6 = addr;
|
101
|
+
b->family = AF_INET6;
|
102
|
+
snprintf(buf, sizeof(buf), "http://[%s]:%d", inet_ntop(AF_INET6, &addr, str, INET6_ADDRSTRLEN), port);
|
103
|
+
b->id = strdup(buf);
|
104
|
+
|
105
|
+
return b;
|
106
|
+
}
|
107
|
+
err_set(err, ERR_MEMORY, "Failed to allocate memory for a Bind.");
|
108
|
+
|
109
|
+
return b;
|
110
|
+
}
|
111
|
+
|
112
|
+
static Bind
|
113
|
+
url_named(Err err, const char *url) {
|
114
|
+
if ('\0' == *url) {
|
115
|
+
err_set(err, ERR_ARG, "Named Unix sockets names must not be empty.");
|
116
|
+
return NULL;
|
117
|
+
} else {
|
118
|
+
Bind b = (Bind)malloc(sizeof(struct _Bind));
|
119
|
+
|
120
|
+
if (NULL != b) {
|
121
|
+
const char *fmt = "unix://%s";
|
122
|
+
char id[1024];
|
123
|
+
|
124
|
+
DEBUG_ALLOC(mem_bind, b);
|
125
|
+
memset(b, 0, sizeof(struct _Bind));
|
126
|
+
b->name = strdup(url);
|
127
|
+
snprintf(id, sizeof(id) - 1, fmt, url);
|
128
|
+
b->id = strdup(id);
|
129
|
+
}
|
130
|
+
return b;
|
131
|
+
}
|
132
|
+
err_set(err, ERR_MEMORY, "Failed to allocate memory for a Bind.");
|
133
|
+
|
134
|
+
return NULL;
|
135
|
+
}
|
136
|
+
|
137
|
+
static Bind
|
138
|
+
url_ssl(Err err, const char *url) {
|
139
|
+
// TBD
|
140
|
+
return NULL;
|
141
|
+
}
|
142
|
+
|
143
|
+
Bind
|
144
|
+
bind_url(Err err, const char *url) {
|
145
|
+
if (0 == strncmp("tcp://", url, 6)) {
|
146
|
+
if ('[' == url[6]) {
|
147
|
+
return url_tcp6(err, url + 6);
|
148
|
+
}
|
149
|
+
return url_tcp(err, url + 6);
|
150
|
+
}
|
151
|
+
if (0 == strncmp("http://", url, 7)) {
|
152
|
+
if ('[' == url[7]) {
|
153
|
+
return url_tcp6(err, url + 7);
|
154
|
+
}
|
155
|
+
return url_tcp(err, url + 7);
|
156
|
+
}
|
157
|
+
if (0 == strncmp("unix://", url, 7)) {
|
158
|
+
return url_named(err, url + 7);
|
159
|
+
}
|
160
|
+
if (0 == strncmp("https://", url, 8)) {
|
161
|
+
return url_ssl(err, url + 8);
|
162
|
+
}
|
163
|
+
if (0 == strncmp("ssl://", url, 6)) {
|
164
|
+
return url_ssl(err, url + 6);
|
165
|
+
}
|
166
|
+
return NULL;
|
167
|
+
}
|
168
|
+
|
169
|
+
void
|
170
|
+
bind_destroy(Bind b) {
|
171
|
+
DEBUG_FREE(mem_bind, b);
|
172
|
+
free(b->id);
|
173
|
+
free(b->name);
|
174
|
+
free(b->key);
|
175
|
+
free(b->cert);
|
176
|
+
free(b->ca);
|
177
|
+
free(b);
|
178
|
+
}
|
179
|
+
|
180
|
+
static int
|
181
|
+
usual_listen(Err err, Bind b) {
|
182
|
+
int optval = 1;
|
183
|
+
int domain = PF_INET;
|
184
|
+
|
185
|
+
if (AF_INET6 == b->family) {
|
186
|
+
domain = PF_INET6;
|
187
|
+
}
|
188
|
+
if (0 >= (b->fd = socket(domain, SOCK_STREAM, IPPROTO_TCP))) {
|
189
|
+
log_cat(&error_cat, "Server failed to open server socket on port %d. %s.", b->port, strerror(errno));
|
190
|
+
|
191
|
+
return err_set(err, errno, "Server failed to open server socket. %s.", strerror(errno));
|
192
|
+
}
|
193
|
+
#ifdef OSX_OS
|
194
|
+
setsockopt(b->fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
195
|
+
#endif
|
196
|
+
setsockopt(b->fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
|
197
|
+
setsockopt(b->fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
|
198
|
+
if (AF_INET6 == b->family) {
|
199
|
+
struct sockaddr_in6 addr;
|
200
|
+
|
201
|
+
memset(&addr, 0, sizeof(addr));
|
202
|
+
addr.sin6_flowinfo = 0;
|
203
|
+
addr.sin6_family = b->family;
|
204
|
+
addr.sin6_addr = b->addr6;
|
205
|
+
addr.sin6_port = htons(b->port);
|
206
|
+
if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
|
207
|
+
log_cat(&error_cat, "Server failed to bind server socket. %s.", strerror(errno));
|
208
|
+
|
209
|
+
return err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
|
210
|
+
}
|
211
|
+
} else {
|
212
|
+
struct sockaddr_in addr;
|
213
|
+
|
214
|
+
memset(&addr, 0, sizeof(addr));
|
215
|
+
addr.sin_family = b->family;
|
216
|
+
addr.sin_addr = b->addr4;
|
217
|
+
addr.sin_port = htons(b->port);
|
218
|
+
if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
|
219
|
+
log_cat(&error_cat, "Server failed to bind server socket. %s.", strerror(errno));
|
220
|
+
|
221
|
+
return err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
|
222
|
+
}
|
223
|
+
}
|
224
|
+
listen(b->fd, 1000);
|
225
|
+
|
226
|
+
return ERR_OK;
|
227
|
+
}
|
228
|
+
|
229
|
+
static int
|
230
|
+
named_listen(Err err, Bind b) {
|
231
|
+
struct sockaddr_un addr;
|
232
|
+
|
233
|
+
remove(b->name);
|
234
|
+
if (0 >= (b->fd = socket(AF_UNIX, SOCK_STREAM, 0))) {
|
235
|
+
log_cat(&error_cat, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
|
236
|
+
|
237
|
+
return err_set(err, errno, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
|
238
|
+
}
|
239
|
+
memset(&addr, 0, sizeof(addr));
|
240
|
+
addr.sun_family = AF_UNIX;
|
241
|
+
strcpy(addr.sun_path, b->name);
|
242
|
+
if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
|
243
|
+
log_cat(&error_cat, "Server failed to bind server socket. %s.", strerror(errno));
|
244
|
+
|
245
|
+
return err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
|
246
|
+
}
|
247
|
+
listen(b->fd, 100);
|
248
|
+
|
249
|
+
return ERR_OK;
|
250
|
+
}
|
251
|
+
|
252
|
+
static int
|
253
|
+
ssl_listen(Err err, Bind b) {
|
254
|
+
// TBD
|
255
|
+
return ERR_OK;
|
256
|
+
}
|
257
|
+
|
258
|
+
int
|
259
|
+
bind_listen(Err err, Bind b) {
|
260
|
+
if (NULL != b->name) {
|
261
|
+
return named_listen(err, b);
|
262
|
+
}
|
263
|
+
if (NULL != b->key) {
|
264
|
+
return ssl_listen(err, b);
|
265
|
+
}
|
266
|
+
return usual_listen(err, b);
|
267
|
+
}
|
268
|
+
|
269
|
+
void
|
270
|
+
bind_close(Bind b) {
|
271
|
+
if (0 != b->fd) {
|
272
|
+
close(b->fd);
|
273
|
+
b->fd = 0;
|
274
|
+
}
|
275
|
+
}
|
data/ext/agoo/bind.h
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef __AGOO_BIND_H__
|
4
|
+
#define __AGOO_BIND_H__
|
5
|
+
|
6
|
+
#include <sys/socket.h>
|
7
|
+
#include <netinet/in.h>
|
8
|
+
#include <arpa/inet.h>
|
9
|
+
|
10
|
+
#include "err.h"
|
11
|
+
|
12
|
+
typedef struct _Bind {
|
13
|
+
struct _Bind *next;
|
14
|
+
int fd;
|
15
|
+
int port;
|
16
|
+
sa_family_t family;
|
17
|
+
union {
|
18
|
+
struct in_addr addr4;
|
19
|
+
struct in6_addr addr6;
|
20
|
+
};
|
21
|
+
char *name; // if set then Unix file
|
22
|
+
char *key; // if set then SSL
|
23
|
+
char *cert;
|
24
|
+
char *ca;
|
25
|
+
char *id;
|
26
|
+
} *Bind;
|
27
|
+
|
28
|
+
extern Bind bind_url(Err err, const char *url);
|
29
|
+
extern Bind bind_port(Err err, int port);
|
30
|
+
extern void bind_destroy(Bind b);
|
31
|
+
|
32
|
+
extern int bind_listen(Err err, Bind b);
|
33
|
+
extern void bind_close(Bind b);
|
34
|
+
|
35
|
+
#endif // __AGOO_BIND_H__
|
data/ext/agoo/con.c
CHANGED
@@ -10,9 +10,11 @@
|
|
10
10
|
#include "dtime.h"
|
11
11
|
#include "hook.h"
|
12
12
|
#include "http.h"
|
13
|
+
#include "page.h"
|
13
14
|
#include "pub.h"
|
14
15
|
#include "res.h"
|
15
16
|
#include "seg.h"
|
17
|
+
#include "rserver.h"
|
16
18
|
#include "server.h"
|
17
19
|
#include "sse.h"
|
18
20
|
#include "subject.h"
|
@@ -152,6 +154,7 @@ page_response(Con c, Page p, char *hend) {
|
|
152
154
|
return false;
|
153
155
|
}
|
154
156
|
|
157
|
+
// rserver
|
155
158
|
static void
|
156
159
|
push_error(Upgraded up, const char *msg, int mlen) {
|
157
160
|
if (NULL != up && Qnil != up->handler && up->on_error) {
|
@@ -164,10 +167,9 @@ push_error(Upgraded up, const char *msg, int mlen) {
|
|
164
167
|
req->msg[mlen] = '\0';
|
165
168
|
req->up = up;
|
166
169
|
req->method = ON_ERROR;
|
167
|
-
req->
|
168
|
-
req->handler = up->handler;
|
170
|
+
req->hook = hook_create(NONE, NULL, (void*)up->handler, PUSH_HOOK, &the_rserver.eval_queue);
|
169
171
|
upgraded_ref(up);
|
170
|
-
queue_push(&
|
172
|
+
queue_push(&the_rserver.eval_queue, (void*)req);
|
171
173
|
}
|
172
174
|
}
|
173
175
|
|
@@ -288,14 +290,14 @@ con_header_read(Con c) {
|
|
288
290
|
}
|
289
291
|
mlen = hend - c->buf + 4 + clen;
|
290
292
|
if (GET == method &&
|
291
|
-
NULL != (p = group_get(&err,
|
293
|
+
NULL != (p = group_get(&err, path.start, (int)(path.end - path.start)))) {
|
292
294
|
if (page_response(c, p, hend)) {
|
293
295
|
return bad_request(c, 500, __LINE__);
|
294
296
|
}
|
295
297
|
return -mlen;
|
296
298
|
}
|
297
299
|
if (GET == method && the_server.root_first &&
|
298
|
-
NULL != (p = page_get(&err,
|
300
|
+
NULL != (p = page_get(&err, path.start, (int)(path.end - path.start)))) {
|
299
301
|
if (page_response(c, p, hend)) {
|
300
302
|
return bad_request(c, 500, __LINE__);
|
301
303
|
}
|
@@ -312,7 +314,7 @@ con_header_read(Con c) {
|
|
312
314
|
}
|
313
315
|
return bad_request(c, 404, __LINE__);
|
314
316
|
}
|
315
|
-
if (NULL == (p = page_get(&err,
|
317
|
+
if (NULL == (p = page_get(&err, path.start, (int)(path.end - path.start)))) {
|
316
318
|
if (NULL != the_server.hook404) {
|
317
319
|
// There would be too many parameters to pass to a
|
318
320
|
// separate function so just goto the hook processing.
|
@@ -354,13 +356,8 @@ HOOKED:
|
|
354
356
|
c->req->header.start = c->req->msg + (b + 2 - c->buf);
|
355
357
|
c->req->header.len = (unsigned int)(hend - b - 2);
|
356
358
|
c->req->res = NULL;
|
357
|
-
|
358
|
-
|
359
|
-
c->req->handler_type = hook->type;
|
360
|
-
} else {
|
361
|
-
c->req->handler = Qnil;
|
362
|
-
c->req->handler_type = NO_HOOK;
|
363
|
-
}
|
359
|
+
c->req->hook = hook;
|
360
|
+
|
364
361
|
return mlen;
|
365
362
|
}
|
366
363
|
|
@@ -368,7 +365,7 @@ static void
|
|
368
365
|
check_upgrade(Con c) {
|
369
366
|
const char *v;
|
370
367
|
int vlen = 0;
|
371
|
-
|
368
|
+
|
372
369
|
if (NULL == c->req) {
|
373
370
|
return;
|
374
371
|
}
|
@@ -470,7 +467,7 @@ con_http_read(Con c) {
|
|
470
467
|
check_upgrade(c);
|
471
468
|
req = c->req;
|
472
469
|
c->req = NULL;
|
473
|
-
queue_push(
|
470
|
+
queue_push(req->hook->queue, (void*)req);
|
474
471
|
if (mlen < (long)c->bcnt) {
|
475
472
|
memmove(c->buf, c->buf + mlen, c->bcnt - mlen);
|
476
473
|
c->bcnt -= mlen;
|
@@ -508,6 +505,7 @@ con_ws_read(Con c) {
|
|
508
505
|
} else {
|
509
506
|
char msg[1024];
|
510
507
|
int len = snprintf(msg, sizeof(msg) - 1, "Failed to read WebSocket message. %s.", strerror(errno));
|
508
|
+
|
511
509
|
push_error(c->up, msg, len);
|
512
510
|
log_cat(&warn_cat, "Failed to read WebSocket message. %s.", strerror(errno));
|
513
511
|
}
|
@@ -571,7 +569,7 @@ con_ws_read(Con c) {
|
|
571
569
|
}
|
572
570
|
}
|
573
571
|
upgraded_ref(c->up);
|
574
|
-
queue_push(&
|
572
|
+
queue_push(&the_rserver.eval_queue, (void*)c->req);
|
575
573
|
if (mlen < (long)c->bcnt) {
|
576
574
|
memmove(c->buf, c->buf + mlen, c->bcnt - mlen);
|
577
575
|
c->bcnt -= mlen;
|
@@ -851,7 +849,7 @@ publish_pub(Pub pub) {
|
|
851
849
|
const char *sub = pub->subject->pattern;
|
852
850
|
int cnt = 0;
|
853
851
|
|
854
|
-
for (up =
|
852
|
+
for (up = the_rserver.up_list; NULL != up; up = up->next) {
|
855
853
|
if (NULL != up->con && upgraded_match(up, sub)) {
|
856
854
|
Res res = res_create(up->con);
|
857
855
|
|
@@ -875,7 +873,7 @@ unsubscribe_pub(Pub pub) {
|
|
875
873
|
if (NULL == pub->up) {
|
876
874
|
Upgraded up;
|
877
875
|
|
878
|
-
for (up =
|
876
|
+
for (up = the_rserver.up_list; NULL != up; up = up->next) {
|
879
877
|
upgraded_del_subject(up, pub->subject);
|
880
878
|
}
|
881
879
|
} else {
|
@@ -897,10 +895,9 @@ process_pub_con(Pub pub) {
|
|
897
895
|
|
898
896
|
req->up = up;
|
899
897
|
req->method = ON_EMPTY;
|
900
|
-
req->
|
901
|
-
req->handler = up->handler;
|
898
|
+
req->hook = hook_create(NONE, NULL, (void*)up->handler, PUSH_HOOK, &the_rserver.eval_queue);
|
902
899
|
upgraded_ref(up);
|
903
|
-
queue_push(&
|
900
|
+
queue_push(&the_rserver.eval_queue, (void*)req);
|
904
901
|
}
|
905
902
|
}
|
906
903
|
}
|
@@ -967,7 +964,7 @@ poll_setup(Con c, struct pollfd *pp) {
|
|
967
964
|
pp->events = POLLIN;
|
968
965
|
pp->revents = 0;
|
969
966
|
pp++;
|
970
|
-
pp->fd = queue_listen(&
|
967
|
+
pp->fd = queue_listen(&the_rserver.pub_queue);
|
971
968
|
pp->events = POLLIN;
|
972
969
|
pp->revents = 0;
|
973
970
|
pp++;
|
@@ -1063,7 +1060,7 @@ con_loop(void *x) {
|
|
1063
1060
|
pend = pa + cnt;
|
1064
1061
|
}
|
1065
1062
|
}
|
1066
|
-
while (NULL != (pub = (Pub)queue_pop(&
|
1063
|
+
while (NULL != (pub = (Pub)queue_pop(&the_rserver.pub_queue, 0.0))) {
|
1067
1064
|
process_pub_con(pub);
|
1068
1065
|
}
|
1069
1066
|
|
@@ -1101,8 +1098,8 @@ con_loop(void *x) {
|
|
1101
1098
|
}
|
1102
1099
|
// Check pub_queue if an event is waiting.
|
1103
1100
|
if (0 != (pa[1].revents & POLLIN)) {
|
1104
|
-
queue_release(&
|
1105
|
-
while (NULL != (pub = (Pub)queue_pop(&
|
1101
|
+
queue_release(&the_rserver.pub_queue);
|
1102
|
+
while (NULL != (pub = (Pub)queue_pop(&the_rserver.pub_queue, 0.0))) {
|
1106
1103
|
process_pub_con(pub);
|
1107
1104
|
}
|
1108
1105
|
}
|