agoo 1.2.2 → 2.0.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.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -9
  3. data/ext/agoo/agoo.c +45 -0
  4. data/ext/agoo/base64.c +107 -0
  5. data/ext/agoo/base64.h +15 -0
  6. data/ext/agoo/ccache.c +301 -0
  7. data/ext/agoo/ccache.h +53 -0
  8. data/ext/agoo/con.c +522 -82
  9. data/ext/agoo/con.h +7 -5
  10. data/ext/agoo/debug.c +121 -7
  11. data/ext/agoo/debug.h +11 -6
  12. data/ext/agoo/error_stream.c +5 -6
  13. data/ext/agoo/error_stream.h +1 -1
  14. data/ext/agoo/extconf.rb +2 -1
  15. data/ext/agoo/hook.c +4 -4
  16. data/ext/agoo/hook.h +1 -0
  17. data/ext/agoo/http.c +2 -2
  18. data/ext/agoo/http.h +2 -0
  19. data/ext/agoo/log.c +604 -219
  20. data/ext/agoo/log.h +20 -7
  21. data/ext/agoo/page.c +20 -23
  22. data/ext/agoo/page.h +2 -0
  23. data/ext/agoo/pub.c +111 -0
  24. data/ext/agoo/pub.h +40 -0
  25. data/ext/agoo/queue.c +2 -2
  26. data/ext/agoo/rack_logger.c +15 -71
  27. data/ext/agoo/rack_logger.h +1 -1
  28. data/ext/agoo/request.c +96 -21
  29. data/ext/agoo/request.h +23 -12
  30. data/ext/agoo/res.c +5 -2
  31. data/ext/agoo/res.h +4 -0
  32. data/ext/agoo/response.c +13 -12
  33. data/ext/agoo/response.h +1 -2
  34. data/ext/agoo/server.c +290 -428
  35. data/ext/agoo/server.h +10 -10
  36. data/ext/agoo/sha1.c +148 -0
  37. data/ext/agoo/sha1.h +10 -0
  38. data/ext/agoo/sse.c +26 -0
  39. data/ext/agoo/sse.h +12 -0
  40. data/ext/agoo/sub.c +111 -0
  41. data/ext/agoo/sub.h +36 -0
  42. data/ext/agoo/subscription.c +54 -0
  43. data/ext/agoo/subscription.h +18 -0
  44. data/ext/agoo/text.c +26 -4
  45. data/ext/agoo/text.h +2 -0
  46. data/ext/agoo/types.h +13 -0
  47. data/ext/agoo/upgraded.c +148 -0
  48. data/ext/agoo/upgraded.h +13 -0
  49. data/ext/agoo/websocket.c +248 -0
  50. data/ext/agoo/websocket.h +27 -0
  51. data/lib/agoo/version.rb +1 -1
  52. data/lib/rack/handler/agoo.rb +13 -6
  53. data/test/base_handler_test.rb +24 -22
  54. data/test/log_test.rb +146 -199
  55. data/test/rack_handler_test.rb +19 -20
  56. data/test/static_test.rb +30 -28
  57. metadata +23 -7
  58. data/test/rrr/test.rb +0 -26
  59. data/test/tests.rb +0 -8
@@ -49,7 +49,6 @@ typedef struct _Log *Log;
49
49
 
