agoo 2.5.1 → 2.5.2

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +12 -1
  4. data/ext/agoo/agoo.c +4 -3
  5. data/ext/agoo/bind.c +51 -11
  6. data/ext/agoo/bind.h +9 -0
  7. data/ext/agoo/con.c +127 -89
  8. data/ext/agoo/con.h +24 -8
  9. data/ext/agoo/debug.c +2 -0
  10. data/ext/agoo/debug.h +1 -0
  11. data/ext/agoo/err.c +1 -1
  12. data/ext/agoo/err.h +2 -5
  13. data/ext/agoo/foo/agoo.c +109 -0
  14. data/ext/agoo/foo/con.c +1220 -0
  15. data/ext/agoo/foo/con.h +65 -0
  16. data/ext/agoo/foo/page.c +699 -0
  17. data/ext/agoo/foo/pub.c +131 -0
  18. data/ext/agoo/foo/pub.h +40 -0
  19. data/ext/agoo/foo/rserver.c +1016 -0
  20. data/ext/agoo/foo/server.c +303 -0
  21. data/ext/agoo/foo/server.h +67 -0
  22. data/ext/agoo/foo/upgraded.c +182 -0
  23. data/ext/agoo/hook.c +31 -0
  24. data/ext/agoo/hook.h +9 -10
  25. data/ext/agoo/{types.h → kinds.h} +3 -3
  26. data/ext/agoo/log.c +168 -83
  27. data/ext/agoo/log.h +6 -2
  28. data/ext/agoo/page.c +38 -32
  29. data/ext/agoo/pub.c +16 -0
  30. data/ext/agoo/pub.h +1 -0
  31. data/ext/agoo/queue.h +1 -0
  32. data/ext/agoo/req.c +95 -0
  33. data/ext/agoo/req.h +48 -0
  34. data/ext/agoo/request.c +10 -38
  35. data/ext/agoo/request.h +1 -34
  36. data/ext/agoo/res.h +1 -3
  37. data/ext/agoo/response.c +6 -248
  38. data/ext/agoo/response.h +2 -6
  39. data/ext/agoo/rlog.c +2 -1
  40. data/ext/agoo/rresponse.c +252 -0
  41. data/ext/agoo/rresponse.h +14 -0
  42. data/ext/agoo/rserver.c +43 -45
  43. data/ext/agoo/rserver.h +3 -24
  44. data/ext/agoo/rupgraded.c +303 -0
  45. data/ext/agoo/rupgraded.h +17 -0
  46. data/ext/agoo/server.c +125 -8
  47. data/ext/agoo/server.h +26 -4
  48. data/ext/agoo/sse.c +3 -1
  49. data/ext/agoo/upgraded.c +42 -280
  50. data/ext/agoo/upgraded.h +16 -8
  51. data/ext/agoo/websocket.c +13 -9
  52. data/lib/agoo/base.rb +84 -0
  53. data/lib/agoo/client.rb +25 -0
  54. data/lib/agoo/version.rb +1 -1
  55. data/test/bind_test.rb +2 -2
  56. metadata +22 -4
@@ -58,11 +58,14 @@ typedef struct _LogEntry {
58
58
  char *whatp;
59
59
  char what[104];
60
60
  volatile bool ready;
61
+ char *tidp;
62
+ char tid[40];
61
63
  } *LogEntry;
62
64
 
