agoo 2.2.2 → 2.3.0
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 +6 -0
 - data/ext/agoo/agoo.c +2 -2
 - data/ext/agoo/con.c +65 -62
 - data/ext/agoo/debug.c +3 -2
 - data/ext/agoo/extconf.rb +4 -2
 - data/ext/agoo/hook.c +15 -74
 - data/ext/agoo/hook.h +20 -12
 - data/ext/agoo/log.c +30 -466
 - data/ext/agoo/log.h +6 -5
 - data/ext/agoo/method.h +25 -0
 - data/ext/agoo/request.c +27 -23
 - data/ext/agoo/request.h +1 -0
 - data/ext/agoo/response.c +0 -1
 - data/ext/agoo/rhook.c +82 -0
 - data/ext/agoo/rhook.h +13 -0
 - data/ext/agoo/rlog.c +469 -0
 - data/ext/agoo/rlog.h +11 -0
 - data/ext/agoo/seg.h +11 -0
 - data/ext/agoo/server.c +22 -8
 - data/ext/agoo/server.h +1 -1
 - data/ext/agoo/types.h +0 -19
 - data/ext/agoo/upgraded.c +13 -1
 - data/ext/agoo/upgraded.h +2 -1
 - data/ext/agoo/websocket.c +3 -3
 - data/lib/agoo/version.rb +1 -1
 - metadata +9 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 68f159d050def385814b8fecb4b3d28cd638bedaa658543881a74f2587957260
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 72a2429c4eb44db0ddf7a033d7fde7a7fcdc112e032b9102340d7fb74a92f68b
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: bc963d7748c0406fa4e82133af064ec1c97607e3cc6c1695939fc5869b35d83f134b7ae440386f06531e9b65d27fcdb9bbc7db9122bdc5fdb1987f5f049703b3
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: fe94670810539c14abba9cdaba57843e1cbd0c8425b72d18d9ac036ee83fc95d513263cac5b2e0156dd94a8a908d70ea26e1fadd50334b7faa7bf5b94c88e38d
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # CHANGELOG
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ### 2.3.0 - 2018-06-29
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - Added an `env` method to the upgrade (Websocket and SSE) client.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            - Fixed Websocket bug where a pong caused a hang on the socket.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       3 
9 
     | 
    
         
             
            ### 2.2.2 - 2018-06-05
         
     | 
| 
       4 
10 
     | 
    
         | 
| 
       5 
11 
     | 
    
         
             
            - Fixed `bin/agoo` which had become out of date.
         
     | 
    
        data/ext/agoo/agoo.c
    CHANGED
    
    | 
         @@ -7,11 +7,11 @@ 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            #include "debug.h"
         
     | 
| 
       9 
9 
     | 
    
         
             
            #include "error_stream.h"
         
     | 
| 
       10 
     | 
    
         
            -
            #include "log.h"
         
     | 
| 
       11 
10 
     | 
    
         
             
            #include "pub.h"
         
     | 
| 
       12 
11 
     | 
    
         
             
            #include "rack_logger.h"
         
     | 
| 
       13 
12 
     | 
    
         
             
            #include "request.h"
         
     | 
| 
       14 
13 
     | 
    
         
             
            #include "response.h"
         
     | 
| 
      
 14 
     | 
    
         
            +
            #include "rlog.h"
         
     | 
| 
       15 
15 
     | 
    
         
             
            #include "server.h"
         
     | 
| 
       16 
16 
     | 
    
         
             
            #include "upgraded.h"
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
         @@ -89,7 +89,7 @@ void 
     | 
|
| 
       89 