50
50
  typedef struct _LogCat {
51
51
  struct _LogCat *next;
52
- Log log;
53
52
  char label[32];
54
53
  Color color;
55
54
  int level;
@@ -91,13 +90,27 @@ struct _Log {
91
90
  int wsock;
92
91
  };
93
92
 
94
- extern int log_init(Err err, Log log, VALUE cfg);
95
- extern void log_close(Log log);
96
- extern bool log_flush(Log log, double timeout);
93
+ extern struct _Log the_log;
94
+ extern struct _LogCat fatal_cat;
95
+ extern struct _LogCat error_cat;
96
+ extern struct _LogCat warn_cat;
97
+ extern struct _LogCat info_cat;
98
+ extern struct _LogCat debug_cat;
99
+ extern struct _LogCat con_cat;
100
+ extern struct _LogCat req_cat;
101
+ extern struct _LogCat resp_cat;
102
+ extern struct _LogCat eval_cat;
103
+ extern struct _LogCat push_cat;
97
104
 
98
- extern void log_cat_reg(Log log, LogCat cat, const char *label, LogLevel level, const char *color, bool on);
99
- extern void log_cat_on(Log log, const char *label, bool on);
100
- extern LogCat log_cat_find(Log log, const char *label);
105
+ extern void log_init(VALUE mod);
106
+
107
+ extern void log_close();
108
+ extern bool log_flush(double timeout);
109
+ extern void log_rotate();
110
+
111
+ extern void log_cat_reg(LogCat cat, const char *label, LogLevel level, const char *color, bool on);
112
+ extern void log_cat_on(const char *label, bool on);
113
+ extern LogCat log_cat_find(const char *label);
101
114
 
102
115
  // Function to call to make a log entry.
103
116
  extern void log_cat(LogCat cat, const char *fmt, ...);
@@ -159,7 +159,7 @@ mime_set(Cache cache, const char *key, const char *value) {
159
159
  ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strcmp(s->key, key))) {
160
160
  if (h == (int64_t)s->hash && len == s->klen &&
161
161
  ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strcmp(s->key, key))) {
162
- DEBUG_FREE(mem_mime_slot)
162
+ DEBUG_FREE(mem_mime_slot, s->value)
163
163
  free(s->value);
164
164
  s->value = strdup(value);
165
165
  return;
@@ -169,7 +169,7 @@ mime_set(Cache cache, const char *key, const char *value) {
169
169
  if (NULL == (s = (MimeSlot)malloc(sizeof(struct _MimeSlot)))) {
170
170
  rb_raise(rb_eArgError, "out of memory adding %s", key);
171
171
  }
172
- DEBUG_ALLOC(mem_mime_slot)
172
+ DEBUG_ALLOC(mem_mime_slot, s)
173
173
  s->hash = h;
174
174
  s->klen = len;
175
175
  if (NULL == key) {
@@ -209,7 +209,7 @@ cache_set(Cache cache, const char *key, int klen, Page value) {
209
209
  if (NULL == (s = (Slot)malloc(sizeof(struct _Slot)))) {
210
210
  return value;
211
211
  }
212
- DEBUG_ALLOC(mem_page_slot)
212
+ DEBUG_ALLOC(mem_page_slot, s)
213
213
  s->hash = h;
214
214
  s->klen = len;
215
215
  if (NULL == key) {
@@ -235,7 +235,7 @@ cache_init(Cache cache) {
235
235
  }
236
236
 
237
237
  void
238
- cache_destroy(Cache cache) {
238
+ cache_cleanup(Cache cache) {
239
239
  Slot *sp = cache->buckets;
240
240
  Slot s;
241
241
  Slot n;
@@ -247,7 +247,8 @@ cache_destroy(Cache cache) {
247
247
  for (i = PAGE_BUCKET_SIZE; 0 < i; i--, sp++) {
248
248
  for (s = *sp; NULL != s; s = n) {
249
249
  n = s->next;
250
- DEBUG_FREE(mem_page_slot)
250
+ DEBUG_FREE(mem_page_slot, s);
251
+ page_destroy(s->value);
251
252
  free(s);
252
253
  }
253
254
  *sp = NULL;
@@ -256,13 +257,11 @@ cache_destroy(Cache cache) {
256
257
  for (i = MIME_BUCKET_SIZE; 0 < i; i--, mp++) {
257
258
  for (sm = *mp; NULL != sm; sm = m) {
258
259
  m = sm->next;
259
- DEBUG_FREE(mem_page_slot)
260
+ DEBUG_FREE(mem_mime_slot, sm);
260
261
  free(sm);
261
262
  }
262
263
  *mp = NULL;
263
264
  }
264
- //DEBUG_FREE(mem_cache)
265
- free(cache);
266
265
  }
267
266
 
268
267
  // The page resp contents point to the page resp msg to save memory and reduce
@@ -272,13 +271,13 @@ page_create(const char *path) {
272
271
  Page p = (Page)malloc(sizeof(struct _Page));
273
272
 
274
273
  if (NULL != p) {
275
- DEBUG_ALLOC(mem_page)
274
+ DEBUG_ALLOC(mem_page, p)
276
275
  p->resp = NULL;
277
276
  if (NULL == path) {
278
277
  p->path = NULL;
279
278
  } else {
280
279
  p->path = strdup(path);
281
- DEBUG_ALLOC(mem_page_path)
280
+ DEBUG_ALLOC(mem_page_path, p->path)
282
281
  }
283
282
  p->mtime = 0;
284
283
  p->last_check = 0.0;
@@ -292,8 +291,8 @@ page_destroy(Page p) {
292
291
  text_release(p->resp);
293
292
  p->resp = NULL;
294
293
  }
295
- DEBUG_FREE(mem_page_path)
296
- DEBUG_FREE(mem_page)
294
+ DEBUG_FREE(mem_page_path, p->path);
295
+ DEBUG_FREE(mem_page, p);
297
296
  free(p->path);
298
297
  free(p);
299
298
  }
@@ -307,10 +306,10 @@ update_contents(Cache cache, Page p) {
307
306
  long size;
308
307
  struct stat fattr;
309
308
  long msize;
310
- char *msg;
311
309
  int cnt;
312
310
  struct stat fs;
313
-
311
+ Text t;
312
+
314
313
  for (; '.' != *suffix; suffix--) {
315
314
  if (suffix <= p->path) {
316
315
  suffix = NULL;
@@ -370,21 +369,19 @@ update_contents(Cache cache, Page p) {
370
369
  // Format size plus space for the length, the mime type, and some
371
370
  // padding. Then add the content length.
372
371
  msize = sizeof(page_fmt) + 60 + size;
373
- if (NULL == (msg = (char*)malloc(msize))) {
372
+ if (NULL == (t = text_allocate((int)msize))) {
374
373
  return false;
375
374
  }
376
- DEBUG_ALLOC(mem_page_msg)
377
- cnt = sprintf(msg, page_fmt, mime, size);
378
-
375
+ cnt = sprintf(t->text, page_fmt, mime, size);
379
376
  msize = cnt + size;
380
- if (size != (long)fread(msg + cnt, 1, size, f)) {
377
+ if (size != (long)fread(t->text + cnt, 1, size, f)) {
381
378
  fclose(f);
382
- DEBUG_FREE(mem_page_msg)
383
- free(msg);
379
+ text_release(t);
384
380
  return false;
385
381
  }
386
382
  fclose(f);
387
- msg[msize] = '\0';
383
+ t->text[msize] = '\0';
384
+ t->len = msize;
388
385
  if (0 == stat(p->path, &fattr)) {
389
386
  p->mtime = fattr.st_mtime;
390
387
  } else {
@@ -394,7 +391,7 @@ update_contents(Cache cache, Page p) {
394
391
  text_release(p->resp);
395
392
  p->resp = NULL;
396
393
  }
397
- p->resp = text_create(msg, (int)msize);
394
+ p->resp = t;
398
395
  text_ref(p->resp);
399
396
  p->last_check = dtime();
400
397
 
@@ -46,6 +46,8 @@ typedef struct _Cache {
46
46
  } *Cache;
47
47
 
48
48
  extern void cache_init(Cache cache);
49
+ extern void cache_cleanup(Cache cache);
50
+
49
51
  extern void page_destroy(Page p);
50
52
  extern Page page_get(Err err, Cache cache, const char *dir, const char *path, int plen);
51
53
  extern void mime_set(Cache cache, const char *key, const char *value);
@@ -0,0 +1,111 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ #include "debug.h"
8
+ #include "pub.h"
9
+ #include "text.h"
10
+
11
+ Pub
12
+ pub_close(uint64_t cid) {
13
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
14
+
15
+ if (NULL != p) {
16
+ DEBUG_ALLOC(mem_pub, p);
17
+ p->next = NULL;
18
+ p->kind = PUB_CLOSE;
19
+ p->cid = cid;
20
+ p->sid = 0;
21
+ p->subject = NULL;
22
+ }
23
+ return p;
24
+ }
25
+
26
+ Pub
27
+ pub_subscribe(uint64_t cid, uint64_t sid, const char *subject) {
28
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
29
+
30
+ if (NULL != p) {
31
+ DEBUG_ALLOC(mem_pub, p);
32
+ p->next = NULL;
33
+ p->kind = PUB_SUB;
34
+ p->cid = cid;
35
+ p->sid = sid;
36
+ p->subject = strdup(subject);
37
+ }
38
+ return p;
39
+ }
40
+
41
+ Pub
42
+ pub_unsubscribe(uint64_t cid, uint64_t sid) {
43
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
44
+
45
+ if (NULL != p) {
46
+ DEBUG_ALLOC(mem_pub, p);
47
+ p->next = NULL;
48
+ p->kind = PUB_UN;
49
+ p->cid = cid;
50
+ p->sid = sid;
51
+ p->subject = NULL;
52
+ }
53
+ return p;
54
+ }
55
+
56
+ Pub
57
+ pub_publish(char *subject, const char *message, size_t mlen, bool bin) {
58
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
59
+
60
+ if (NULL != p) {
61
+ DEBUG_ALLOC(mem_pub, p);
62
+ p->next = NULL;
63
+ p->kind = PUB_MSG;
64
+ p->cid = 0;
65
+ p->subject = strdup(subject);
66
+ // Allocate an extra 24 bytes so the message can be expanded in place
67
+ // if a WebSocket or SSE write.
68
+ p->msg = text_allocate((int)mlen + 24);
69
+ p->msg = text_append(text_allocate((int)mlen + 16), message, (int)mlen);
70
+ text_ref(p->msg);
71
+ }
72
+ return p;
73
+ }
74
+
75
+ Pub
76
+ pub_write(uint64_t cid, const char *message, size_t mlen, bool bin) {
77
+ // Allocate an extra 16 bytes so the message can be expanded in place if a
78
+ // WebSocket write.
79
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
80
+
81
+ if (NULL != p) {
82
+ DEBUG_ALLOC(mem_pub, p);
83
+ p->next = NULL;
84
+ p->kind = PUB_WRITE;
85
+ p->cid = cid;
86
+ p->subject = NULL;
87
+ // Allocate an extra 16 bytes so the message can be expanded in place
88
+ // if a WebSocket write.
89
+ p->msg = text_append(text_allocate((int)mlen + 16), message, (int)mlen);
90
+ p->msg->bin = bin;
91
+ text_ref(p->msg);
92
+ }
93
+ return p;
94
+ }
95
+
96
+ void
97
+ pub_destroy(Pub pub) {
98
+ switch (pub->kind) {
99
+ case PUB_MSG:
100
+ case PUB_WRITE:
101
+ if (NULL != pub->msg) {
102
+ text_release(pub->msg);
103
+ }
104
+ break;
105
+ default:
106
+ break;
107
+ }
108
+ DEBUG_FREE(mem_pub, pub);
109
+ free(pub);
110
+ }
111
+
@@ -0,0 +1,40 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #ifndef __AGOO_PUB_H__
4
+ #define __AGOO_PUB_H__
5
+
6
+ #include <stdbool.h>
7
+ #include <stdint.h>
8
+ #include <stdlib.h>
9
+
10
+ struct _Text;
11
+
12
+ typedef enum {
13
+ PUB_SUB = 'S',
14
+ PUB_CLOSE = 'C',
15
+ PUB_UN = 'U',
16
+ PUB_MSG = 'M',
17
+ PUB_WRITE = 'W',
18
+ } PubKind;
19
+
20
+ // Generated by extened handlers and placed on the pub_queue to be pulled off
21
+ // in the con_loop.
22
+ typedef struct _Pub {
23
+ struct _Pub *next;
24
+ PubKind kind;
25
+ uint64_t cid;
26
+ char *subject;
27
+ union {
28
+ uint64_t sid;
29
+ struct _Text *msg;
30
+ };
31
+ } *Pub;
32
+
33
+ extern Pub pub_close(uint64_t cid);
34
+ extern Pub pub_subscribe(uint64_t cid, uint64_t sid, const char *subject);
35
+ extern Pub pub_unsubscribe(uint64_t cid, uint64_t sid);
36
+ extern Pub pub_publish(char *subject, const char *message, size_t mlen, bool bin);
37
+ extern Pub pub_write(uint64_t cid, const char *message, size_t mlen, bool bin);
38
+ extern void pub_destroy(Pub pub);
39
+
40
+ #endif // __AGOO_PUB_H__
@@ -35,7 +35,7 @@ queue_multi_init(Queue q, size_t qsize, bool multi_push, bool multi_pop) {
35
35
  qsize = 4;
36
36
  }
37
37
  q->q = (QItem*)malloc(sizeof(QItem) * qsize);
38
- DEBUG_ALLOC(mem_qitem)
38
+ DEBUG_ALLOC(mem_qitem, q->q)
39
39
  q->end = q->q + qsize;
40
40
 
41
41
  memset(q->q, 0, sizeof(QItem) * qsize);
@@ -53,7 +53,7 @@ queue_multi_init(Queue q, size_t qsize, bool multi_push, bool multi_pop) {
53
53
 
54
54
  void
55
55
  queue_cleanup(Queue q) {
56
- DEBUG_FREE(mem_qitem)
56
+ DEBUG_FREE(mem_qitem, q->q)
57
57
  free(q->q);
58
58
  q->q = NULL;
59
59
  q->end = NULL;
@@ -9,33 +9,19 @@
9
9
 
10
10
  static VALUE rl_class = Qundef;
11
11
 
12
- typedef struct _RackLogger {
13
- Server server;
14
- } *RackLogger;
15
-
16
- static void
17
- rack_logger_free(void *ptr) {
18
- DEBUG_FREE(mem_rack_logger)
19
- xfree(ptr);
20
- }
21
-
22
12
  VALUE
23
- rack_logger_new(Server server) {
24
- RackLogger rl = ALLOC(struct _RackLogger);
25
-
26
- DEBUG_ALLOC(mem_rack_logger)
27
- rl->server = server;
28
-
29
- //return Data_Wrap_Struct(rl_class, NULL, xfree, rl);
30
- return Data_Wrap_Struct(rl_class, NULL, rack_logger_free, rl);
13
+ rack_logger_new() {
14
+ return rb_class_new_instance(0, NULL, rl_class);
31
15
  }
32
16
 
33
17
  static void
34
- log_message(RackLogger rl, LogLevel level, VALUE message) {
18
+ log_message(LogCat cat, VALUE message) {
35
19
  volatile VALUE rs = rb_funcall(message, rb_intern("to_s"), 0);
36
20
 
37
21
  rb_check_type(rs, T_STRING);
38
-
22
+ if (!the_server.active) {
23
+ return;
24
+ }
39
25
  if (rb_block_given_p()) {
40
26
  Text text = text_create(StringValuePtr(rs), (int)RSTRING_LEN(rs));
41
27
  volatile VALUE x = rb_yield_values(0);
@@ -45,51 +31,13 @@ log_message(RackLogger rl, LogLevel level, VALUE message) {
45
31
  text = text_append(text, ": ", 2);
46
32
  text = text_append(text, StringValuePtr(rs), (int)RSTRING_LEN(rs));
47
33
  }
48
- switch (level) {
49
- case FATAL:
50
- log_cat(&rl->server->error_cat, "%s", text->text);
51
- exit(0);
52
- break;
53
- case ERROR:
54
- log_cat(&rl->server->error_cat, "%s", text->text);
55
- break;
56
- case WARN:
57
- log_cat(&rl->server->warn_cat, "%s", text->text);
58
- break;
59
- case INFO:
60
- log_cat(&rl->server->info_cat, "%s", text->text);
61
- break;
62
- case DEBUG:
63
- log_cat(&rl->server->debug_cat, "%s", text->text);
64
- break;
65
- default:
66
- break;
67
- }
34
+ log_cat(cat, "%s", text->text);
68
35
  text_release(text);
69
36
  } else {
70
- switch (level) {
71
- case FATAL:
72
- log_cat(&rl->server->error_cat, "%s", StringValuePtr(rs));
73
- exit(0);
74
- break;
75
- case ERROR:
76
- log_cat(&rl->server->error_cat, "%s", StringValuePtr(rs));
77
- break;
78
- case WARN:
79
- log_cat(&rl->server->warn_cat, "%s", StringValuePtr(rs));
80
- break;
81
- case INFO:
82
- log_cat(&rl->server->info_cat, "%s", StringValuePtr(rs));
83
- break;
84
- case DEBUG:
85
- log_cat(&rl->server->debug_cat, "%s", StringValuePtr(rs));
86
- break;
87
- default:
88
- break;
89
- }
37
+ log_cat(cat, "%s", StringValuePtr(rs));
90
38
  }
91
39
  }
92
-
40
+
93
41
  /* Document-method: debug
94
42
  *
95
43
  * call-seq: debug(message, &block)
@@ -98,8 +46,7 @@ log_message(RackLogger rl, LogLevel level, VALUE message) {
98
46
  */
99
47
  static VALUE
100
48
  rl_debug(VALUE self, VALUE message) {
101
- log_message((RackLogger)DATA_PTR(self), DEBUG, message);
102
-
49
+ log_message(&debug_cat, message);
103
50
  return Qnil;
104
51
  }
105
52
 
@@ -111,8 +58,7 @@ rl_debug(VALUE self, VALUE message) {
111
58
  */
112
59
  static VALUE
113
60
  rl_info(VALUE self, VALUE message) {
114
- log_message((RackLogger)DATA_PTR(self), INFO, message);
115
-
61
+ log_message(&info_cat, message);
116
62
  return Qnil;
117
63
  }
118
64
 
@@ -124,8 +70,7 @@ rl_info(VALUE self, VALUE message) {
124
70
  */
125
71
  static VALUE
126
72
  rl_warn(VALUE self, VALUE message) {
127
- log_message((RackLogger)DATA_PTR(self), WARN, message);
128
-
73
+ log_message(&warn_cat, message);
129
74
  return Qnil;
130
75
  }
131
76
 
@@ -137,8 +82,7 @@ rl_warn(VALUE self, VALUE message) {
137
82
  */
138
83
  static VALUE
139
84
  rl_error(VALUE self, VALUE message) {
140
- log_message((RackLogger)DATA_PTR(self), ERROR, message);
141
-
85
+ log_message(&error_cat, message);
142
86
  return Qnil;
143
87
  }
144
88
 
@@ -150,8 +94,8 @@ rl_error(VALUE self, VALUE message) {
150
94
  */
151
95
  static VALUE
152
96
  rl_fatal(VALUE self, VALUE message) {
153
- log_message((RackLogger)DATA_PTR(self), FATAL, message);
154
-
97
+ log_message(&fatal_cat, message);
98
+ exit(0);
155
99
  return Qnil;
156
100
  }
157
101