agoo 2.5.7 → 2.6.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.

Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +38 -0
  4. data/ext/agoo/agoo.c +11 -2
  5. data/ext/agoo/bind.c +15 -20
  6. data/ext/agoo/con.c +32 -25
  7. data/ext/agoo/debug.c +225 -162
  8. data/ext/agoo/debug.h +31 -51
  9. data/ext/agoo/doc.c +278 -5
  10. data/ext/agoo/doc.h +6 -1
  11. data/ext/agoo/err.c +1 -0
  12. data/ext/agoo/err.h +1 -0
  13. data/ext/agoo/error_stream.c +3 -6
  14. data/ext/agoo/gqlcobj.c +12 -0
  15. data/ext/agoo/gqlcobj.h +25 -0
  16. data/ext/agoo/gqleval.c +520 -0
  17. data/ext/agoo/gqleval.h +49 -0
  18. data/ext/agoo/gqlintro.c +1237 -97
  19. data/ext/agoo/gqlintro.h +8 -0
  20. data/ext/agoo/gqljson.c +460 -0
  21. data/ext/agoo/gqljson.h +15 -0
  22. data/ext/agoo/gqlvalue.c +679 -136
  23. data/ext/agoo/gqlvalue.h +29 -7
  24. data/ext/agoo/graphql.c +841 -362
  25. data/ext/agoo/graphql.h +180 -90
  26. data/ext/agoo/hook.c +8 -16
  27. data/ext/agoo/http.c +3 -4
  28. data/ext/agoo/log.c +22 -25
  29. data/ext/agoo/log.h +1 -0
  30. data/ext/agoo/page.c +24 -40
  31. data/ext/agoo/pub.c +23 -21
  32. data/ext/agoo/queue.c +2 -4
  33. data/ext/agoo/ready.c +9 -9
  34. data/ext/agoo/req.c +80 -5
  35. data/ext/agoo/req.h +2 -0
  36. data/ext/agoo/res.c +1 -3
  37. data/ext/agoo/rgraphql.c +753 -0
  38. data/ext/agoo/rresponse.c +9 -15
  39. data/ext/agoo/rserver.c +18 -17
  40. data/ext/agoo/sdl.c +1264 -120
  41. data/ext/agoo/sdl.h +8 -1
  42. data/ext/agoo/sectime.c +136 -0
  43. data/ext/agoo/sectime.h +19 -0
  44. data/ext/agoo/server.c +1 -3
  45. data/ext/agoo/subject.c +2 -4
  46. data/ext/agoo/text.c +124 -18
  47. data/ext/agoo/text.h +5 -1
  48. data/ext/agoo/upgraded.c +2 -4
  49. data/lib/agoo/version.rb +1 -1
  50. data/test/base_handler_test.rb +43 -40
  51. data/test/bind_test.rb +49 -48
  52. data/test/graphql_test.rb +1019 -0
  53. data/test/hijack_test.rb +1 -1
  54. data/test/rack_handler_test.rb +40 -34
  55. data/test/static_test.rb +33 -32
  56. metadata +17 -6
@@ -5,6 +5,13 @@
5
5
 
6
6
  #include "err.h"
7
7
 
8
- extern int sdl_parse(agooErr err, const char *str, int len);
8
+ struct _gqlVar;
9
+
10
+ extern int sdl_parse(agooErr err, const char *str, int len);
11
+
12
+ // Parse a execution definition.
13
+ extern struct _gqlDoc* sdl_parse_doc(agooErr err, const char *str, int len, struct _gqlVar *vars);
14
+
15
+ extern gqlVar gql_op_var_create(agooErr err, const char *name, gqlType type, gqlValue value);
9
16
 
10
17
  #endif // AGOO_SDL_H