63
65
  struct _Log {
64
66
  LogCat cats;
65
67
  char dir[1024];
68
+ char app[16];
66
69
  FILE *file; // current output file
67
70
  int max_files;
68
71
  int max_size;
@@ -102,7 +105,7 @@ extern struct _LogCat resp_cat;
102
105
  extern struct _LogCat eval_cat;
103
106
  extern struct _LogCat push_cat;
104
107
 
105
- extern void log_init();
108
+ extern void log_init(const char *app);
106
109
  extern void open_log_file();
107
110
 
108
111
  extern void log_close();
@@ -115,7 +118,8 @@ extern LogCat log_cat_find(const char *label);
115
118
 
116
119
  // Function to call to make a log entry.
117
120
  extern void log_cat(LogCat cat, const char *fmt, ...);
118
- extern void log_catv(LogCat cat, const char *fmt, va_list ap);
121
+ extern void log_tid_cat(LogCat cat, const char *tid, const char *fmt, ...);
122
+ extern void log_catv(LogCat cat, const char *tid, const char *fmt, va_list ap);
119
123
 
120
124
  extern void log_start(bool with_pid);
121
125
 
@@ -275,7 +275,11 @@ pages_init() {
275
275
  void
276
276
  pages_set_root(const char *root) {
277
277
  free(cache.root);
278
- cache.root = strdup(root);
278
+ if (NULL == root) {
279
+ cache.root = NULL;
280
+ } else {
281
+ cache.root = strdup(root);
282
+ }
279
283
  }
280
284
 
281
285
  static void
@@ -380,7 +384,7 @@ page_immutable(Err err, const char *path, const char *content, int clen) {
380
384
  p->path = NULL;
381
385
  } else {
382
386
  p->path = strdup(path);
383
- plen = strlen(path);
387
+ plen = (int)strlen(path);
384
388
  DEBUG_ALLOC(mem_page_path, p->path);
385
389
  }
386
390
  p->mtime = 0;
@@ -466,7 +470,7 @@ update_contents(Page p) {
466
470
  fclose(f);
467
471
  return false;
468
472
  }
469
- if (0 >= (size = ftell(f))) {
473
+ if (0 > (size = ftell(f))) {
470
474
  fclose(f);
471
475
  return false;
472
476
  }
@@ -506,7 +510,7 @@ update_contents(Page p) {
506
510
 
507
511
  static void
508
512
  page_remove(Page p) {
509
- int len = strlen(p->path);
513
+ int len = (int)strlen(p->path);
510
514
  int64_t h = calc_hash(p->path, &len);
511
515
  Slot *bucket = get_bucketp(h);
512
516
  Slot s;
@@ -561,30 +565,32 @@ page_get(Err err, const char *path, int plen) {
561
565
  return NULL;
562
566
  }
563
567
  if (NULL == (page = cache_get(path, plen))) {
564
- Page old;
565
- char full_path[2048];
566
- char *s = stpcpy(full_path, cache.root);
568
+ if (NULL != cache.root) {
569
+ Page old;
570
+ char full_path[2048];
571
+ char *s = stpcpy(full_path, cache.root);
567
572
 
568
- if ('/' != *cache.root && '/' != *path) {
569
- *s++ = '/';
570
- }
571
- if ((int)sizeof(full_path) <= plen + (s - full_path)) {
572
- err_set(err, ERR_MEMORY, "Failed to allocate memory for page path.");
573
- return NULL;
574
- }
575
- strncpy(s, path, plen);
576
- s[plen] = '\0';
577
- if (NULL == (page = page_create(full_path))) {
578
- err_set(err, ERR_MEMORY, "Failed to allocate memory for Page.");
579
- return NULL;
580
- }
581
- if (!update_contents(page) || NULL == page->resp) {
582
- page_destroy(page);
583
- err_set(err, ERR_NOT_FOUND, "not found.");
584
- return NULL;
585
- }
586
- if (NULL != (old = cache_set(path, plen, page))) {
587
- page_destroy(old);
573
+ if ('/' != *cache.root && '/' != *path) {
574
+ *s++ = '/';
575
+ }
576
+ if ((int)sizeof(full_path) <= plen + (s - full_path)) {
577
+ err_set(err, ERR_MEMORY, "Failed to allocate memory for page path.");
578
+ return NULL;
579
+ }
580
+ strncpy(s, path, plen);
581
+ s[plen] = '\0';
582
+ if (NULL == (page = page_create(full_path))) {
583
+ err_set(err, ERR_MEMORY, "Failed to allocate memory for Page.");
584
+ return NULL;
585
+ }
586
+ if (!update_contents(page) || NULL == page->resp) {
587
+ page_destroy(page);
588
+ err_set(err, ERR_NOT_FOUND, "not found.");
589
+ return NULL;
590
+ }
591
+ if (NULL != (old = cache_set(path, plen, page))) {
592
+ page_destroy(old);
593
+ }
588
594
  }
589
595
  } else {
590
596
  page = page_check(err, page);
@@ -597,7 +603,7 @@ group_get(Err err, const char *path, int plen) {
597
603
  Page page = NULL;
598
604
  Group g = NULL;
599
605
  char full_path[2048];
600
- char *s;
606
+ char *s = NULL;
601
607
  Dir d;
602
608
 
603
609
  if (NULL != strstr(path, "../")) {
@@ -619,7 +625,7 @@ group_get(Err err, const char *path, int plen) {
619
625
  strncpy(s, path + g->plen, plen - g->plen);
620
626
  s += plen - g->plen;
621
627
  *s = '\0';
622
- if (NULL != (page = cache_get(full_path, s - full_path))) {
628
+ if (NULL != (page = cache_get(full_path, (int)(s - full_path)))) {
623
629
  break;
624
630
  }
625
631
  }
@@ -639,7 +645,7 @@ group_get(Err err, const char *path, int plen) {
639
645
  if (NULL == d) {
640
646
  return NULL;
641
647
  }
642
- plen = s - full_path;
648
+ plen = (int)(s - full_path);
643
649
  path = full_path;
644
650
  if (NULL == (page = cache_get(path, plen))) {
645
651
  Page old;
@@ -671,7 +677,7 @@ group_create(const char *path) {
671
677
  g->next = cache.groups;
672
678
  cache.groups = g;
673
679
  g->path = strdup(path);
674
- g->plen = strlen(path);
680
+ g->plen = (int)strlen(path);
675
681
  DEBUG_ALLOC(mem_group_path, g->path);
676
682
  g->dirs = NULL;
677
683
  }
@@ -687,7 +693,7 @@ group_add(Group g, const char *dir) {
687
693
  d->next = g->dirs;
688
694
  g->dirs = d;
689
695
  d->path = strdup(dir);
690
- d->plen = strlen(dir);
696
+ d->plen = (int)strlen(dir);
691
697
  DEBUG_ALLOC(mem_dir_path, d->path);
692
698
  }
693
699
  }
@@ -98,6 +98,22 @@ pub_write(Upgraded up, const char *message, size_t mlen, bool bin) {
98
98
  return p;
99
99
  }
100
100
 
101
+ Pub
102
+ pub_dup(Pub src) {
103
+ Pub p = (Pub)malloc(sizeof(struct _Pub));
104
+
105
+ if (NULL != p) {
106
+ DEBUG_ALLOC(mem_pub, p);
107
+ p->next = NULL;
108
+ p->kind = src->kind;
109
+ p->up = src->up;
110
+ p->subject = subject_create(src->subject->pattern, strlen(src->subject->pattern));
111
+ p->msg = src->msg;
112
+ text_ref(p->msg);
113
+ }
114
+ return p;
115
+ }
116
+
101
117
  void
102
118
  pub_destroy(Pub pub) {
103
119
  if (NULL != pub->msg) {
@@ -34,6 +34,7 @@ extern Pub pub_subscribe(struct _Upgraded *up, const char *subject, int slen);
34
34
  extern Pub pub_unsubscribe(struct _Upgraded *up, const char *subject, int slen);
35
35
  extern Pub pub_publish(const char *subject, int slen, const char *message, size_t mlen);
36
36
  extern Pub pub_write(struct _Upgraded *up, const char *message, size_t mlen, bool bin);
37
+ extern Pub pub_dup(Pub src);
37
38
  extern void pub_destroy(Pub pub);
38
39
 
39
40
  #endif // __AGOO_PUB_H__
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <stdatomic.h>
7
7
  #include <stdbool.h>
8
+ #include <stdlib.h>
8
9
 
9
10
  typedef void *QItem;
10
11
 
@@ -0,0 +1,95 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <ctype.h>
7
+
8
+ #include "con.h"
9
+ #include "debug.h"
10
+ #include "server.h"
11
+ #include "req.h"
12
+
13
+ Req
14
+ req_create(size_t mlen) {
15
+ size_t size = mlen + sizeof(struct _Req) - 7;
16
+ Req req = (Req)malloc(size);
17
+
18
+ if (NULL != req) {
19
+ DEBUG_ALLOC(mem_req, req);
20
+ memset(req, 0, size);
21
+ req->env = the_server.env_nil_value;
22
+ req->mlen = mlen;
23
+ req->hook = NULL;
24
+ }
25
+ return req;
26
+ }
27
+
28
+ void
29
+ req_destroy(Req req) {
30
+ DEBUG_FREE(mem_req, req);
31
+ if (NULL != req->hook && PUSH_HOOK == req->hook->type) {
32
+ free(req->hook);
33
+ }
34
+ free(req);
35
+ }
36
+
37
+ const char*
38
+ req_host(Req r, int *lenp) {
39
+ const char *host;
40
+ const char *colon;
41
+
42
+ if (NULL == (host = con_header_value(r->header.start, r->header.len, "Host", lenp))) {
43
+ return NULL;
44
+ }
45
+ for (colon = host + *lenp - 1; host < colon; colon--) {
46
+ if (':' == *colon) {
47
+ break;
48
+ }
49
+ }
50
+ if (host < colon) {
51
+ *lenp = (int)(colon - host);
52
+ }
53
+ return host;
54
+ }
55
+
56
+ int
57
+ req_port(Req r) {
58
+ int len;
59
+ const char *host;
60
+ const char *colon;
61
+
62
+ if (NULL == (host = con_header_value(r->header.start, r->header.len, "Host", &len))) {
63
+ return 0;
64
+ }
65
+ for (colon = host + len - 1; host < colon; colon--) {
66
+ if (':' == *colon) {
67
+ break;
68
+ }
69
+ }
70
+ if (host == colon) {
71
+ return 0;
72
+ }
73
+ return (int)strtol(colon + 1, NULL, 10);
74
+ }
75
+
76
+ const char*
77
+ req_query_value(Req r, const char *key, int klen, int *vlenp) {
78
+ const char *value;
79
+
80
+ if (NULL != (value = strstr(r->query.start, key))) {
81
+ char *end;
82
+
83
+ if (0 >= klen) {
84
+ klen = strlen(key);
85
+ }
86
+ value += klen + 1;
87
+ if (NULL == (end = index(value, '&'))) {
88
+ *vlenp = strlen(value);
89
+ } else {
90
+ *vlenp = (int)(end - value);
91
+ }
92
+ }
93
+ return value;
94
+ }
95
+
@@ -0,0 +1,48 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #ifndef __AGOO_REQ_H__
4
+ #define __AGOO_REQ_H__
5
+
6
+ #include <stdint.h>
7
+
8
+ #include "hook.h"
9
+ #include "kinds.h"
10
+
11
+ struct _Server;
12
+ struct _Upgraded;
13
+ struct _Res;
14
+
15
+ typedef enum {
16
+ UP_NONE = '\0',
17
+ UP_WS = 'W',
18
+ UP_SSE = 'S',
19
+ } Upgrade;
20
+
21
+ typedef struct _Str {
22
+ char *start;
23
+ unsigned int len;
24
+ } *Str;
25
+
26
+ typedef struct _Req {
27
+ Method method;
28
+ struct _Res *res;
29
+
30
+ Upgrade upgrade;
31
+ struct _Upgraded *up;
32
+ struct _Str path;
33
+ struct _Str query;
34
+ struct _Str header;
35
+ struct _Str body;
36
+ void *env;
37
+ Hook hook;
38
+ size_t mlen; // allocated msg length
39
+ char msg[8]; // expanded to be full message
40
+ } *Req;
41
+
42
+ extern Req req_create(size_t mlen);
43
+ extern void req_destroy(Req req);
44
+ extern const char* req_host(Req r, int *lenp);
45
+ extern int req_port(Req r);
46
+ extern const char* req_query_value(Req r, const char *key, int klen, int *vlenp);
47
+
48
+ #endif // __AGOO_REQ_H__
@@ -1,6 +1,7 @@
1
1
  // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
2
 
3
3
  #include <stdio.h>
4
+ #include <stdlib.h>
4
5
  #include <ctype.h>
5
6
 
6
7
  #include "debug.h"
@@ -8,6 +9,7 @@
8
9
  #include "error_stream.h"
9
10
  #include "rack_logger.h"
10
11
  #include "request.h"
12
+ #include "res.h"
11
13
 
12
14
  static VALUE req_class = Qundef;
13
15
 
@@ -59,21 +61,6 @@ static const char websocket_val[] = "websocket";
59
61
  static const char accept_key[] = "Accept";
60
62
  static const char event_stream_val[] = "text/event-stream";
61
63
 
62
- Req
63
- request_create(size_t mlen) {
64
- size_t size = mlen + sizeof(struct _Req) - 7;
65
- Req req = (Req)malloc(size);
66
-
67
- if (NULL != req) {
68
- DEBUG_ALLOC(mem_req, req);
69
- memset(req, 0, size);
70
- req->env = Qnil;
71
- req->mlen = mlen;
72
- req->hook = NULL;
73
- }
74
- return req;
75
- }
76
-
77
64
  static VALUE
78
65
  req_method(Req r) {
79
66
  VALUE m;
@@ -185,23 +172,14 @@ static VALUE
185
172
  req_server_name(Req r) {
186
173
  int len;
187
174
  const char *host;
188
- const char *colon;
189
175
 
190
176
  if (NULL == r) {
191
177
  rb_raise(rb_eArgError, "Request is no longer valid.");
192
178
  }
193
- if (NULL == (host = con_header_value(r->header.start, r->header.len, "Host", &len))) {
179
+ if (NULL == (host = req_host(r, &len))) {
194
180
  return rb_str_new2("unknown");
195
181
  }
196
- for (colon = host + len - 1; host < colon; colon--) {
197
- if (':' == *colon) {
198
- break;
199
- }
200
- }
201
- if (host == colon) {
202
- return rb_str_new(host, len);
203
- }
204
- return rb_str_new(host, colon - host);
182
+ return rb_str_new(host, len);
205
183
  }
206
184
 
207
185
  /* Document-method: server_name
@@ -381,6 +359,7 @@ rack_run_once(VALUE self) {
381
359
  return Qfalse;
382
360
  }
383
361
 
362
+ // TBD req.c
384
363
  static void
385
364
  add_header_value(VALUE hh, const char *key, int klen, const char *val, int vlen) {
386
365
  if (sizeof(content_type) - 1 == klen && 0 == strncasecmp(key, content_type, sizeof(content_type) - 1)) {
@@ -413,6 +392,7 @@ add_header_value(VALUE hh, const char *key, int klen, const char *val, int vlen)
413
392
  }
414
393
  }
415
394
 
395
+ // TBD req.c
416
396
  static void
417
397
  fill_headers(Req r, VALUE hash) {
418
398
  char *h = r->header.start;
@@ -551,7 +531,7 @@ rack_logger(VALUE self) {
551
531
  */
552
532
  VALUE
553
533
  request_env(Req req, VALUE self) {
554
- if (Qnil == req->env) {
534
+ if (Qnil == (VALUE)req->env) {
555
535
  volatile VALUE env = rb_hash_new();
556
536
 
557
537
  // As described by
@@ -586,9 +566,9 @@ request_env(Req req, VALUE self) {
586
566
  rb_hash_aset(env, rack_hijack_val, self);
587
567
  rb_hash_aset(env, rack_hijack_io_val, Qnil);
588
568
 
589
- req->env = env;
569
+ req->env = (void*)env;
590
570
  }
591
- return req->env;
571
+ return (VALUE)req->env;
592
572
  }
593
573
 
594
574
  /* Document-method: to_h
@@ -644,18 +624,10 @@ call(VALUE self) {
644
624
  args[0] = INT2NUM(r->res->con->sock);
645
625
 
646
626
  io = rb_class_new_instance(1, args, rb_cIO);
647
- rb_hash_aset(r->env, rack_hijack_io_val, io);
627
+ rb_hash_aset((VALUE)r->env, rack_hijack_io_val, io);
648
628
 
649
629
  return io;
650
630
  }
651
- void
652
- request_destroy(Req req) {
653
- DEBUG_FREE(mem_req, req);
654
- if (NULL != req->hook && PUSH_HOOK == req->hook->type) {
655
- free(req->hook);
656
- }
657
- free(req);
658
- }
659
631
 
660
632
  VALUE
661
633
  request_wrap(Req req) {