agoo 2.5.6 → 2.5.7

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cad69f3ff26f2495acc27644889572dceafba42fffe0bf15b27f3ed711f764a6
4
- data.tar.gz: c47ac0aca4a90eebb507bf64d3da2508bc9ce1e608d281f351ea1745ad0cb745
3
+ metadata.gz: cf9915f94b902db5415c971deaa9b1acbcf1a293656958fe78b4b467256ce858
4
+ data.tar.gz: 3e6a90cff696e575faa58cd5e18af23234eedab8c0478f5ecb5ec8b385de56e4
5
5
  SHA512:
6
- metadata.gz: cdd0fb689b6e1afa3b65c4cbb5b2c7151b7d76202aa0c58a57d30a8bf2e1d3cdb026f15a731745eab042f762639ed29094c065354c942cf4c2b20cd99c11d53b
7
- data.tar.gz: 3c82c32e1e52ccd0da66b47c94365d236c27ea4c7be7812fb9a5d8a91d880c9d6838a4734e1ddf00f77ed3fd8de3a3583f83bdf4e02c235483c27da27d0573c4
6
+ metadata.gz: 773278757468ee34167b62a2cbf41d0c35caf3240b595d5b500222045acd247273317f84fd9e25dc8b1dfbe2afce1585bbfcda360e458c15e9a28493dc078938
7
+ data.tar.gz: 68fadbf82b989ebc4ae2deb35209f5aff9f7d1a6a289b8d53cbab8c7930a44e93ba9515a36e15d5ed0fb9d3e6717d2c0678606c6b9c62330839b278b4e59c41b
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ### 2.5.7 - 2018-12-03
4
+
5
+ Bad release fix along with upload example.
6
+
7
+ - Additional return value checking on `strdup`, `strndup`, and `fstat`.
8
+
9
+ - Fix double free when a connection times out.
10
+
3
11
  ### 2.5.6 - 2018-11-26
4
12
 
5
13
  Even more cleanup and minor performance tweak.