@@ -0,0 +1,136 @@
1
+ // Copyright (c) 2019, Peter Ohler, All rights reserved.
2
+
3
+ #include <stdbool.h>
4
+ #include <stdint.h>
5
+ #include <stdio.h>
6
+ #include <string.h>
7
+ #include <time.h>
8
+
9
+ #include "sectime.h"
10
+
11
+ #define SECS_PER_DAY 86400LL
12
+ #define SECS_PER_YEAR 31536000LL
13
+ #define SECS_PER_LEAP 31622400LL
14
+ #define SECS_PER_QUAD_YEAR (SECS_PER_YEAR * 3 + SECS_PER_LEAP)
15
+ #define SECS_PER_CENT (SECS_PER_QUAD_YEAR * 24 + SECS_PER_YEAR * 4)
16
+ #define SECS_PER_LEAP_CENT (SECS_PER_CENT + SECS_PER_DAY)
17
+ #define SECS_PER_QUAD_CENT (SECS_PER_CENT * 4 + SECS_PER_DAY)
18
+
19
+ static int64_t eom_secs[] = {
20
+ 2678400, // January (31)
21
+ 5097600, // February (28) 2419200 2505600
22
+ 7776000, // March (31)
23
+ 10368000, // April (30 2592000
24
+ 13046400, // May (31)
25
+ 15638400, // June (30)
26
+ 18316800, // July (31)
27
+ 20995200, // August (31)
28
+ 23587200, // September (30)
29
+ 26265600, // October (31)
30
+ 28857600, // November (30)
31
+ 31536000, // December (31)
32
+ };
33
+
34
+ static int64_t eom_leap_secs[] = {
35
+ 2678400, // January (31)
36
+ 5184000, // February (28) 2419200 2505600
37
+ 7862400, // March (31)
38
+ 10454400, // April (30 2592000
39
+ 13132800, // May (31)
40
+ 15724800, // June (30)
41
+ 18403200, // July (31)
42
+ 21081600, // August (31)
43
+ 23673600, // September (30)
44
+ 26352000, // October (31)
45
+ 28944000, // November (30)
46
+ 31622400, // December (31)
47
+ };
48
+
49
+
50
+ void
51
+ agoo_sectime(int64_t secs, agooTime at) {
52
+ int64_t qc = 0;
53
+ int64_t c = 0;
54
+ int64_t qy = 0;
55
+ int64_t y = 0;
56
+ bool leap = false;
57
+ int64_t *ms;
58
+ int m;
59
+ int shift = 0;
60
+
61
+ secs += 62167219200LL; // normalize to first day of the year 0
62
+ if (secs < 0) {
63
+ shift = -secs / SECS_PER_QUAD_CENT;
64
+ shift++;
65
+ secs += shift * SECS_PER_QUAD_CENT;
66
+ }
67
+ qc = secs / SECS_PER_QUAD_CENT;
68
+ secs = secs - qc * SECS_PER_QUAD_CENT;
69
+ if (secs < SECS_PER_LEAP) {
70
+ leap = true;
71
+ } else if (secs < SECS_PER_QUAD_YEAR) {
72
+ if (SECS_PER_LEAP <= secs) {
73
+ secs -= SECS_PER_LEAP;
74
+ y = secs / SECS_PER_YEAR;
75
+ secs = secs - y * SECS_PER_YEAR;
76
+ y++;
77
+ leap = true;
78
+ }
79
+ } else if (secs < SECS_PER_LEAP_CENT) { // first century in 400 years is a leap century (one extra day)
80
+ qy = secs / SECS_PER_QUAD_YEAR;
81
+ secs = secs - qy * SECS_PER_QUAD_YEAR;
82
+ if (secs < SECS_PER_LEAP) {
83
+ leap = true;
84
+ } else {
85
+ secs -= SECS_PER_LEAP;
86
+ y = secs / SECS_PER_YEAR;
87
+ secs = secs - y * SECS_PER_YEAR;
88
+ y++;
89
+ }
90
+ } else {
91
+ secs -= SECS_PER_LEAP_CENT;
92
+ c = secs / SECS_PER_CENT;
93
+ secs = secs - c * SECS_PER_CENT;
94
+ c++;
95
+ if (secs < SECS_PER_YEAR * 4) {
96
+ y = secs / SECS_PER_YEAR;
97
+ secs = secs - y * SECS_PER_YEAR;
98
+ } else {
99
+ secs -= SECS_PER_YEAR * 4;
100
+ qy = secs / SECS_PER_QUAD_YEAR;
101
+ secs = secs - qy * SECS_PER_QUAD_YEAR;
102
+ qy++;
103
+ if (secs < SECS_PER_LEAP) {
104
+ leap = true;
105
+ } else {
106
+ secs -= SECS_PER_LEAP;
107
+ y = secs / SECS_PER_YEAR;
108
+ secs = secs - y * SECS_PER_YEAR;
109
+ y++;
110
+ }
111
+ }
112
+ }
113
+ at->year = (qc - shift) * 400 + c * 100 + qy * 4 + y;
114
+ if (leap) {
115
+ ms = eom_leap_secs;
116
+ } else {
117
+ ms = eom_secs;
118
+ }
119
+ for (m = 1; m <= 12; m++, ms++) {
120
+ if (secs < *ms) {
121
+ if (1 < m) {
122
+ secs -= *(ms - 1);
123
+ }
124
+ at->mon = m;
125
+ break;
126
+ }
127
+ }
128
+ at->day = secs / 86400LL;
129
+ secs = secs - (int64_t)at->day * 86400LL;
130
+ at->day++;
131
+ at->hour = secs / 3600LL;
132
+ secs = secs - (int64_t)at->hour * 3600LL;
133
+ at->min = secs / 60LL;
134
+ secs = secs - (int64_t)at->min * 60LL;
135
+ at->sec = secs;
136
+ }
@@ -0,0 +1,19 @@
1
+ // Copyright (c) 2019, Peter Ohler, All rights reserved.
2
+
3
+ #ifndef AGOO_SECTIME_H
4
+ #define AGOO_SECTIME_H
5
+
6
+ #include <stdint.h>
7
+
8
+ typedef struct _agooTime {
9
+ int sec;
10
+ int min;
11
+ int hour;
12
+ int day;
13
+ int mon;
14
+ int year;
15
+ } *agooTime;
16
+
17
+ extern void agoo_sectime(int64_t secs, agooTime at);
18
+
19
+ #endif /* AGOO_SECTIME_H */
@@ -72,8 +72,6 @@ listen_loop(void *x) {
72
72
  uint64_t cnt = 0;
73
73
  agooBind b;
74
74
 
75
- // TBD support multiple sockets, count binds, allocate pollfd, setup
76
- //
77
75
  for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++, pcnt++) {
78
76
  p->fd = b->fd;
79
77
  p->events = POLLIN;
@@ -156,7 +154,7 @@ agoo_server_start(agooErr err, const char *app_name, const char *version) {
156
154
  agoo_server.con_loops = agoo_conloop_create(err, 0);
157
155
  agoo_server.loop_cnt = 1;
158
156
  xcnt++;
159
-
157
+
160
158
  // If the eval thread count is 1 that implies the eval load is low so
161
159
  // might as well create the maximum number of con threads as is
162
160
  // reasonable.
@@ -9,10 +9,9 @@
9
9
 
10
10
  agooSubject
11
11
  agoo_subject_create(const char *pattern, int plen) {
12
- agooSubject subject = (agooSubject)malloc(sizeof(struct _agooSubject) - 7 + plen);
12
+ agooSubject subject = (agooSubject)AGOO_MALLOC(sizeof(struct _agooSubject) - 7 + plen);
13
13
 
14
14
  if (NULL != subject) {
15
- DEBUG_ALLOC(mem_subject, subject);
16
15
  subject->next = NULL;
17
16
  memcpy(subject->pattern, pattern, plen);
18
17
  subject->pattern[plen] = '\0';
@@ -22,8 +21,7 @@ agoo_subject_create(const char *pattern, int plen) {
22
21
 
23
22
  void
24
23
  agoo_subject_destroy(agooSubject subject) {
25
- DEBUG_FREE(mem_subject, subject);
26
- free(subject);
24
+ AGOO_FREE(subject);
27
25
  }
28
26
 
29
27
  bool
@@ -1,18 +1,52 @@
1
1
  // Copyright 2016, 2018 by Peter Ohler, All Rights Reserved
2
2
 
3
3
  #include <stdio.h>
4
+ #include <stdint.h>
4
5
  #include <stdlib.h>
5
6
  #include <string.h>
6
7
 
7
8
  #include "debug.h"
8
9
  #include "text.h"
9
10
 
11
+ static const char hex_chars[17] = "0123456789abcdef";
12
+
13
+ static char json_chars[256] = "\
14
+ 66666666222622666666666666666666\
15
+ 11211111111111111111111111111111\
16
+ 11111111111111111111111111112111\
17
+ 11111111111111111111111111111111\
18
+ 11111111111111111111111111111111\
19
+ 11111111111111111111111111111111\
20
+ 11111111111111111111111111111111\
21
+ 11111111111111111111111111111111";
22
+
23
+ static void
24
+ dump_hex(char *s, uint8_t c) {
25
+ uint8_t d = (c >> 4) & 0x0F;
26
+
27
+ *s++ = hex_chars[d];
28
+ d = c & 0x0F;
29
+ *s++ = hex_chars[d];
30
+ }
31
+
32
+ static size_t
33
+ json_size(const char *str, size_t len) {
34
+ uint8_t *u = (uint8_t*)str;
35
+ size_t size = 0;
36
+ size_t i = len;
37
+
38
+ for (; 0 < i; u++, i--) {
39
+ size += json_chars[*u];
40
+ }
41
+ return size - len * (size_t)'0';
42
+ }
43
+
44
+
10
45
  agooText
11
46
  agoo_text_create(const char *str, int len) {
12
- agooText t = (agooText)malloc(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
47
+ agooText t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
13
48
 
14
49
  if (NULL != t) {
15
- DEBUG_ALLOC(mem_text, t)
16
50
  t->len = len;
17
51
  t->alen = len;
18
52
  t->bin = false;
@@ -25,10 +59,9 @@ agoo_text_create(const char *str, int len) {
25
59
 
26
60
  agooText
27
61
  agoo_text_dup(agooText t0) {
28
- agooText t = (agooText)malloc(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + t0->alen + 1);
62
+ agooText t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + t0->alen + 1);
29
63
 
30
64
  if (NULL != t) {
31
- DEBUG_ALLOC(mem_text, t)
32
65
  t->len = t0->len;
33
66
  t->alen = t0->alen;
34
67
  t->bin = false;
@@ -40,10 +73,9 @@ agoo_text_dup(agooText t0) {
40
73
 
41
74
  agooText
42
75
  agoo_text_allocate(int len) {
43
- agooText t = (agooText)malloc(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
76
+ agooText t = (agooText)AGOO_MALLOC(sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + len + 1);
44
77
 
45
78
  if (NULL != t) {
46
- DEBUG_ALLOC(mem_text, t)
47
79
  t->len = 0;
48
80
  t->alen = len;
49
81
  t->bin = false;
@@ -61,8 +93,7 @@ agoo_text_ref(agooText t) {
61
93
  void
62
94
  agoo_text_release(agooText t) {
63
95
  if (1 >= atomic_fetch_sub(&t->ref_cnt, 1)) {
64
- DEBUG_FREE(mem_text, t);
65
- free(t);
96
+ AGOO_FREE(t);
66
97
  }
67
98
  }
68
99
 
@@ -74,13 +105,10 @@ agoo_text_append(agooText t, const char *s, int len) {
74
105
  if (t->alen <= t->len + len) {
75
106
  long new_len = t->alen + len + t->alen / 2;
76
107
  size_t size = sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + new_len + 1;
77
- #ifdef MEM_DEBUG
78
- agooText t0 = t;
79
- #endif
80
- if (NULL == (t = (agooText)realloc(t, size))) {
108
+
109
+ if (NULL == (t = (agooText)AGOO_REALLOC(t, size))) {
81
110
  return NULL;
82
111
  }
83
- DEBUG_REALLOC(mem_text, t0, t);
84
112
  t->alen = new_len;
85
113
  }
86
114
  memcpy(t->text + t->len, s, len);
@@ -90,6 +118,24 @@ agoo_text_append(agooText t, const char *s, int len) {
90
118
  return t;
91
119
  }
92
120
 
121
+ agooText
122
+ agoo_text_append_char(agooText t, const char c) {
123
+ if (t->alen <= t->len + 1) {
124
+ long new_len = t->alen + 1 + t->alen / 2;
125
+ size_t size = sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + new_len + 1;
126
+
127
+ if (NULL == (t = (agooText)AGOO_REALLOC(t, size))) {
128
+ return NULL;
129
+ }
130
+ t->alen = new_len;
131
+ }
132
+ *(t->text + t->len) = c;
133
+ t->len++;
134
+ t->text[t->len] = '\0';
135
+
136
+ return t;
137
+ }
138
+
93
139
  agooText
94
140
  agoo_text_prepend(agooText t, const char *s, int len) {
95
141
  if (0 >= len) {
@@ -98,14 +144,10 @@ agoo_text_prepend(agooText t, const char *s, int len) {
98
144
  if (t->alen <= t->len + len) {
99
145
  long new_len = t->alen + len + t->alen / 2;
100
146
  size_t size = sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + new_len + 1;
101
- #ifdef MEM_DEBUG
102
- agooText t0 = t;
103
- #endif
104
147
 
105
- if (NULL == (t = (agooText)realloc(t, size))) {
148
+ if (NULL == (t = (agooText)AGOO_REALLOC(t, size))) {
106
149
  return NULL;
107
150
  }
108
- DEBUG_REALLOC(mem_text, t0, t);
109
151
  t->alen = new_len;
110
152
  }
111
153
  memmove(t->text + len, t->text, t->len + 1);
@@ -114,3 +156,67 @@ agoo_text_prepend(agooText t, const char *s, int len) {
114
156
 
115
157
  return t;
116
158
  }
159
+
160
+ agooText
161
+ agoo_text_append_json(agooText t, const char *s, int len) {
162
+ size_t jlen;
163
+
164
+ if (0 >= len) {
165
+ len = (int)strlen(s);
166
+ }
167
+ jlen = json_size(s, len);
168
+ if (t->alen <= (long)(t->len + jlen)) {
169
+ long new_len = t->alen + jlen + t->alen / 2;
170
+ size_t size = sizeof(struct _agooText) - AGOO_TEXT_MIN_SIZE + new_len + 1;
171
+
172
+ if (NULL == (t = (agooText)AGOO_REALLOC(t, size))) {
173
+ return NULL;
174
+ }
175
+ t->alen = new_len;
176
+ }
177
+ if (jlen == (size_t)len) {
178
+ memcpy(t->text + t->len, s, len);
179
+ } else {
180
+ const char *end = s + len;
181
+ char *ts = t->text + t->len;
182
+
183
+ for (; s < end; s++) {
184
+ switch (json_chars[(uint8_t)*s]) {
185
+ case '1':
186
+ *ts++ = *s;
187
+ break;
188
+ case '2':
189
+ *ts++ = '\\';
190
+ switch (*s) {
191
+ case '\\': *ts++ = '\\'; break;
192
+ case '\b': *ts++ = 'b'; break;
193
+ case '\t': *ts++ = 't'; break;
194
+ case '\n': *ts++ = 'n'; break;
195
+ case '\f': *ts++ = 'f'; break;
196
+ case '\r': *ts++ = 'r'; break;
197
+ default: *ts++ = *s; break;
198
+ }
199
+ break;
200
+ case '6': // control characters
201
+ *ts++ = '\\';
202
+ *ts++ = 'u';
203
+ *ts++ = '0';
204
+ *ts++ = '0';
205
+ dump_hex(ts, (uint8_t)*s);
206
+ ts += 2;
207
+ break;
208
+ default:
209
+ break; // should never get here
210
+ }
211
+ }
212
+ }
213
+ t->len += jlen;
214
+ t->text[t->len] = '\0';
215
+
216
+ return t;
217
+ }
218
+
219
+ void
220
+ agoo_text_reset(agooText t) {
221
+ t->len = 0;
222
+ }
@@ -10,7 +10,7 @@
10
10
  #define AGOO_TEXT_MIN_SIZE 8
11
11
 
12
12
  typedef struct _agooText {
13
- long len; // length of valid text
13
+ long len; // length of valid text
14
14
  long alen; // size of allocated text
15
15
  atomic_int ref_cnt;
16
16
  bool bin;
@@ -24,5 +24,9 @@ extern void agoo_text_ref(agooText t);
24
24
  extern void agoo_text_release(agooText t);
25
25
  extern agooText agoo_text_append(agooText t, const char *s, int len);
26
26
  extern agooText agoo_text_prepend(agooText t, const char *s, int len);
27
+ extern agooText agoo_text_append_json(agooText t, const char *s, int len);
28
+ extern agooText agoo_text_append_char(agooText t, const char c);
29
+
30
+ extern void agoo_text_reset(agooText t);
27
31
 
28
32
  #endif // AGOO_TEXT_H
@@ -32,8 +32,7 @@ destroy(agooUpgraded up) {
32
32
  up->subjects = up->subjects->next;
33
33
  agoo_subject_destroy(subject);
34
34
  }
35
- DEBUG_FREE(mem_upgraded, up);
36
- free(up);
35
+ AGOO_FREE(up);
37
36
  }
38
37
 
39
38
  void
@@ -167,10 +166,9 @@ agoo_upgraded_pending(agooUpgraded up) {
167
166
 
168
167
  agooUpgraded
169
168
  agoo_upgraded_create(agooCon c, void * ctx, void *env) {
170
- agooUpgraded up = (agooUpgraded)malloc(sizeof(struct _agooUpgraded));
169
+ agooUpgraded up = (agooUpgraded)AGOO_MALLOC(sizeof(struct _agooUpgraded));
171
170
 
172
171
  if (NULL != up) {
173
- DEBUG_ALLOC(mem_upgraded, up);
174
172
  memset(up, 0, sizeof(struct _agooUpgraded));
175
173
  up->con = c;
176
174
  up->ctx = ctx;