agoo 0.9.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 +7 -0
 - data/LICENSE +21 -0
 - data/README.md +61 -0
 - data/ext/agoo/agoo.c +19 -0
 - data/ext/agoo/con.c +515 -0
 - data/ext/agoo/con.h +46 -0
 - data/ext/agoo/dtime.c +52 -0
 - data/ext/agoo/dtime.h +10 -0
 - data/ext/agoo/err.c +78 -0
 - data/ext/agoo/err.h +48 -0
 - data/ext/agoo/error_stream.c +92 -0
 - data/ext/agoo/error_stream.h +13 -0
 - data/ext/agoo/extconf.rb +13 -0
 - data/ext/agoo/hook.c +74 -0
 - data/ext/agoo/hook.h +33 -0
 - data/ext/agoo/http.c +617 -0
 - data/ext/agoo/http.h +13 -0
 - data/ext/agoo/log.c +497 -0
 - data/ext/agoo/log.h +106 -0
 - data/ext/agoo/log_queue.h +30 -0
 - data/ext/agoo/page.c +342 -0
 - data/ext/agoo/page.h +39 -0
 - data/ext/agoo/queue.c +191 -0
 - data/ext/agoo/queue.h +39 -0
 - data/ext/agoo/request.c +563 -0
 - data/ext/agoo/request.h +36 -0
 - data/ext/agoo/res.c +38 -0
 - data/ext/agoo/res.h +28 -0
 - data/ext/agoo/response.c +271 -0
 - data/ext/agoo/response.h +33 -0
 - data/ext/agoo/server.c +891 -0
 - data/ext/agoo/server.h +47 -0
 - data/ext/agoo/text.c +66 -0
 - data/ext/agoo/text.h +24 -0
 - data/ext/agoo/types.h +18 -0
 - data/lib/agoo.rb +9 -0
 - data/lib/agoo/version.rb +5 -0
 - data/test/base_handler_test.rb +170 -0
 - data/test/log_test.rb +269 -0
 - data/test/rack_handler_test.rb +147 -0
 - data/test/static_test.rb +81 -0
 - data/test/tests.rb +8 -0
 - metadata +159 -0
 
    
        data/ext/agoo/con.h
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #ifndef __AGOO_CON_H__
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define __AGOO_CON_H__
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #include <poll.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include <stdbool.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
            #include <stdint.h>
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            #include "err.h"
         
     | 
| 
      
 11 
     | 
    
         
            +
            #include "request.h"
         
     | 
| 
      
 12 
     | 
    
         
            +
            #include "response.h"
         
     | 
| 
      
 13 
     | 
    
         
            +
            #include "server.h"
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            #define MAX_HEADER_SIZE	8192
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            typedef struct _Con {
         
     | 
| 
      
 18 
     | 
    
         
            +
                int			sock;
         
     | 
| 
      
 19 
     | 
    
         
            +
                struct pollfd	*pp;
         
     | 
| 
      
 20 
     | 
    
         
            +
                char		id[32];
         
     | 
| 
      
 21 
     | 
    
         
            +
                uint64_t		iid;
         
     | 
| 
      
 22 
     | 
    
         
            +
                char		buf[MAX_HEADER_SIZE];
         
     | 
| 
      
 23 
     | 
    
         
            +
                size_t		bcnt;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                ssize_t		msize; // size of complete message
         
     | 
| 
      
 26 
     | 
    
         
            +
                ssize_t		mcnt;  // how much has been read so far
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                ssize_t		wcnt;  // how much has been written
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                Server		server;
         
     | 
| 
      
 31 
     | 
    
         
            +
                double		timeout;
         
     | 
| 
      
 32 
     | 
    
         
            +
                bool		closing;
         
     | 
| 
      
 33 
     | 
    
         
            +
                Req			req;
         
     | 
| 
      
 34 
     | 
    
         
            +
                Res			res_head;
         
     | 
| 
      
 35 
     | 
    
         
            +
                Res			res_tail;
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                //FEval		eval;
         
     | 
| 
      
 38 
     | 
    
         
            +
            } *Con;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            extern Con		con_create(Err err, Server server, int sock, uint64_t id);
         
     | 
| 
      
 41 
     | 
    
         
            +
            extern void		con_destroy(Con c);
         
     | 