89 
     | 
    
         
             
            Init_agoo() {
         
     | 
| 
       90 
90 
     | 
    
         
             
                VALUE	mod = rb_define_module("Agoo");
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                 
     | 
| 
      
 92 
     | 
    
         
            +
                rlog_init(mod);
         
     | 
| 
       93 
93 
     | 
    
         
             
                error_stream_init(mod);
         
     | 
| 
       94 
94 
     | 
    
         
             
                rack_logger_init(mod);
         
     | 
| 
       95 
95 
     | 
    
         
             
                request_init(mod);
         
     | 
    
        data/ext/agoo/con.c
    CHANGED
    
    | 
         @@ -1,6 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            #include <ctype.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <netdb.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
       4 
6 
     | 
    
         
             
            #include <string.h>
         
     | 
| 
       5 
7 
     | 
    
         | 
| 
       6 
8 
     | 
    
         
             
            #include "con.h"
         
     | 
| 
         @@ -10,6 +12,7 @@ 
     | 
|
| 
       10 
12 
     | 
    
         
             
            #include "http.h"
         
     | 
| 
       11 
13 
     | 
    
         
             
            #include "pub.h"
         
     | 
| 
       12 
14 
     | 
    
         
             
            #include "res.h"
         
     | 
| 
      
 15 
     | 
    
         
            +
            #include "seg.h"
         
     | 
| 
       13 
16 
     | 
    
         
             
            #include "server.h"
         
     | 
| 
       14 
17 
     | 
    
         
             
            #include "sse.h"
         
     | 
| 
       15 
18 
     | 
    
         
             
            #include "subject.h"
         
     | 
| 
         @@ -95,7 +98,7 @@ bad_request(Con c, int status, int line) { 
     | 
|
| 
       95 
98 
     | 
    
         
             
                const char *msg = http_code_message(status);
         
     | 
| 
       96 
99 
     | 
    
         | 
| 
       97 
100 
     | 
    
         
             
                if (NULL == (res = res_create(c))) {
         
     | 
| 
       98 
     | 
    
         
            -
            	log_cat(&error_cat, "memory allocation of response failed on connection %llu @ %d.", c->id, line);
         
     | 
| 
      
 101 
     | 
    
         
            +
            	log_cat(&error_cat, "memory allocation of response failed on connection %llu @ %d.", (unsigned long long)c->id, line);
         
     | 
| 
       99 
102 
     | 
    
         
             
                } else {
         
     | 
| 
       100 
103 
     | 
    
         
             
            	char	buf[256];
         
     | 
| 
       101 
104 
     | 
    
         
             
            	int	cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n", status, msg);
         
     | 
| 
         @@ -158,8 +161,7 @@ static long 
     | 
|
| 
       158 
161 
     | 
    
         
             
            con_header_read(Con c) {
         
     | 
| 
       159 
162 
     | 
    
         
             
                char	*hend = strstr(c->buf, "\r\n\r\n");
         
     | 
| 
       160 
163 
     | 
    
         
             
                Method	method;
         
     | 
| 
       161 
     | 
    
         
            -
                 
     | 
| 
       162 
     | 
    
         
            -
                char	*pend;
         
     | 
| 
      
 164 
     | 
    
         
            +
                struct _Seg	path;
         
     | 
| 
       163 
165 
     | 
    
         
             
                char	*query = NULL;
         
     | 
| 
       164 
166 
     | 
    
         
             
                char	*qend;
         
     | 
| 
       165 
167 
     | 
    
         
             
                char	*b;
         
     | 
| 
         @@ -177,7 +179,7 @@ con_header_read(Con c) { 
     | 
|
| 
       177 
179 
     | 
    
         
             
                }
         
     | 
| 
       178 
180 
     | 
    
         
             
                if (req_cat.on) {
         
     | 
| 
       179 
181 
     | 
    
         
             
            	*hend = '\0';
         
     | 
| 
       180 
     | 
    
         
            -
            	log_cat(&req_cat, "%llu: %s", c->id, c->buf);
         
     | 
| 
      
 182 
     | 
    
         
            +
            	log_cat(&req_cat, "%llu: %s", (unsigned long long)c->id, c->buf);
         
     | 
| 
       181 
183 
     | 
    
         
             
            	*hend = '\r';
         
     | 
| 
       182 
184 
     | 
    
         
             
                }
         
     | 
| 
       183 
185 
     | 
    
         
             
                for (b = c->buf; ' ' != *b; b++) {
         
     | 
| 
         @@ -245,11 +247,11 @@ con_header_read(Con c) { 
     | 
|
| 
       245 
247 
     | 
    
         
             
            	    return bad_request(c, 400, __LINE__);
         
     | 
| 
       246 
248 
     | 
    
         
             
            	}
         
     | 
| 
       247 
249 
     | 
    
         
             
                }
         
     | 
| 
       248 
     | 
    
         
            -
                path = b;
         
     | 
| 
      
 250 
     | 
    
         
            +
                path.start = b;
         
     | 
| 
       249 
251 
     | 
    
         
             
                for (; ' ' != *b; b++) {
         
     | 
| 
       250 
252 
     | 
    
         
             
            	switch (*b) {
         
     | 
| 
       251 
253 
     | 
    
         
             
            	case '?':
         
     | 
| 
       252 
     | 
    
         
            -
            	     
     | 
| 
      
 254 
     | 
    
         
            +
            	    path.end = b;
         
     | 
| 
       253 
255 
     | 
    
         
             
            	    query = b + 1;
         
     | 
| 
       254 
256 
     | 
    
         
             
            	    break;
         
     | 
| 
       255 
257 
     | 
    
         
             
            	case '\0':
         
     | 
| 
         @@ -259,7 +261,7 @@ con_header_read(Con c) { 
     | 
|
| 
       259 
261 
     | 
    
         
             
            	}
         
     | 
| 
       260 
262 
     | 
    
         
             
                }
         
     | 
| 
       261 
263 
     | 
    
         
             
                if (NULL == query) {
         
     | 
| 
       262 
     | 
    
         
            -
            	 
     | 
| 
      
 264 
     | 
    
         
            +
            	path.end = b;
         
     | 
| 
       263 
265 
     | 
    
         
             
            	query = b;
         
     | 
| 
       264 
266 
     | 
    
         
             
            	qend = b;
         
     | 
| 
       265 
267 
     | 
    
         
             
                } else {
         
     | 
| 
         @@ -267,20 +269,20 @@ con_header_read(Con c) { 
     | 
|
| 
       267 
269 
     | 
    
         
             
                }
         
     | 
| 
       268 
270 
     | 
    
         
             
                mlen = hend - c->buf + 4 + clen;
         
     | 
| 
       269 
271 
     | 
    
         
             
                if (GET == method &&
         
     | 
| 
       270 
     | 
    
         
            -
            	NULL != (p = group_get(&err, &the_server.pages, path, (int)( 
     | 
| 
      
 272 
     | 
    
         
            +
            	NULL != (p = group_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
         
     | 
| 
       271 
273 
     | 
    
         
             
            	if (page_response(c, p, hend)) {
         
     | 
| 
       272 
274 
     | 
    
         
             
            	    return bad_request(c, 500, __LINE__);
         
     | 
| 
       273 
275 
     | 
    
         
             
            	}
         
     | 
| 
       274 
276 
     | 
    
         
             
            	return -mlen;
         
     | 
| 
       275 
277 
     | 
    
         
             
                }
         
     | 
| 
       276 
278 
     | 
    
         
             
                if (GET == method && the_server.root_first &&
         
     | 
| 
       277 
     | 
    
         
            -
            	NULL != (p = page_get(&err, &the_server.pages, path, (int)( 
     | 
| 
      
 279 
     | 
    
         
            +
            	NULL != (p = page_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
         
     | 
| 
       278 
280 
     | 
    
         
             
            	if (page_response(c, p, hend)) {
         
     | 
| 
       279 
281 
     | 
    
         
             
            	    return bad_request(c, 500, __LINE__);
         
     | 
| 
       280 
282 
     | 
    
         
             
            	}
         
     | 
| 
       281 
283 
     | 
    
         
             
            	return -mlen;
         
     | 
| 
       282 
284 
     | 
    
         
             
                }
         
     | 
| 
       283 
     | 
    
         
            -
                if (NULL == (hook = hook_find(the_server.hooks, method, path 
     | 
| 
      
 285 
     | 
    
         
            +
                if (NULL == (hook = hook_find(the_server.hooks, method, &path))) {
         
     | 
| 
       284 
286 
     | 
    
         
             
            	if (GET == method) {
         
     | 
| 
       285 
287 
     | 
    
         
             
            	    if (the_server.root_first) { // already checked
         
     | 
| 
       286 
288 
     | 
    
         
             
            		if (NULL != the_server.hook404) {
         
     | 
| 
         @@ -291,7 +293,7 @@ con_header_read(Con c) { 
     | 
|
| 
       291 
293 
     | 
    
         
             
            		}
         
     | 
| 
       292 
294 
     | 
    
         
             
            		return bad_request(c, 404, __LINE__);
         
     | 
| 
       293 
295 
     | 
    
         
             
            	    }
         
     | 
| 
       294 
     | 
    
         
            -
            	    if (NULL == (p = page_get(&err, &the_server.pages, path, (int)( 
     | 
| 
      
 296 
     | 
    
         
            +
            	    if (NULL == (p = page_get(&err, &the_server.pages, path.start, (int)(path.end - path.start)))) {
         
     | 
| 
       295 
297 
     | 
    
         
             
            		if (NULL != the_server.hook404) {
         
     | 
| 
       296 
298 
     | 
    
         
             
            		    // There would be too many parameters to pass to a
         
     | 
| 
       297 
299 
     | 
    
         
             
            		    // separate function so just goto the hook processing.
         
     | 
| 
         @@ -323,8 +325,8 @@ HOOKED: 
     | 
|
| 
       323 
325 
     | 
    
         
             
                c->req->method = method;
         
     | 
| 
       324 
326 
     | 
    
         
             
                c->req->upgrade = UP_NONE;
         
     | 
| 
       325 
327 
     | 
    
         
             
                c->req->up = NULL;
         
     | 
| 
       326 
     | 
    
         
            -
                c->req->path.start = c->req->msg + (path - c->buf);
         
     | 
| 
       327 
     | 
    
         
            -
                c->req->path.len = (int)( 
     | 
| 
      
 328 
     | 
    
         
            +
                c->req->path.start = c->req->msg + (path.start - c->buf);
         
     | 
| 
      
 329 
     | 
    
         
            +
                c->req->path.len = (int)(path.end - path.start);
         
     | 
| 
       328 
330 
     | 
    
         
             
                c->req->query.start = c->req->msg + (query - c->buf);
         
     | 
| 
       329 
331 
     | 
    
         
             
                c->req->query.len = (int)(qend - query);
         
     | 
| 
       330 
332 
     | 
    
         
             
                c->req->body.start = c->req->msg + (hend - c->buf + 4);
         
     | 
| 
         @@ -334,7 +336,7 @@ HOOKED: 
     | 
|
| 
       334 
336 
     | 
    
         
             
                c->req->header.len = (unsigned int)(hend - b - 2);
         
     | 
| 
       335 
337 
     | 
    
         
             
                c->req->res = NULL;
         
     | 
| 
       336 
338 
     | 
    
         
             
                if (NULL != hook) {
         
     | 
| 
       337 
     | 
    
         
            -
            	c->req->handler = hook->handler;
         
     | 
| 
      
 339 
     | 
    
         
            +
            	c->req->handler = (VALUE)hook->handler;
         
     | 
| 
       338 
340 
     | 
    
         
             
            	c->req->handler_type = hook->type;
         
     | 
| 
       339 
341 
     | 
    
         
             
                } else {
         
     | 
| 
       340 
342 
     | 
    
         
             
            	c->req->handler = Qnil;
         
     | 
| 
         @@ -388,7 +390,7 @@ con_http_read(Con c) { 
     | 
|
| 
       388 
390 
     | 
    
         
             
            	// If nothing read then no need to complain. Just close.
         
     | 
| 
       389 
391 
     | 
    
         
             
            	if (0 < c->bcnt) {
         
     | 
| 
       390 
392 
     | 
    
         
             
            	    if (0 == cnt) {
         
     | 
| 
       391 
     | 
    
         
            -
            		log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", c->id);
         
     | 
| 
      
 393 
     | 
    
         
            +
            		log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", (unsigned long long)c->id);
         
     | 
| 
       392 
394 
     | 
    
         
             
            	    } else {
         
     | 
| 
       393 
395 
     | 
    
         
             
            		log_cat(&warn_cat, "Failed to read request. %s.", strerror(errno));
         
     | 
| 
       394 
396 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -426,11 +428,11 @@ con_http_read(Con c) { 
     | 
|
| 
       426 
428 
     | 
    
         
             
            		long	mlen;
         
     | 
| 
       427 
429 
     | 
    
         | 
| 
       428 
430 
     | 
    
         
             
            		if (debug_cat.on && NULL != c->req && NULL != c->req->body.start) {
         
     | 
| 
       429 
     | 
    
         
            -
            		    log_cat(&debug_cat, "request on %llu: %s", c->id, c->req->body.start);
         
     | 
| 
      
 431 
     | 
    
         
            +
            		    log_cat(&debug_cat, "request on %llu: %s", (unsigned long long)c->id, c->req->body.start);
         
     | 
| 
       430 
432 
     | 
    
         
             
            		}
         
     | 
| 
       431 
433 
     | 
    
         
             
            		if (NULL == (res = res_create(c))) {
         
     | 
| 
       432 
434 
     | 
    
         
             
            		    c->req = NULL;
         
     | 
| 
       433 
     | 
    
         
            -
            		    log_cat(&error_cat, "memory allocation of response failed on connection %llu.", c->id);
         
     | 
| 
      
 435 
     | 
    
         
            +
            		    log_cat(&error_cat, "memory allocation of response failed on connection %llu.", (unsigned long long)c->id);
         
     | 
| 
       434 
436 
     | 
    
         
             
            		    return bad_request(c, 500, __LINE__);
         
     | 
| 
       435 
437 
     | 
    
         
             
            		} else {
         
     | 
| 
       436 
438 
     | 
    
         
             
            		    if (NULL == c->res_tail) {
         
     | 
| 
         @@ -483,7 +485,7 @@ con_ws_read(Con c) { 
     | 
|
| 
       483 
485 
     | 
    
         
             
            	// If nothing read then no need to complain. Just close.
         
     | 
| 
       484 
486 
     | 
    
         
             
            	if (0 < c->bcnt) {
         
     | 
| 
       485 
487 
     | 
    
         
             
            	    if (0 == cnt) {
         
     | 
| 
       486 
     | 
    
         
            -
            		log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", c->id);
         
     | 
| 
      
 488 
     | 
    
         
            +
            		log_cat(&warn_cat, "Nothing to read. Client closed socket on connection %llu.", (unsigned long long)c->id);
         
     | 
| 
       487 
489 
     | 
    
         
             
            	    } else {
         
     | 
| 
       488 
490 
     | 
    
         
             
            		log_cat(&warn_cat, "Failed to read WebSocket message. %s.", strerror(errno));
         
     | 
| 
       489 
491 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -511,14 +513,20 @@ con_ws_read(Con c) { 
     | 
|
| 
       511 
513 
     | 
    
         
             
            	    case WS_OP_CLOSE:
         
     | 
| 
       512 
514 
     | 
    
         
             
            		return true;
         
     | 
| 
       513 
515 
     | 
    
         
             
            	    case WS_OP_PING:
         
     | 
| 
       514 
     | 
    
         
            -
            		 
     | 
| 
      
 516 
     | 
    
         
            +
            		if (mlen == (long)c->bcnt) {
         
     | 
| 
      
 517 
     | 
    
         
            +
            		    ws_pong(c);
         
     | 
| 
      
 518 
     | 
    
         
            +
            		    c->bcnt = 0;
         
     | 
| 
      
 519 
     | 
    
         
            +
            		}
         
     | 
| 
       515 
520 
     | 
    
         
             
            		break;
         
     | 
| 
       516 
521 
     | 
    
         
             
            	    case WS_OP_PONG:
         
     | 
| 
       517 
522 
     | 
    
         
             
            		// ignore
         
     | 
| 
      
 523 
     | 
    
         
            +
            		if (mlen == (long)c->bcnt) {
         
     | 
| 
      
 524 
     | 
    
         
            +
            		    c->bcnt = 0;
         
     | 
| 
      
 525 
     | 
    
         
            +
            		}
         
     | 
| 
       518 
526 
     | 
    
         
             
            		break;
         
     | 
| 
       519 
527 
     | 
    
         
             
            	    case WS_OP_CONT:
         
     | 
| 
       520 
528 
     | 
    
         
             
            	    default:
         
     | 
| 
       521 
     | 
    
         
            -
            		log_cat(&error_cat, "WebSocket op 0x%02x not supported on %llu.", op, c->id);
         
     | 
| 
      
 529 
     | 
    
         
            +
            		log_cat(&error_cat, "WebSocket op 0x%02x not supported on %llu.", op, (unsigned long long)c->id);
         
     | 
| 
       522 
530 
     | 
    
         
             
            		return true;
         
     | 
| 
       523 
531 
     | 
    
         
             
            	    }
         
     | 
| 
       524 
532 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -528,9 +536,9 @@ con_ws_read(Con c) { 
     | 
|
| 
       528 
536 
     | 
    
         
             
            	    if (mlen <= (long)c->bcnt) {
         
     | 
| 
       529 
537 
     | 
    
         
             
            		if (debug_cat.on) {
         
     | 
| 
       530 
538 
     | 
    
         
             
            		    if (ON_MSG == c->req->method) {
         
     | 
| 
       531 
     | 
    
         
            -
            			log_cat(&debug_cat, "WebSocket message on %llu: %s", c->id, c->req->msg);
         
     | 
| 
      
 539 
     | 
    
         
            +
            			log_cat(&debug_cat, "WebSocket message on %llu: %s", (unsigned long long)c->id, c->req->msg);
         
     | 
| 
       532 
540 
     | 
    
         
             
            		    } else {
         
     | 
| 
       533 
     | 
    
         
            -
            			log_cat(&debug_cat, "WebSocket binary message on %llu", c->id);
         
     | 
| 
      
 541 
     | 
    
         
            +
            			log_cat(&debug_cat, "WebSocket binary message on %llu", (unsigned long long)c->id);
         
     | 
| 
       534 
542 
     | 
    
         
             
            		    }
         
     | 
| 
       535 
543 
     | 
    
         
             
            		}
         
     | 
| 
       536 
544 
     | 
    
         
             
            	    }
         
     | 
| 
         @@ -587,17 +595,17 @@ con_http_write(Con c) { 
     | 
|
| 
       587 
595 
     | 
    
         
             
            	    }
         
     | 
| 
       588 
596 
     | 
    
         
             
            	    memcpy(buf, message->text, hend - message->text);
         
     | 
| 
       589 
597 
     | 
    
         
             
            	    buf[hend - message->text] = '\0';
         
     | 
| 
       590 
     | 
    
         
            -
            	    log_cat(&resp_cat, "%llu: %s", c->id, buf);
         
     | 
| 
      
 598 
     | 
    
         
            +
            	    log_cat(&resp_cat, "%llu: %s", (unsigned long long)c->id, buf);
         
     | 
| 
       591 
599 
     | 
    
         
             
            	}
         
     | 
| 
       592 
600 
     | 
    
         
             
            	if (debug_cat.on) {
         
     | 
| 
       593 
     | 
    
         
            -
            	    log_cat(&debug_cat, "response on %llu: %s", c->id, message->text);
         
     | 
| 
      
 601 
     | 
    
         
            +
            	    log_cat(&debug_cat, "response on %llu: %s", (unsigned long long)c->id, message->text);
         
     | 
| 
       594 
602 
     | 
    
         
             
            	}
         
     | 
| 
       595 
603 
     | 
    
         
             
                }
         
     | 
| 
       596 
604 
     | 
    
         
             
                if (0 > (cnt = send(c->sock, message->text + c->wcnt, message->len - c->wcnt, 0))) {
         
     | 
| 
       597 
605 
     | 
    
         
             
            	if (EAGAIN == errno) {
         
     | 
| 
       598 
606 
     | 
    
         
             
            	    return false;
         
     | 
| 
       599 
607 
     | 
    
         
             
            	}
         
     | 
| 
       600 
     | 
    
         
            -
            	log_cat(&error_cat, "Socket error @ %llu.", c->id);
         
     | 
| 
      
 608 
     | 
    
         
            +
            	log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
         
     | 
| 
       601 
609 
     | 
    
         | 
| 
       602 
610 
     | 
    
         
             
            	return true;
         
     | 
| 
       603 
611 
     | 
    
         
             
                }
         
     | 
| 
         @@ -633,7 +641,7 @@ con_ws_write(Con c) { 
     | 
|
| 
       633 
641 
     | 
    
         
             
            		if (EAGAIN == errno) {
         
     | 
| 
       634 
642 
     | 
    
         
             
            		    return false;
         
     | 
| 
       635 
643 
     | 
    
         
             
            		}
         
     | 
| 
       636 
     | 
    
         
            -
            		log_cat(&error_cat, "Socket error @ %llu.", c->id);
         
     | 
| 
      
 644 
     | 
    
         
            +
            		log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
         
     | 
| 
       637 
645 
     | 
    
         
             
            		ws_req_close(c);
         
     | 
| 
       638 
646 
     | 
    
         
             
            		res_destroy(res);
         
     | 
| 
       639 
647 
     | 
    
         | 
| 
         @@ -644,7 +652,7 @@ con_ws_write(Con c) { 
     | 
|
| 
       644 
652 
     | 
    
         
             
            		if (EAGAIN == errno) {
         
     | 
| 
       645 
653 
     | 
    
         
             
            		    return false;
         
     | 
| 
       646 
654 
     | 
    
         
             
            		}
         
     | 
| 
       647 
     | 
    
         
            -
            		log_cat(&error_cat, "Socket error @ %llu.", c->id);
         
     | 
| 
      
 655 
     | 
    
         
            +
            		log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
         
     | 
| 
       648 
656 
     | 
    
         
             
            		ws_req_close(c);
         
     | 
| 
       649 
657 
     | 
    
         
             
            		res_destroy(res);
         
     | 
| 
       650 
658 
     | 
    
         | 
| 
         @@ -671,9 +679,9 @@ con_ws_write(Con c) { 
     | 
|
| 
       671 
679 
     | 
    
         | 
| 
       672 
680 
     | 
    
         
             
            	if (push_cat.on) {
         
     | 
| 
       673 
681 
     | 
    
         
             
            	    if (message->bin) {
         
     | 
| 
       674 
     | 
    
         
            -
            		log_cat(&push_cat, "%llu binary", c->id);
         
     | 
| 
      
 682 
     | 
    
         
            +
            		log_cat(&push_cat, "%llu binary", (unsigned long long)c->id);
         
     | 
| 
       675 
683 
     | 
    
         
             
            	    } else {
         
     | 
| 
       676 
     | 
    
         
            -
            		log_cat(&push_cat, "%llu: %s", c->id, message->text);
         
     | 
| 
      
 684 
     | 
    
         
            +
            		log_cat(&push_cat, "%llu: %s", (unsigned long long)c->id, message->text);
         
     | 
| 
       677 
685 
     | 
    
         
             
            	    }
         
     | 
| 
       678 
686 
     | 
    
         
             
            	}
         
     | 
| 
       679 
687 
     | 
    
         
             
            	t = ws_expand(message);
         
     | 
| 
         @@ -686,7 +694,7 @@ con_ws_write(Con c) { 
     | 
|
| 
       686 
694 
     | 
    
         
             
            	if (EAGAIN == errno) {
         
     | 
| 
       687 
695 
     | 
    
         
             
            	    return false;
         
     | 
| 
       688 
696 
     | 
    
         
             
            	}
         
     | 
| 
       689 
     | 
    
         
            -
            	log_cat(&error_cat, "Socket error @ %llu.", c->id);
         
     | 
| 
      
 697 
     | 
    
         
            +
            	log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
         
     | 
| 
       690 
698 
     | 
    
         
             
            	ws_req_close(c);
         
     | 
| 
       691 
699 
     | 
    
         | 
| 
       692 
700 
     | 
    
         
             
            	return true;
         
     | 
| 
         @@ -695,7 +703,6 @@ con_ws_write(Con c) { 
     | 
|
| 
       695 
703 
     | 
    
         
             
                if (c->wcnt == message->len) { // finished
         
     | 
| 
       696 
704 
     | 
    
         
             
            	Res	res = c->res_head;
         
     | 
| 
       697 
705 
     | 
    
         
             
            	bool	done = res->close;
         
     | 
| 
       698 
     | 
    
         
            -
            	int	pending;
         
     | 
| 
       699 
706 
     | 
    
         | 
| 
       700 
707 
     | 
    
         
             
            	c->res_head = res->next;
         
     | 
| 
       701 
708 
     | 
    
         
             
            	if (res == c->res_tail) {
         
     | 
| 
         @@ -703,18 +710,7 @@ con_ws_write(Con c) { 
     | 
|
| 
       703 
710 
     | 
    
         
             
            	}
         
     | 
| 
       704 
711 
     | 
    
         
             
            	c->wcnt = 0;
         
     | 
| 
       705 
712 
     | 
    
         
             
            	res_destroy(res);
         
     | 
| 
       706 
     | 
    
         
            -
             
     | 
| 
       707 
     | 
    
         
            -
            	    if (NULL != c->up && Qnil != c->up->handler && c->up->on_empty) {
         
     | 
| 
       708 
     | 
    
         
            -
            		Req	req = request_create(0);
         
     | 
| 
       709 
     | 
    
         
            -
            	    
         
     | 
| 
       710 
     | 
    
         
            -
            		req->up = c->up;
         
     | 
| 
       711 
     | 
    
         
            -
            		req->method = ON_EMPTY;
         
     | 
| 
       712 
     | 
    
         
            -
            		req->handler_type = PUSH_HOOK;
         
     | 
| 
       713 
     | 
    
         
            -
            		req->handler = c->up->handler;
         
     | 
| 
       714 
     | 
    
         
            -
            		upgraded_ref(c->up);
         
     | 
| 
       715 
     | 
    
         
            -
            		queue_push(&the_server.eval_queue, (void*)req);
         
     | 
| 
       716 
     | 
    
         
            -
            	    }
         
     | 
| 
       717 
     | 
    
         
            -
            	}
         
     | 
| 
      
 713 
     | 
    
         
            +
             
     | 
| 
       718 
714 
     | 
    
         
             
            	return done;
         
     | 
| 
       719 
715 
     | 
    
         
             
                }
         
     | 
| 
       720 
716 
     | 
    
         
             
                return false;
         
     | 
| 
         @@ -736,7 +732,7 @@ con_sse_write(Con c) { 
     | 
|
| 
       736 
732 
     | 
    
         
             
            	Text	t;
         
     | 
| 
       737 
733 
     | 
    
         | 
| 
       738 
734 
     | 
    
         
             
            	if (push_cat.on) {
         
     | 
| 
       739 
     | 
    
         
            -
            	    log_cat(&push_cat, "%llu: %s", c->id, message->text);
         
     | 
| 
      
 735 
     | 
    
         
            +
            	    log_cat(&push_cat, "%llu: %s", (unsigned long long)c->id, message->text);
         
     | 
| 
       740 
736 
     | 
    
         
             
            	}
         
     | 
| 
       741 
737 
     | 
    
         
             
            	t = sse_expand(message);
         
     | 
| 
       742 
738 
     | 
    
         
             
            	if (t != message) {
         
     | 
| 
         @@ -748,7 +744,7 @@ con_sse_write(Con c) { 
     | 
|
| 
       748 
744 
     | 
    
         
             
            	if (EAGAIN == errno) {
         
     | 
| 
       749 
745 
     | 
    
         
             
            	    return false;
         
     | 
| 
       750 
746 
     | 
    
         
             
            	}
         
     | 
| 
       751 
     | 
    
         
            -
            	log_cat(&error_cat, "Socket error @ %llu.", c->id);
         
     | 
| 
      
 747 
     | 
    
         
            +
            	log_cat(&error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
         
     | 
| 
       752 
748 
     | 
    
         
             
            	ws_req_close(c);
         
     | 
| 
       753 
749 
     | 
    
         | 
| 
       754 
750 
     | 
    
         
             
            	return true;
         
     | 
| 
         @@ -757,7 +753,6 @@ con_sse_write(Con c) { 
     | 
|
| 
       757 
753 
     | 
    
         
             
                if (c->wcnt == message->len) { // finished
         
     | 
| 
       758 
754 
     | 
    
         
             
            	Res	res = c->res_head;
         
     | 
| 
       759 
755 
     | 
    
         
             
            	bool	done = res->close;
         
     | 
| 
       760 
     | 
    
         
            -
            	int	pending;
         
     | 
| 
       761 
756 
     | 
    
         | 
| 
       762 
757 
     | 
    
         
             
            	c->res_head = res->next;
         
     | 
| 
       763 
758 
     | 
    
         
             
            	if (res == c->res_tail) {
         
     | 
| 
         @@ -765,18 +760,7 @@ con_sse_write(Con c) { 
     | 
|
| 
       765 
760 
     | 
    
         
             
            	}
         
     | 
| 
       766 
761 
     | 
    
         
             
            	c->wcnt = 0;
         
     | 
| 
       767 
762 
     | 
    
         
             
            	res_destroy(res);
         
     | 
| 
       768 
     | 
    
         
            -
             
     | 
| 
       769 
     | 
    
         
            -
            	    if (NULL != c->up && Qnil != c->up->handler && c->up->on_empty) {
         
     | 
| 
       770 
     | 
    
         
            -
            		Req	req = request_create(0);
         
     | 
| 
       771 
     | 
    
         
            -
            	    
         
     | 
| 
       772 
     | 
    
         
            -
            		req->up = c->up;
         
     | 
| 
       773 
     | 
    
         
            -
            		req->method = ON_EMPTY;
         
     | 
| 
       774 
     | 
    
         
            -
            		req->handler_type = PUSH_HOOK;
         
     | 
| 
       775 
     | 
    
         
            -
            		req->handler = c->up->handler;
         
     | 
| 
       776 
     | 
    
         
            -
            		upgraded_ref(c->up);
         
     | 
| 
       777 
     | 
    
         
            -
            		queue_push(&the_server.eval_queue, (void*)req);
         
     | 
| 
       778 
     | 
    
         
            -
            	    }
         
     | 
| 
       779 
     | 
    
         
            -
            	}
         
     | 
| 
      
 763 
     | 
    
         
            +
             
     | 
| 
       780 
764 
     | 
    
         
             
            	return done;
         
     | 
| 
       781 
765 
     | 
    
         
             
                }
         
     | 
| 
       782 
766 
     | 
    
         
             
                return false;
         
     | 
| 
         @@ -816,7 +800,8 @@ static void 
     | 
|
| 
       816 
800 
     | 
    
         
             
            publish_pub(Pub pub) {
         
     | 
| 
       817 
801 
     | 
    
         
             
                Upgraded	up;
         
     | 
| 
       818 
802 
     | 
    
         
             
                const char	*sub = pub->subject->pattern;
         
     | 
| 
       819 
     | 
    
         
            -
             
     | 
| 
      
 803 
     | 
    
         
            +
                int	cnt = 0;
         
     | 
| 
      
 804 
     | 
    
         
            +
                
         
     | 
| 
       820 
805 
     | 
    
         
             
                for (up = the_server.up_list; NULL != up; up = up->next) {
         
     | 
| 
       821 
806 
     | 
    
         
             
            	if (NULL != up->con && upgraded_match(up, sub)) {
         
     | 
| 
       822 
807 
     | 
    
         
             
            	    Res	res = res_create(up->con);
         
     | 
| 
         @@ -830,6 +815,7 @@ publish_pub(Pub pub) { 
     | 
|
| 
       830 
815 
     | 
    
         
             
            		up->con->res_tail = res;
         
     | 
| 
       831 
816 
     | 
    
         
             
            		res->con_kind = CON_ANY;
         
     | 
| 
       832 
817 
     | 
    
         
             
            		res_set_message(res, text_dup(pub->msg));
         
     | 
| 
      
 818 
     | 
    
         
            +
            		cnt++;
         
     | 
| 
       833 
819 
     | 
    
         
             
            	    }
         
     | 
| 
       834 
820 
     | 
    
         
             
            	}
         
     | 
| 
       835 
821 
     | 
    
         
             
                }
         
     | 
| 
         @@ -852,6 +838,23 @@ static void 
     | 
|
| 
       852 
838 
     | 
    
         
             
            process_pub_con(Pub pub) {
         
     | 
| 
       853 
839 
     | 
    
         
             
                Upgraded	up = pub->up;
         
     | 
| 
       854 
840 
     | 
    
         | 
| 
      
 841 
     | 
    
         
            +
                if (NULL != up) {
         
     | 
| 
      
 842 
     | 
    
         
            +
            	int	pending;
         
     | 
| 
      
 843 
     | 
    
         
            +
            	
         
     | 
| 
      
 844 
     | 
    
         
            +
            	// TBD Change pending to be based on length of con queue
         
     | 
| 
      
 845 
     | 
    
         
            +
            	if (1 == (pending = atomic_fetch_sub(&up->pending, 1))) {
         
     | 
| 
      
 846 
     | 
    
         
            +
            	    if (NULL != up && Qnil != up->handler && up->on_empty) {
         
     | 
| 
      
 847 
     | 
    
         
            +
            		Req	req = request_create(0);
         
     | 
| 
      
 848 
     | 
    
         
            +
            	    
         
     | 
| 
      
 849 
     | 
    
         
            +
            		req->up = up;
         
     | 
| 
      
 850 
     | 
    
         
            +
            		req->method = ON_EMPTY;
         
     | 
| 
      
 851 
     | 
    
         
            +
            		req->handler_type = PUSH_HOOK;
         
     | 
| 
      
 852 
     | 
    
         
            +
            		req->handler = up->handler;
         
     | 
| 
      
 853 
     | 
    
         
            +
            		upgraded_ref(up);
         
     | 
| 
      
 854 
     | 
    
         
            +
            		queue_push(&the_server.eval_queue, (void*)req);
         
     | 
| 
      
 855 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 856 
     | 
    
         
            +
            	}
         
     | 
| 
      
 857 
     | 
    
         
            +
                }
         
     | 
| 
       855 
858 
     | 
    
         
             
                switch (pub->kind) {
         
     | 
| 
       856 
859 
     | 
    
         
             
                case PUB_CLOSE:
         
     | 
| 
       857 
860 
     | 
    
         
             
            	// An close after already closed is used to decrement the reference
         
     | 
| 
         @@ -1073,9 +1076,9 @@ con_loop(void *x) { 
     | 
|
| 
       1073 
1076 
     | 
    
         
             
            	    if (0 != (pp->revents & (POLLERR | POLLHUP | POLLNVAL))) {
         
     | 
| 
       1074 
1077 
     | 
    
         
             
            		if (0 < c->bcnt) {
         
     | 
| 
       1075 
1078 
     | 
    
         
             
            		    if (0 != (pp->revents & (POLLHUP | POLLNVAL))) {
         
     | 
| 
       1076 
     | 
    
         
            -
            			log_cat(&error_cat, "Socket %llu closed.", c->id);
         
     | 
| 
      
 1079 
     | 
    
         
            +
            			log_cat(&error_cat, "Socket %llu closed.", (unsigned long long)c->id);
         
     | 
| 
       1077 
1080 
     | 
    
         
             
            		    } else if (!c->closing) {
         
     | 
| 
       1078 
     | 
    
         
            -
            			log_cat(&error_cat, "Socket %llu error. %s", c->id, strerror(errno));
         
     | 
| 
      
 1081 
     | 
    
         
            +
            			log_cat(&error_cat, "Socket %llu error. %s", (unsigned long long)c->id, strerror(errno));
         
     | 
| 
       1079 
1082 
     | 
    
         
             
            		    }
         
     | 
| 
       1080 
1083 
     | 
    
         
             
            		}
         
     | 
| 
       1081 
1084 
     | 
    
         
             
            		c->dead = true;
         
     | 
| 
         @@ -1113,7 +1116,7 @@ con_loop(void *x) { 
     | 
|
| 
       1113 
1116 
     | 
    
         
             
            		prev->next = next;
         
     | 
| 
       1114 
1117 
     | 
    
         
             
            	    }
         
     | 
| 
       1115 
1118 
     | 
    
         
             
            	    ccnt--;
         
     | 
| 
       1116 
     | 
    
         
            -
            	    log_cat(&con_cat, "Connection %llu closed.", c->id);
         
     | 
| 
      
 1119 
     | 
    
         
            +
            	    log_cat(&con_cat, "Connection %llu closed.", (unsigned long long)c->id);
         
     | 
| 
       1117 
1120 
     | 
    
         
             
            	    con_destroy(c);
         
     | 
| 
       1118 
1121 
     | 
    
         
             
            	}
         
     | 
| 
       1119 
1122 
     | 
    
         
             
                }
         
     | 
    
        data/ext/agoo/debug.c
    CHANGED
    
    
    
        data/ext/agoo/extconf.rb
    CHANGED
    
    | 
         @@ -5,8 +5,10 @@ extension_name = 'agoo' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            dir_config(extension_name)
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            $CPPFLAGS += " -DPLATFORM_LINUX" if 'x86_64-linux' == RUBY_PLATFORM
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            # 
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # Adding the __attribute__ flag only works with gcc compilers and even then it
         
     | 
| 
      
 10 
     | 
    
         
            +
            # does not work to check args with varargs s just remove the check.
         
     | 
| 
      
 11 
     | 
    
         
            +
            CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
       11 
13 
     | 
    
         
             
            create_makefile(File.join(extension_name, extension_name))
         
     | 
| 
       12 
14 
     | 
    
         | 
    
        data/ext/agoo/hook.c
    CHANGED
    
    | 
         @@ -6,52 +6,8 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
            #include "debug.h"
         
     | 
| 
       7 
7 
     | 
    
         
             
            #include "hook.h"
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       10 
     | 
    
         
            -
            resolve_classname(VALUE mod, const char *classname) {
         
     | 
| 
       11 
     | 
    
         
            -
                VALUE	clas;
         
     | 
| 
       12 
     | 
    
         
            -
                ID		ci = rb_intern(classname);
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                if (rb_const_defined_at(mod, ci)) {
         
     | 
| 
       15 
     | 
    
         
            -
            	clas = rb_const_get_at(mod, ci);
         
     | 
| 
       16 
     | 
    
         
            -
                } else {
         
     | 
| 
       17 
     | 
    
         
            -
            	clas = Qundef;
         
     | 
| 
       18 
     | 
    
         
            -
                }
         
     | 
| 
       19 
     | 
    
         
            -
                return clas;
         
     | 
| 
       20 
     | 
    
         
            -
            }
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       23 
     | 
    
         
            -
            resolve_classpath(const char *name, size_t len) {
         
     | 
| 
       24 
     | 
    
         
            -
                char	class_name[1024];
         
     | 
| 
       25 
     | 
    
         
            -
                VALUE	clas;
         
     | 
| 
       26 
     | 
    
         
            -
                char	*end = class_name + sizeof(class_name) - 1;
         
     | 
| 
       27 
     | 
    
         
            -
                char	*s;
         
     | 
| 
       28 
     | 
    
         
            -
                const char	*n = name;
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                clas = rb_cObject;
         
     | 
| 
       31 
     | 
    
         
            -
                for (s = class_name; 0 < len; n++, len--) {
         
     | 
| 
       32 
     | 
    
         
            -
            	if (':' == *n) {
         
     | 
| 
       33 
     | 
    
         
            -
            	    *s = '\0';
         
     | 
| 
       34 
     | 
    
         
            -
            	    n++;
         
     | 
| 
       35 
     | 
    
         
            -
            	    len--;
         
     | 
| 
       36 
     | 
    
         
            -
            	    if (':' != *n) {
         
     | 
| 
       37 
     | 
    
         
            -
            		return Qundef;
         
     | 
| 
       38 
     | 
    
         
            -
            	    }
         
     | 
| 
       39 
     | 
    
         
            -
            	    if (Qundef == (clas = resolve_classname(clas, class_name))) {
         
     | 
| 
       40 
     | 
    
         
            -
            		return Qundef;
         
     | 
| 
       41 
     | 
    
         
            -
            	    }
         
     | 
| 
       42 
     | 
    
         
            -
            	    s = class_name;
         
     | 
| 
       43 
     | 
    
         
            -
            	} else if (end <= s) {
         
     | 
| 
       44 
     | 
    
         
            -
            	    return Qundef;
         
     | 
| 
       45 
     | 
    
         
            -
            	} else {
         
     | 
| 
       46 
     | 
    
         
            -
            	    *s++ = *n;
         
     | 
| 
       47 
     | 
    
         
            -
            	}
         
     | 
| 
       48 
     | 
    
         
            -
                }
         
     | 
| 
       49 
     | 
    
         
            -
                *s = '\0';
         
     | 
| 
       50 
     | 
    
         
            -
                return resolve_classname(clas, class_name);
         
     | 
| 
       51 
     | 
    
         
            -
            }
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
9 
     | 
    
         
             
            Hook
         
     | 
| 
       54 
     | 
    
         
            -
            hook_create(Method method, const char *pattern,  
     | 
| 
      
 10 
     | 
    
         
            +
            hook_create(Method method, const char *pattern, void *handler, HookType type) {
         
     | 
| 
       55 
11 
     | 
    
         
             
                Hook	hook = (Hook)malloc(sizeof(struct _Hook));
         
     | 
| 
       56 
12 
     | 
    
         | 
| 
       57 
13 
     | 
    
         
             
                if (NULL != hook) {
         
     | 
| 
         @@ -60,67 +16,52 @@ hook_create(Method method, const char *pattern, VALUE handler) { 
     | 
|
| 
       60 
16 
     | 
    
         
             
            	    pattern = "";
         
     | 
| 
       61 
17 
     | 
    
         
             
            	}
         
     | 
| 
       62 
18 
     | 
    
         
             
            	hook->next = NULL;
         
     | 
| 
       63 
     | 
    
         
            -
            	if (T_STRING == rb_type(handler)) {
         
     | 
| 
       64 
     | 
    
         
            -
            	    handler = resolve_classpath(StringValuePtr(handler), RSTRING_LEN(handler));
         
     | 
| 
       65 
     | 
    
         
            -
            	    // TBD does class handle it or should an instance be made?
         
     | 
| 
       66 
     | 
    
         
            -
            	    //  
         
     | 
| 
       67 
     | 
    
         
            -
            	}
         
     | 
| 
       68 
     | 
    
         
            -
            	hook->handler = handler;
         
     | 
| 
       69 
     | 
    
         
            -
            	rb_gc_register_address(&handler);
         
     | 
| 
       70 
19 
     | 
    
         
             
            	hook->pattern = strdup(pattern);
         
     | 
| 
       71 
20 
     | 
    
         
             
            	DEBUG_ALLOC(mem_hook_pattern, hook->pattern)
         
     | 
| 
       72 
21 
     | 
    
         
             
            	hook->method = method;
         
     | 
| 
       73 
     | 
    
         
            -
            	 
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            	} else if (rb_respond_to(handler, rb_intern("call"))) {
         
     | 
| 
       76 
     | 
    
         
            -
            	    hook->type = RACK_HOOK;
         
     | 
| 
       77 
     | 
    
         
            -
            	} else if (rb_respond_to(handler, rb_intern("create")) &&
         
     | 
| 
       78 
     | 
    
         
            -
            		   rb_respond_to(handler, rb_intern("read")) &&
         
     | 
| 
       79 
     | 
    
         
            -
            		   rb_respond_to(handler, rb_intern("update")) &&
         
     | 
| 
       80 
     | 
    
         
            -
            		   rb_respond_to(handler, rb_intern("delete"))) {
         
     | 
| 
       81 
     | 
    
         
            -
            	    hook->type = WAB_HOOK;
         
     | 
| 
       82 
     | 
    
         
            -
            	} else {
         
     | 
| 
       83 
     | 
    
         
            -
            	    rb_raise(rb_eArgError, "handler does not have a on_request, or call method nor is it a WAB::Controller");
         
     | 
| 
       84 
     | 
    
         
            -
            	}
         
     | 
| 
      
 22 
     | 
    
         
            +
            	hook->handler = handler;
         
     | 
| 
      
 23 
     | 
    
         
            +
            	hook->type = type;
         
     | 
| 
       85 
24 
     | 
    
         
             
                }
         
     | 
| 
       86 
25 
     | 
    
         
             
                return hook;
         
     | 
| 
       87 
26 
     | 
    
         
             
            }
         
     | 
| 
       88 
27 
     | 
    
         | 
| 
       89 
28 
     | 
    
         
             
            void
         
     | 
| 
       90 
29 
     | 
    
         
             
            hook_destroy(Hook hook) {
         
     | 
| 
       91 
     | 
    
         
            -
                DEBUG_FREE(mem_hook_pattern, hook->pattern)
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
                DEBUG_FREE(mem_hook_pattern, hook->pattern);
         
     | 
| 
      
 31 
     | 
    
         
            +
                DEBUG_FREE(mem_hook, hook)
         
     | 
| 
       93 
32 
     | 
    
         
             
                free(hook->pattern);
         
     | 
| 
       94 
33 
     | 
    
         
             
                free(hook);
         
     | 
| 
       95 
34 
     | 
    
         
             
            }
         
     | 
| 
       96 
35 
     | 
    
         | 
| 
       97 
36 
     | 
    
         
             
            bool
         
     | 
| 
       98 
     | 
    
         
            -
            hook_match(Hook hook, Method method, const  
     | 
| 
      
 37 
     | 
    
         
            +
            hook_match(Hook hook, Method method, const Seg path) {
         
     | 
| 
       99 
38 
     | 
    
         
             
                const char	*pat = hook->pattern;
         
     | 
| 
      
 39 
     | 
    
         
            +
                char	*p = path->start;
         
     | 
| 
      
 40 
     | 
    
         
            +
                char	*end = path->end;
         
     | 
| 
       100 
41 
     | 
    
         | 
| 
       101 
42 
     | 
    
         
             
                if (method != hook->method && ALL != hook->method) {
         
     | 
| 
       102 
43 
     | 
    
         
             
            	return false;
         
     | 
| 
       103 
44 
     | 
    
         
             
                }
         
     | 
| 
       104 
     | 
    
         
            -
                for (; '\0' != *pat &&  
     | 
| 
       105 
     | 
    
         
            -
            	if (* 
     | 
| 
       106 
     | 
    
         
            -
            	     
     | 
| 
      
 45 
     | 
    
         
            +
                for (; '\0' != *pat && p < end; pat++) {
         
     | 
| 
      
 46 
     | 
    
         
            +
            	if (*p == *pat) {
         
     | 
| 
      
 47 
     | 
    
         
            +
            	    p++;
         
     | 
| 
       107 
48 
     | 
    
         
             
            	} else if ('*' == *pat) {
         
     | 
| 
       108 
49 
     | 
    
         
             
            	    if ('*' == *(pat + 1)) {
         
     | 
| 
       109 
50 
     | 
    
         
             
            		return true;
         
     | 
| 
       110 
51 
     | 
    
         
             
            	    }
         
     | 
| 
       111 
     | 
    
         
            -
            	    for (;  
     | 
| 
      
 52 
     | 
    
         
            +
            	    for (; p < end && '/' != *p; p++) {
         
     | 
| 
       112 
53 
     | 
    
         
             
            	    }
         
     | 
| 
       113 
54 
     | 
    
         
             
            	} else {
         
     | 
| 
       114 
55 
     | 
    
         
             
            	    break;
         
     | 
| 
       115 
56 
     | 
    
         
             
            	}
         
     | 
| 
       116 
57 
     | 
    
         
             
                }
         
     | 
| 
       117 
     | 
    
         
            -
                return '\0' == *pat &&  
     | 
| 
      
 58 
     | 
    
         
            +
                return '\0' == *pat && p == end;
         
     | 
| 
       118 
59 
     | 
    
         
             
            }
         
     | 
| 
       119 
60 
     | 
    
         | 
| 
       120 
61 
     | 
    
         
             
            Hook
         
     | 
| 
       121 
     | 
    
         
            -
            hook_find(Hook hook, Method method, const  
     | 
| 
      
 62 
     | 
    
         
            +
            hook_find(Hook hook, Method method, const Seg path) {
         
     | 
| 
       122 
63 
     | 
    
         
             
                for (; NULL != hook; hook = hook->next) {
         
     | 
| 
       123 
     | 
    
         
            -
            	if (hook_match(hook, method, path 
     | 
| 
      
 64 
     | 
    
         
            +
            	if (hook_match(hook, method, path)) {
         
     | 
| 
       124 
65 
     | 
    
         
             
            	    return hook;
         
     | 
| 
       125 
66 
     | 
    
         
             
            	}
         
     | 
| 
       126 
67 
     | 
    
         
             
                }
         
     |