agoo 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of agoo might be problematic. Click here for more details.

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
@@ -0,0 +1,10 @@
1
+ // Copyright 2009, 2015, 2018, 2016 by Peter Ohler, All Rights Reserved
2
+
3
+ #ifndef __AGOO_DTIME_H__
4
+ #define __AGOO_DTIME_H__
5
+
6
+ extern double dtime(void);
7
+ extern double dsleep(double t);
8
+ extern double dwait(double t);
9
+
10
+ #endif /* __AGOO_DTIME_H__ */
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__
@@ -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__