| 
      
 42 
     | 
    
         
            +
            extern const char*	con_header_value(const char *header, int hlen, const char *key, int *vlen);
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            extern void*		con_loop(void *ctx);
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            #endif /* __AGOO_CON_H__ */
         
     | 
    
        data/ext/agoo/dtime.c
    ADDED
    
    | 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright 2009, 2015, 2016, 2018 by Peter Ohler, All Rights Reserved
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #include <time.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <sys/time.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <errno.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            #include "dtime.h"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #define MIN_SLEEP	(1.0 / (double)CLOCKS_PER_SEC)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            double
         
     | 
| 
      
 12 
     | 
    
         
            +
            dtime() {
         
     | 
| 
      
 13 
     | 
    
         
            +
                struct timeval	tv;
         
     | 
| 
      
 14 
     | 
    
         
            +
                struct timezone	tz;
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                gettimeofday(&tv, &tz);
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
         
     | 
| 
      
 19 
     | 
    
         
            +
            }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            double
         
     | 
| 
      
 22 
     | 
    
         
            +
            dsleep(double t) {
         
     | 
| 
      
 23 
     | 
    
         
            +
                struct timespec	req, rem;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                if (MIN_SLEEP > t) {
         
     | 
| 
      
 26 
     | 
    
         
            +
            	t = MIN_SLEEP;
         
     | 
| 
      
 27 
     | 
    
         
            +
                }
         
     | 
| 
      
 28 
     | 
    
         
            +
                req.tv_sec = (time_t)t;
         
     | 
| 
      
 29 
     | 
    
         
            +
                req.tv_nsec = (long)(1000000000.0 * (t - (double)req.tv_sec));
         
     | 
| 
      
 30 
     | 
    
         
            +
                if (nanosleep(&req, &rem) == -1 && EINTR == errno) {
         
     | 
| 
      
 31 
     | 
    
         
            +
            	return (double)rem.tv_sec + (double)rem.tv_nsec / 1000000000.0;
         
     | 
| 
      
 32 
     | 
    
         
            +
                }
         
     | 
| 
      
 33 
     | 
    
         
            +
                return 0.0;
         
     | 
| 
      
 34 
     | 
    
         
            +
            }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            double
         
     | 