@@ -26,7 +26,10 @@ agoo_bind_port(agooErr err, int port) {
26
26
  b->family = AF_INET;
27
27
  snprintf(id, sizeof(id) - 1, "http://:%d", port);
28
28
  strcpy(b->scheme, "http");
29
- b->id = strdup(id);
29
+ if (NULL == (b->id = strdup(id))) {
30
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of bind id failed.");
31
+ return NULL;
32
+ }
30
33
  b->kind = AGOO_CON_HTTP;
31
34
  b->read = NULL;
32
35
  b->write = NULL;
@@ -70,7 +73,10 @@ url_tcp(agooErr err, const char *url, const char *scheme) {
70
73
  b->addr4 = addr;
71
74
  b->family = AF_INET;
72
75
  snprintf(id, sizeof(id), "%s://%s:%d", scheme, inet_ntoa(addr), port);
73
- b->id = strdup(id);
76
+ if (NULL == (b->id = strdup(id))) {
77
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of bind id failed.");
78
+ return NULL;
79
+ }
74
80
  strncpy(b->scheme, scheme, sizeof(b->scheme));
75
81
  b->scheme[sizeof(b->scheme) - 1] = '\0';
76
82
  b->kind = AGOO_CON_HTTP;
@@ -113,7 +119,10 @@ url_tcp6(agooErr err, const char *url, const char *scheme) {
113
119
  b->addr6 = addr;
114
120
  b->family = AF_INET6;
115
121
  snprintf(buf, sizeof(buf), "%s://[%s]:%d", scheme, inet_ntop(AF_INET6, &addr, str, INET6_ADDRSTRLEN), port);
116
- b->id = strdup(buf);
122
+ if (NULL == (b->id = strdup(buf))) {
123
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of bind id failed.");
124
+ return NULL;
125
+ }
117
126
  strncpy(b->scheme, scheme, sizeof(b->scheme));
118
127
  b->scheme[sizeof(b->scheme) - 1] = '\0';
119
128
  b->kind = AGOO_CON_HTTP;
@@ -142,9 +151,15 @@ url_named(agooErr err, const char *url) {
142
151
 
143
152
  DEBUG_ALLOC(mem_bind, b);
144
153
  memset(b, 0, sizeof(struct _agooBind));
145
- b->name = strdup(url);
154
+ if (NULL == (b->name = strdup(url))) {
155
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of bind url failed.");
156
+ return NULL;
157
+ }
146
158
  snprintf(id, sizeof(id) - 1, fmt, url);
147
- b->id = strdup(id);
159
+ if (NULL == (b->id = strdup(id))) {
160
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of bind id failed.");
161
+ return NULL;
162
+ }
148
163
  strcpy(b->scheme, "unix");
149
164
  b->kind = AGOO_CON_HTTP;
150
165
  b->read = NULL;
@@ -24,7 +24,7 @@
24
24
  #include "upgraded.h"
25
25
  #include "websocket.h"
26
26
 
27
- #define CON_TIMEOUT 5.0
27
+ #define CON_TIMEOUT 10.0
28
28
  #define INITIAL_POLL_SIZE 1024
29
29
 
30
30
  typedef enum {
@@ -91,7 +91,7 @@ agoo_con_destroy(agooCon c) {
91
91
  c->up = NULL;
92
92
  }
93
93
  agoo_log_cat(&agoo_con_cat, "Connection %llu closed.", (unsigned long long)c->id);
94
- DEBUG_FREE(mem_con, c)
94
+ DEBUG_FREE(mem_con, c);
95
95
  free(c);
96
96
  }
97
97
 
@@ -1023,16 +1023,12 @@ con_ready_check(void *ctx, double now) {
1023
1023
 
1024
1024
  if (c->dead || 0 == c->sock) {
1025
1025
  if (remove_dead_res(c)) {
1026
- agoo_con_destroy(c);
1027
-
1028
1026
  return false;
1029
1027
  }
1030
1028
  } else if (0.0 == c->timeout || now < c->timeout) {
1031
1029
  return true;
1032
1030
  } else if (c->closing) {
1033
1031
  if (remove_dead_res(c)) {
1034
- agoo_con_destroy(c);
1035
-
1036
1032
  return false;
1037
1033
  }
1038
1034
  } else if (AGOO_CON_WS == c->bind->kind || AGOO_CON_SSE == c->bind->kind) {
@@ -719,8 +719,8 @@ gql_i64_set(gqlValue value, int64_t i) {
719
719
  value->i64 = i;
720
720
  }
721
721
 
722
- void
723
- gql_string_set(gqlValue value, const char *str, int len) {
722
+ int
723
+ gql_string_set(agooErr err, gqlValue value, const char *str, int len) {
724
724
  value->type = &gql_string_type;
725
725
  if (NULL == str) {
726
726
  value->str = NULL;
@@ -732,9 +732,12 @@ gql_string_set(gqlValue value, const char *str, int len) {
732
732
  value->type = &gql_str16_type;
733
733
  strncpy(value->str16, str, len);
734
734
  } else {
735
- value->str = strndup(str, len);
735
+ if (NULL == (value->str = strndup(str, len))) {
736
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
737
+ }
736
738
  }
737
739
  }
740
+ return AGOO_ERR_OK;
738
741
  }
739
742
 
740
743
  int
@@ -746,7 +749,9 @@ gql_url_set(agooErr err, gqlValue value, const char *url, int len) {
746
749
  if (0 >= len) {
747
750
  len = (int)strlen(url);
748
751
  }
749
- value->url = strndup(url, len);
752
+ if (NULL == (value->url = strndup(url, len))) {
753
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
754
+ }
750
755
  }
751
756
  return AGOO_ERR_OK;
752
757
  }
@@ -905,7 +910,10 @@ gql_string_create(agooErr err, const char *str, int len) {
905
910
  }
906
911
  if ((int)sizeof(v->str16) <= len) {
907
912
  if (NULL != (v = value_create(&gql_string_type))) {
908
- v->str = strndup(str, len);
913
+ if (NULL == (v->str = strndup(str, len))) {
914
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
915
+ return NULL;
916
+ }
909
917
  }
910
918
  } else {
911
919
  if (NULL != (v = value_create(&gql_str16_type))) {
@@ -924,7 +932,11 @@ gql_url_create(agooErr err, const char *url, int len) {
924
932
  len = (int)strlen(url);
925
933
  }
926
934
  if (NULL != v) {
927
- v->str = strndup(url, len);
935
+ if (NULL == (v->str = strndup(url, len))) {
936
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
937
+ return NULL;
938
+ }
939
+
928
940
  }
929
941
  return v;
930
942
  }
@@ -63,7 +63,7 @@ extern int gql_object_set(agooErr err, gqlValue obj, const char *key, gqlValue i
63
63
 
64
64
  extern void gql_int_set(gqlValue value, int32_t i);
65
65
  extern void gql_i64_set(gqlValue value, int64_t i);
66
- extern void gql_string_set(gqlValue value, const char *str, int len);
66
+ extern int gql_string_set(agooErr err, gqlValue value, const char *str, int len);
67
67
  extern int gql_url_set(agooErr err, gqlValue value, const char *url, int len);
68
68
  extern void gql_bool_set(gqlValue value, bool b);
69
69
  extern void gql_float_set(gqlValue value, double f);
@@ -307,6 +307,10 @@ type_create(agooErr err, const char *name, const char *desc, int dlen, bool lock
307
307
  } else {
308
308
  type->desc = strndup(desc, dlen);
309
309
  }
310
+ if (NULL == type->desc) {
311
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", dlen);
312
+ return NULL;
313
+ }
310
314
  }
311
315
  type->locked = locked;
312
316
  type->core = false;
@@ -476,7 +480,9 @@ gql_union_add(agooErr err, gqlType type, const char *name, int len) {
476
480
  if (0 >= len) {
477
481
  len = (int)strlen(name);
478
482
  }
479
- link->name = strndup(name, len);
483
+ if (NULL == (link->name = strndup(name, len))) {
484
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
485
+ }
480
486
  if (NULL == type->types) {
481
487
  link->next = type->types;
482
488
  type->types = link;
@@ -521,8 +527,9 @@ gql_enum_add(agooErr err, gqlType type, const char *value, int len) {
521
527
  }
522
528
  link->next = type->choices;
523
529
  type->choices = link;
524
- link->str = strndup(value, len);
525
-
530
+ if (NULL == (link->str = strndup(value, len))) {
531
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", len);
532
+ }
526
533
  return AGOO_ERR_OK;
527
534
  }
528
535
 
@@ -536,7 +543,9 @@ gql_enum_append(agooErr err, gqlType type, const char *value, int len) {
536
543
  if (0 >= len) {
537
544
  len = (int)strlen(value);
538
545
  }
539
- link->str = strndup(value, len);
546
+ if (NULL == (link->str = strndup(value, len))) {
547
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", len);
548
+ }
540
549
  if (NULL == type->choices) {
541
550
  link->next = type->choices;
542
551
  type->choices = link;
@@ -655,6 +664,10 @@ gql_directive_create(agooErr err, const char *name, const char *desc, int dlen,
655
664
  } else {
656
665
  dir->desc = strndup(desc, dlen);
657
666
  }
667
+ if (NULL == dir->desc) {
668
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", dlen);
669
+ return NULL;
670
+ }
658
671
  }
659
672
  return dir;
660
673
  }
@@ -686,6 +699,10 @@ gql_dir_arg(agooErr err,
686
699
  } else {
687
700
  a->desc = strndup(desc, dlen);
688
701
  }
702
+ if (NULL == a->desc) {
703
+ agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", dlen);
704
+ return NULL;
705
+ }
689
706
  a->default_value = def_value;
690
707
  a->dir = NULL;
691
708
  a->required = required;
@@ -722,8 +739,9 @@ gql_directive_on(agooErr err, gqlDir d, const char *on, int len) {
722
739
  }
723
740
  loc->next = link;
724
741
  }
725
- link->str = strndup(on, len);
726
-
742
+ if (NULL == (link->str = strndup(on, len))) {
743
+ return agoo_err_set(err, AGOO_ERR_MEMORY, "strdup or strndup of length %d failed.", len);
744
+ }
727
745
  return AGOO_ERR_OK;
728
746
  }
729
747
 
@@ -488,12 +488,13 @@ set_entry(agooLogEntry e, agooLogCat cat, const char *tid, const char *fmt, va_l
488
488
  }
489
489
  }
490
490
  if (NULL != tid) {
491
+ e->tidp = NULL;
491
492
  if (strlen(tid) < sizeof(e->tid)) {
492
493
  strcpy(e->tid, tid);
493
- e->tidp = NULL;
494
494
  } else {
495
- e->tidp = strdup(tid);
496
- *e->tid = '\0';
495
+ if (NULL != (e->tidp = strdup(tid))) {
496
+ *e->tid = '\0';
497
+ }
497
498
  }
498
499
  } else {
499
500
  e->tidp = NULL;
@@ -440,10 +440,13 @@ update_contents(agooPage p) {
440
440
  // fstat is called to get the file mode and verify it is a regular file or
441
441
  // a symlink.
442
442
  if (NULL != f) {
443
- fstat(fileno(f), &fs);
444
- if (!S_ISREG(fs.st_mode) && !S_ISLNK(fs.st_mode)) {
445
- fclose(f);
446
- f = NULL;
443
+ if (0 == fstat(fileno(f), &fs)) {
444
+ if (!S_ISREG(fs.st_mode) && !S_ISLNK(fs.st_mode)) {
445
+ fclose(f);
446
+ f = NULL;
447
+ }
448
+ } else {
449
+ return close_return_false(f);
447
450
  }
448
451
  }
449
452
  if (NULL == f) {
@@ -96,7 +96,9 @@ body_set(VALUE self, VALUE val) {
96
96
  agooResponse res = (agooResponse)DATA_PTR(self);
97
97
 
98
98
  if (T_STRING == rb_type(val)) {
99
- res->body = strdup(StringValuePtr(val));
99
+ if (NULL == (res->body = strdup(StringValuePtr(val)))) {
100
+ rb_raise(rb_eArgError, "failed to copy body");
101
+ }
100
102
  DEBUG_ALLOC(mem_res_body, res->body)
101
103
  res->blen = (int)RSTRING_LEN(val);
102
104
  } else {
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Agoo
3
3
  # Agoo version.
4
- VERSION = '2.5.6'
4
+ VERSION = '2.5.7'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.6
4
+ version: 2.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-26 00:00:00.000000000 Z
11
+ date: 2018-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -124,16 +124,12 @@ files:
124
124
  - ext/agoo/websocket.c
125
125
  - ext/agoo/websocket.h
126
126
  - lib/agoo.rb
127
- - lib/agoo/base.rb
128
- - lib/agoo/client.rb
129
127
  - lib/agoo/version.rb
130
128
  - lib/rack/handler/agoo.rb
131
129
  - test/base_handler_test.rb
132
130
  - test/bind_test.rb
133
131
  - test/hijack_test.rb
134
132
  - test/log_test.rb
135
- - test/named_client.rb
136
- - test/named_server.rb
137
133
  - test/rack_handler_test.rb
138
134
  - test/static_test.rb
139
135
  homepage: https://github.com/ohler55/agoo
@@ -167,16 +163,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
163
  requirements:
168
164
  - Linux or macOS
169
165
  rubyforge_project: agoo
170
- rubygems_version: 2.7.6
166
+ rubygems_version: 2.7.3
171
167
  signing_key:
172
168
  specification_version: 4
173
169
  summary: An HTTP server
174
170
  test_files:
175
- - test/named_client.rb
171
+ - test/base_handler_test.rb
172
+ - test/bind_test.rb
173
+ - test/hijack_test.rb
176
174
  - test/log_test.rb
177
175
  - test/rack_handler_test.rb
178
- - test/hijack_test.rb
179
- - test/named_server.rb
180
- - test/base_handler_test.rb
181
176
  - test/static_test.rb
182
- - test/bind_test.rb
@@ -1,84 +0,0 @@
1
-
2
- module Agoo
3
-
4
- # Maybe not the best class name but this class implements the base methds
5
- # for a Rack WebSocket/SSE handler. A handler does not have to inherit from
6
- # this class but the class does identify the methods supported.
7
- class Base
8
- attr_accessor :connection
9
-
10
- def initialize(env)
11
- # Nothing needs to be done on initialize although the #call env is
12
- # available if desired for some reason on creaton. After #on_open is
13
- # called the same env can be accessed through the client.
14
- end
15
-
16
- # Called when the WebSocket or SSE connection has been established. The
17
- # client represents the connection and cab be used to send messages to the
18
- # JavaScript WebSocket or SSE listener.
19
- def on_open(client)
20
- # save the client to support a send later on.
21
- @connection = client
22
- end
23
-
24
- # Called when the WebSocket or SSE connection is closed.
25
- def on_close(client)
26
- @connection = nil
27
- end
28
-
29
- # This indicates the send delivery queue is empty. Useful if attempting to
30
- # restrict the sends to one at a time.
31
- def on_drained(client)
32
- end
33
-
34
- # Called when the JavaScript listener sends a WebSocket message.
35
- def on_message(client, data)
36
- # Handle a received message.
37
- end
38
-
39
- # Called when an error occurs on the WebSocket or SSE connection.
40
- def on_error(client, err_msg)
41
- # Handle an error.
42
- end
43
-
44
- # Sends a message to the WebSocket or SSE listener.
45
- def send_message(msg)
46
- check_connection
47
- connection.write(msg)
48
- end
49
-
50
- # Closes the WebSocket or SSE connection. Note the connection can also be
51
- # closed by the JavaScript listener.
52
- def close
53
- check_connection
54
- connection.close
55
- end
56
-
57
- # The #subscribe, #unsubscribe, and #publish methods are not part of the
58
- # Rack SPEC but add added here to demonstrate the publish and subscribe
59
- # add-on that Agoo and Iodine provide. If you think it is something that
60
- # should be included in the Rack SPEC we can add that. It was left out as
61
- # it made the API more complex and
62
- def subscribe(subject)
63
- check_connection
64
- connection.subscribe(subject)
65
- end
66
-
67
- def unsubscribe(subject=nil)
68
- check_connection
69
- connection.unsubscribe(subject)
70
- end
71
-
72
- def publish(subject, message)
73
- check_connection
74
- connection.publish(subject, message)
75
- end
76
-
77
- private
78
-
79
- def check_connection
80
- raise StandardError.new('Not connected') if connection.nil?
81
- end
82
- end
83
-
84
- end
@@ -1,25 +0,0 @@
1
- module Agoo
2
-
3
- # A WebSocket/SSE middleware class. If a WebSocket connection has been
4
- # requested by a JavaScript listener then a success status (200) is returned
5
- # by the call method otherwise a 404 status is returned.
6
- class Client
7
-
8
- attr_accessor :handler_class
9
-
10
- def initialize(handler_class)
11
- @handler_class = handler_class
12
- end
13
-
14
- def call(env)
15
- unless env['rack.upgrade?'].nil?
16
- env['rack.upgrade'] = @handler_class.new(env)
17
- [ 200, { }, [ ] ]
18
- else
19
- [ 404, { }, [ ] ]
20
- end
21
- end
22
-
23
- end
24
- end
25
-
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'socket'
4
-
5
- UNIXSocket.open("/tmp/sockme") {|c|
6
- p c.read #=> "hi\n"
7
- }
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'socket'
4
-
5
- serv = UNIXServer.new("/tmp/sockme")
6
- begin
7
- sock = serv.accept_nonblock
8
- sock.puts "hello"
9
- sock.flush()
10
- rescue IO::WaitReadable, Errno::EINTR
11
- IO.select([serv])
12
- retry
13
- end