| 
      
 37 
     | 
    
         
            +
            dwait(double t) {
         
     | 
| 
      
 38 
     | 
    
         
            +
                double	end = dtime() + t;
         
     | 
| 
      
 39 
     | 
    
         
            +
                
         
     | 
| 
      
 40 
     | 
    
         
            +
                if (MIN_SLEEP < t) {
         
     | 
| 
      
 41 
     | 
    
         
            +
            	struct timespec	req, rem;
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            	t -= MIN_SLEEP;
         
     | 
| 
      
 44 
     | 
    
         
            +
            	req.tv_sec = (time_t)t;
         
     | 
| 
      
 45 
     | 
    
         
            +
            	req.tv_nsec = (long)(1000000000.0 * (t - (double)req.tv_sec));
         
     | 
| 
      
 46 
     | 
    
         
            +
            	nanosleep(&req, &rem);
         
     | 
| 
      
 47 
     | 
    
         
            +
                }
         
     | 
| 
      
 48 
     | 
    
         
            +
                while (dtime() < end) {
         
     | 
| 
      
 49 
     | 
    
         
            +
            	continue;
         
     | 
| 
      
 50 
     | 
    
         
            +
                }
         
     | 
| 
      
 51 
     | 
    
         
            +
                return 0.0;
         
     | 
| 
      
 52 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/agoo/dtime.h
    ADDED
    
    
    
        data/ext/agoo/err.c
    ADDED
    
    | 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #include <stdarg.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            #include "err.h"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #ifdef PLATFORM_LINUX
         
     | 
| 
      
 10 
     | 
    
         
            +
            #pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
         
     | 
| 
      
 11 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            int
         
     | 
| 
      
 14 
     | 
    
         
            +
            err_set(Err err, int code, const char *fmt, ...) {
         
     | 
| 
      
 15 
     | 
    
         
            +
                va_list	ap;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                va_start(ap, fmt);
         
     | 
| 
      
 18 
     | 
    
         
            +
                vsnprintf(err->msg, sizeof(err->msg), fmt, ap);
         
     | 
| 
      
 19 
     | 
    
         
            +
                va_end(ap);
         
     | 
| 
      
 20 
     | 
    
         
            +
                err->code = code;
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                return err->code;
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            int
         
     | 
| 
      
 26 
     | 
    
         
            +
            err_no(Err err, const char *fmt, ...) {
         
     | 
| 
      
 27 
     | 
    
         
            +
                int	cnt = 0;
         
     | 
| 
      
 28 
     | 
    
         
            +
                
         
     | 
| 
      
 29 
     | 
    
         
            +
                if (NULL != fmt) {
         
     | 
| 
      
 30 
     | 
    
         
            +
            	va_list	ap;
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            	va_start(ap, fmt);
         
     | 
| 
      
 33 
     | 
    
         
            +
            	cnt = vsnprintf(err->msg, sizeof(err->msg), fmt, ap);
         
     | 
| 
      
 34 
     | 
    
         
            +
            	va_end(ap);
         
     | 
| 
      
 35 
     | 
    
         
            +
                }
         
     | 
| 
      
 36 
     | 
    
         
            +
                if (cnt < (int)sizeof(err->msg) + 2 && 0 <= cnt) {
         
     | 
| 
      
 37 
     | 
    
         
            +
            	err->msg[cnt] = ' ';
         
     | 
| 
      
 38 
     | 
    
         
            +
            	cnt++;
         
     | 
| 
      
 39 
     | 
    
         
            +
            	strncpy(err->msg + cnt, strerror(errno), sizeof(err->msg) - cnt);
         
     | 
| 
      
 40 
     | 
    
         
            +
            	err->msg[sizeof(err->msg) - 1] = '\0';
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                err->code = errno;
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                return err->code;
         
     | 
| 
      
 45 
     | 
    
         
            +
            }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            void
         
     | 
| 
      
 48 
     | 
    
         
            +
            err_clear(Err err) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                err->code = ERR_OK;
         
     | 
| 
      
 50 
     | 
    
         
            +
                *err->msg = '\0';
         
     | 
| 
      
 51 
     | 
    
         
            +
            }
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            const char*
         
     | 
| 
      
 54 
     | 
    
         
            +
            err_str(ErrCode code) {
         
     | 
| 
      
 55 
     | 
    
         
            +
                const char	*str = NULL;
         
     | 
| 
      
 56 
     | 
    
         
            +
                
         
     | 
| 
      
 57 
     | 
    
         
            +
                if (code <= ELAST) {
         
     | 
| 
      
 58 
     | 
    
         
            +
            	str = strerror(code);
         
     | 
| 
      
 59 
     | 
    
         
            +
                }
         
     | 
| 
      
 60 
     | 
    
         
            +
                if (NULL == str) {
         
     | 
| 
      
 61 
     | 
    
         
            +
            	switch (code) {
         
     | 
| 
      
 62 
     | 
    
         
            +
            	case ERR_PARSE:		str = "parse error";		break;
         
     | 
| 
      
 63 
     | 
    
         
            +
            	case ERR_READ:		str = "read failed";		break;
         
     | 
| 
      
 64 
     | 
    
         
            +
            	case ERR_WRITE:		str = "write failed";		break;
         
     | 
| 
      
 65 
     | 
    
         
            +
            	case ERR_ARG:		str = "invalid argument";	break;
         
     | 
| 
      
 66 
     | 
    
         
            +
            	case ERR_NOT_FOUND:	str = "not found";		break;
         
     | 
| 
      
 67 
     | 
    
         
            +
            	case ERR_THREAD:	str = "thread error";		break;
         
     | 
| 
      
 68 
     | 
    
         
            +
            	case ERR_NETWORK:	str = "network error";		break;
         
     | 
| 
      
 69 
     | 
    
         
            +
            	case ERR_LOCK:		str = "lock error";		break;
         
     | 
| 
      
 70 
     | 
    
         
            +
            	case ERR_FREE:		str = "already freed";		break;
         
     | 
| 
      
 71 
     | 
    
         
            +
            	case ERR_IN_USE:	str = "in use";			break;
         
     | 
| 
      
 72 
     | 
    
         
            +
            	case ERR_TOO_MANY:	str = "too many";		break;
         
     | 
| 
      
 73 
     | 
    
         
            +
            	case ERR_TYPE:		str = "type error";		break;
         
     | 
| 
      
 74 
     | 
    
         
            +
            	default:		str = "unknown error";		break;
         
     | 
| 
      
 75 
     | 
    
         
            +
            	}
         
     | 
| 
      
 76 
     | 
    
         
            +
                }
         
     | 
| 
      
 77 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 78 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/agoo/err.h
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #ifndef __AGOO_ERR_H__
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define __AGOO_ERR_H__
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #include <errno.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #ifndef ELAST
         
     | 
| 
      
 9 
     | 
    
         
            +
            #define ELAST 300
         
     | 
| 
      
 10 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            #define ERR_INIT	{ 0, { 0 } }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            typedef enum {
         
     | 
| 
      
 15 
     | 
    
         
            +
                ERR_OK	= 0,
         
     | 
| 
      
 16 
     | 
    
         
            +
                ERR_MEMORY	= ENOMEM,
         
     | 
| 
      
 17 
     | 
    
         
            +
                ERR_DENIED	= EACCES,
         
     | 
| 
      
 18 
     | 
    
         
            +
                ERR_IMPL	= ENOSYS,
         
     | 
| 
      
 19 
     | 
    
         
            +
                ERR_PARSE	= ELAST + 1,
         
     | 
| 
      
 20 
     | 
    
         
            +
                ERR_READ,
         
     | 
| 
      
 21 
     | 
    
         
            +
                ERR_WRITE,
         
     | 
| 
      
 22 
     | 
    
         
            +
                ERR_OVERFLOW,
         
     | 
| 
      
 23 
     | 
    
         
            +
                ERR_ARG,
         
     | 
| 
      
 24 
     | 
    
         
            +
                ERR_NOT_FOUND,
         
     | 
| 
      
 25 
     | 
    
         
            +
                ERR_THREAD,
         
     | 
| 
      
 26 
     | 
    
         
            +
                ERR_NETWORK,
         
     | 
| 
      
 27 
     | 
    
         
            +
                ERR_LOCK,
         
     | 
| 
      
 28 
     | 
    
         
            +
                ERR_FREE,
         
     | 
| 
      
 29 
     | 
    
         
            +
                ERR_IN_USE,
         
     | 
| 
      
 30 
     | 
    
         
            +
                ERR_TOO_MANY,
         
     | 
| 
      
 31 
     | 
    
         
            +
                ERR_TYPE,
         
     | 
| 
      
 32 
     | 
    
         
            +
                ERR_LAST
         
     | 
| 
      
 33 
     | 
    
         
            +
            } ErrCode;
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            // The struct used to report errors or status after a function returns. The
         
     | 
| 
      
 36 
     | 
    
         
            +
            // struct must be initialized before use as most calls that take an err
         
     | 
| 
      
 37 
     | 
    
         
            +
            // argument will return immediately if an error has already occurred.
         
     | 
| 
      
 38 
     | 
    
         
            +
            typedef struct _Err {
         
     | 
| 
      
 39 
     | 
    
         
            +
                int		code;
         
     | 
| 
      
 40 
     | 
    
         
            +
                char	msg[256];
         
     | 
| 
      
 41 
     | 
    
         
            +
            } *Err;
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            extern int		err_set(Err err, int code, const char *fmt, ...);
         
     | 
| 
      
 44 
     | 
    
         
            +
            extern int		err_no(Err err, const char *fmt, ...);
         
     | 
| 
      
 45 
     | 
    
         
            +
            extern const char*	err_str(ErrCode code);
         
     | 
| 
      
 46 
     | 
    
         
            +
            extern void		err_clear(Err err);
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            #endif /* __AGOO_ERR_H__ */
         
     | 
| 
         @@ -0,0 +1,92 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #include "error_stream.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include "text.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            static VALUE	es_class = Qundef;
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            typedef struct _ErrorStream {
         
     | 
| 
      
 9 
     | 
    
         
            +
                Server	server;
         
     | 
| 
      
 10 
     | 
    
         
            +
                Text	text;
         
     | 
| 
      
 11 
     | 
    
         
            +
            } *ErrorStream;
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            static void
         
     | 
| 
      
 14 
     | 
    
         
            +
            es_free(void *ptr) {
         
     | 
| 
      
 15 
     | 
    
         
            +
                ErrorStream	es = (ErrorStream)ptr;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                free(es->text); // allocated with malloc
         
     | 
| 
      
 18 
     | 
    
         
            +
                xfree(ptr);
         
     | 
| 
      
 19 
     | 
    
         
            +
            }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 22 
     | 
    
         
            +
            error_stream_new(Server server) {
         
     | 
| 
      
 23 
     | 
    
         
            +
                ErrorStream	es = ALLOC(struct _ErrorStream);
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                es->text = text_allocate(1024);
         
     | 
| 
      
 26 
     | 
    
         
            +
                es->server = server;
         
     | 
| 
      
 27 
     | 
    
         
            +
                
         
     | 
| 
      
 28 
     | 
    
         
            +
                return Data_Wrap_Struct(es_class, NULL, es_free, es);
         
     | 
| 
      
 29 
     | 
    
         
            +
            }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            /* Document-method: puts
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
             * call-seq: puts(str)
         
     | 
| 
      
 34 
     | 
    
         
            +
             *
         
     | 
| 
      
 35 
     | 
    
         
            +
             * Write the _str_ to the stream along with a newline character, accumulating
         
     | 
| 
      
 36 
     | 
    
         
            +
             * it until _flush_ is called.
         
     | 
| 
      
 37 
     | 
    
         
            +
             */
         
     | 
| 
      
 38 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 39 
     | 
    
         
            +
            es_puts(VALUE self, VALUE str) {
         
     | 
| 
      
 40 
     | 
    
         
            +
                ErrorStream	es = (ErrorStream)DATA_PTR(self);
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                es->text = text_append(es->text, StringValuePtr(str), RSTRING_LEN(str));
         
     | 
| 
      
 43 
     | 
    
         
            +
                es->text = text_append(es->text, "\n", 1);
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 46 
     | 
    
         
            +
            }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            /* Document-method: write
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
             * call-seq: write(str)
         
     | 
| 
      
 51 
     | 
    
         
            +
             *
         
     | 
| 
      
 52 
     | 
    
         
            +
             * Write the _str_ to the stream, accumulating it until _flush_ is called.
         
     | 
| 
      
 53 
     | 
    
         
            +
             */
         
     | 
| 
      
 54 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 55 
     | 
    
         
            +
            es_write(VALUE self, VALUE str) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                ErrorStream	es = (ErrorStream)DATA_PTR(self);
         
     | 
| 
      
 57 
     | 
    
         
            +
                int		cnt = RSTRING_LEN(str);
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                es->text = text_append(es->text, StringValuePtr(str), cnt);
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                return INT2NUM(cnt);
         
     | 
| 
      
 62 
     | 
    
         
            +
            }
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            /* Document-method: flush
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
             * call-seq: flush()
         
     | 
| 
      
 67 
     | 
    
         
            +
             *
         
     | 
| 
      
 68 
     | 
    
         
            +
             * Flushs the accumulated text in the stream as an error log entry.
         
     | 
| 
      
 69 
     | 
    
         
            +
             */
         
     | 
| 
      
 70 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 71 
     | 
    
         
            +
            es_flush(VALUE self) {
         
     | 
| 
      
 72 
     | 
    
         
            +
                ErrorStream	es = (ErrorStream)DATA_PTR(self);
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                log_cat(&es->server->error_cat, "%s", es->text->text);
         
     | 
| 
      
 75 
     | 
    
         
            +
                es->text->len = 0;
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 78 
     | 
    
         
            +
            }
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            /* Document-class: Agoo::ErrorStream
         
     | 
| 
      
 81 
     | 
    
         
            +
             *
         
     | 
| 
      
 82 
     | 
    
         
            +
             * Used in a reqquest as the _rack.errors_ attribute. Writing to the stream
         
     | 
| 
      
 83 
     | 
    
         
            +
             * and flushing will make an error log entry.
         
     | 
| 
      
 84 
     | 
    
         
            +
             */
         
     | 
| 
      
 85 
     | 
    
         
            +
            void
         
     | 
| 
      
 86 
     | 
    
         
            +
            error_stream_init(VALUE mod) {
         
     | 
| 
      
 87 
     | 
    
         
            +
                es_class = rb_define_class_under(mod, "ErrorStream", rb_cObject);
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                rb_define_method(es_class, "puts", es_puts, 1);
         
     | 
| 
      
 90 
     | 
    
         
            +
                rb_define_method(es_class, "write", es_write, 1);
         
     | 
| 
      
 91 
     | 
    
         
            +
                rb_define_method(es_class, "flush", es_flush, 0);
         
     | 
| 
      
 92 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #ifndef __AGOO_ERROR_STREAM_H__
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define __AGOO_ERROR_STREAM_H__
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #include "server.h"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            extern void	error_stream_init(VALUE mod);
         
     | 
| 
      
 11 
     | 
    
         
            +
            extern VALUE	error_stream_new(Server server);
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            #endif // __AGOO_ERROR_STREAM_H__
         
     | 
    
        data/ext/agoo/extconf.rb
    ADDED
    
    | 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'mkmf'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rbconfig'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            extension_name = 'agoo'
         
     | 
| 
      
 5 
     | 
    
         
            +
            dir_config(extension_name)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            $CPPFLAGS += " -DPLATFORM_LINUX" if 'x86_64-linux' == RUBY_PLATFORM
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            create_makefile(File.join(extension_name, extension_name))
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            puts ">>>>> Created Makefile for #{RUBY_DESCRIPTION.split(' ')[0]} version #{RUBY_VERSION} on #{RUBY_PLATFORM} <<<<<"
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            %x{make clean}
         
     | 
    
        data/ext/agoo/hook.c
    ADDED
    
    | 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #include "hook.h"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Hook
         
     | 
| 
      
 9 
     | 
    
         
            +
            hook_create(Method method, const char *pattern, VALUE handler) {
         
     | 
| 
      
 10 
     | 
    
         
            +
                Hook	hook = (Hook)malloc(sizeof(struct _Hook));
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                if (NULL != hook) {
         
     | 
| 
      
 13 
     | 
    
         
            +
            	if (NULL == pattern) {
         
     | 
| 
      
 14 
     | 
    
         
            +
            	    pattern = "";
         
     | 
| 
      
 15 
     | 
    
         
            +
            	}
         
     | 
| 
      
 16 
     | 
    
         
            +
            	hook->next = NULL;
         
     | 
| 
      
 17 
     | 
    
         
            +
            	hook->handler = handler;
         
     | 
| 
      
 18 
     | 
    
         
            +
            	rb_gc_register_address(&handler);
         
     | 
| 
      
 19 
     | 
    
         
            +
            	hook->pattern = strdup(pattern);
         
     | 
| 
      
 20 
     | 
    
         
            +
            	hook->method = method;
         
     | 
| 
      
 21 
     | 
    
         
            +
            	if (rb_respond_to(handler, rb_intern("on_request"))) {
         
     | 
| 
      
 22 
     | 
    
         
            +
            	    hook->type = BASE_HOOK;
         
     | 
| 
      
 23 
     | 
    
         
            +
            	} else if (rb_respond_to(handler, rb_intern("call"))) {
         
     | 
| 
      
 24 
     | 
    
         
            +
            	    hook->type = RACK_HOOK;
         
     | 
| 
      
 25 
     | 
    
         
            +
            	} else if (rb_respond_to(handler, rb_intern("create")) &&
         
     | 
| 
      
 26 
     | 
    
         
            +
            		   rb_respond_to(handler, rb_intern("read")) &&
         
     | 
| 
      
 27 
     | 
    
         
            +
            		   rb_respond_to(handler, rb_intern("update")) &&
         
     | 
| 
      
 28 
     | 
    
         
            +
            		   rb_respond_to(handler, rb_intern("delete"))) {
         
     | 
| 
      
 29 
     | 
    
         
            +
            	    hook->type = WAB_HOOK;
         
     | 
| 
      
 30 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 31 
     | 
    
         
            +
            	    rb_raise(rb_eArgError, "handler does not have a on_request, or call method nor is it a WAB::Controller");
         
     | 
| 
      
 32 
     | 
    
         
            +
            	}
         
     | 
| 
      
 33 
     | 
    
         
            +
                }
         
     | 
| 
      
 34 
     | 
    
         
            +
                return hook;
         
     | 
| 
      
 35 
     | 
    
         
            +
            }
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            void
         
     | 
| 
      
 38 
     | 
    
         
            +
            hook_destroy(Hook hook) {
         
     | 
| 
      
 39 
     | 
    
         
            +
                free(hook->pattern);
         
     | 
| 
      
 40 
     | 
    
         
            +
                free(hook);
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            bool
         
     | 
| 
      
 44 
     | 
    
         
            +
            hook_match(Hook hook, Method method, const char *path, const char *pend) {
         
     | 
| 
      
 45 
     | 
    
         
            +
                const char	*pat = hook->pattern;
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                if (method != hook->method && ALL != hook->method) {
         
     | 
| 
      
 48 
     | 
    
         
            +
            	return false;
         
     | 
| 
      
 49 
     | 
    
         
            +
                }
         
     | 
| 
      
 50 
     | 
    
         
            +
                for (; '\0' != *pat && path < pend; pat++) {
         
     | 
| 
      
 51 
     | 
    
         
            +
            	if (*path == *pat) {
         
     | 
| 
      
 52 
     | 
    
         
            +
            	    path++;
         
     | 
| 
      
 53 
     | 
    
         
            +
            	} else if ('*' == *pat) {
         
     | 
| 
      
 54 
     | 
    
         
            +
            	    if ('*' == *(pat + 1)) {
         
     | 
| 
      
 55 
     | 
    
         
            +
            		return true;
         
     | 
| 
      
 56 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 57 
     | 
    
         
            +
            	    for (; path < pend && '/' != *path; path++) {
         
     | 
| 
      
 58 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 59 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 60 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 61 
     | 
    
         
            +
            	}
         
     | 
| 
      
 62 
     | 
    
         
            +
                }
         
     | 
| 
      
 63 
     | 
    
         
            +
                return '\0' == *pat && path == pend;
         
     | 
| 
      
 64 
     | 
    
         
            +
            }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            Hook
         
     | 
| 
      
 67 
     | 
    
         
            +
            hook_find(Hook hook, Method method, const char *path, const char *pend) {
         
     | 
| 
      
 68 
     | 
    
         
            +
                for (; NULL != hook; hook = hook->next) {
         
     | 
| 
      
 69 
     | 
    
         
            +
            	if (hook_match(hook, method, path, pend)) {
         
     | 
| 
      
 70 
     | 
    
         
            +
            	    return hook;
         
     | 
| 
      
 71 
     | 
    
         
            +
            	}
         
     | 
| 
      
 72 
     | 
    
         
            +
                }
         
     | 
| 
      
 73 
     | 
    
         
            +
                return NULL;
         
     | 
| 
      
 74 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/agoo/hook.h
    ADDED
    
    | 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // Copyright (c) 2018, Peter Ohler, All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #ifndef __AGOO_HOOK_H__
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define __AGOO_HOOK_H__
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #include <stdbool.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            #include "types.h"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            typedef enum {
         
     | 
| 
      
 13 
     | 
    
         
            +
                NO_HOOK	= '\0',
         
     | 
| 
      
 14 
     | 
    
         
            +
                RACK_HOOK	= 'R',
         
     | 
| 
      
 15 
     | 
    
         
            +
                BASE_HOOK	= 'B',
         
     | 
| 
      
 16 
     | 
    
         
            +
                WAB_HOOK	= 'W',
         
     | 
| 
      
 17 
     | 
    
         
            +
            } HookType;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            typedef struct _Hook {
         
     | 
| 
      
 20 
     | 
    
         
            +
                struct _Hook	*next;
         
     | 
| 
      
 21 
     | 
    
         
            +
                Method		method;
         
     | 
| 
      
 22 
     | 
    
         
            +
                VALUE		handler;
         
     | 
| 
      
 23 
     | 
    
         
            +
                char		*pattern;
         
     | 
| 
      
 24 
     | 
    
         
            +
                HookType		type;
         
     | 
| 
      
 25 
     | 
    
         
            +
            } *Hook;
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            extern Hook	hook_create(Method method, const char *pattern, VALUE handler);
         
     | 
| 
      
 28 
     | 
    
         
            +
            extern void	hook_destroy(Hook hook);
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            extern bool	hook_match(Hook hook, Method method, const char *path, const char *pend);
         
     | 
| 
      
 31 
     | 
    
         
            +
            extern Hook	hook_find(Hook hook, Method method, const char *path, const char *pend);
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #endif // __AGOO_HOOK_H__
         
     |