iodine 0.7.7 → 0.7.8

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

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f1e30dc08b1f6e19e59689fc251f50d1fe2de15377c36d9d6c0244a3a569352
4
- data.tar.gz: 3ea55ee5a0c809ba5f3bbde618beef72a2dd151242f5aadbf2b68c0d3a403d68
3
+ metadata.gz: 6ab6a6656db6e8d26002bb029212f5d5d65b8cfeaddf5550416ce796dc16dc70
4
+ data.tar.gz: aa23fa7aab530a3b448c2a52e63dffe52c8d8aee1e9259b53c7523e81b379876
5
5
  SHA512:
6
- metadata.gz: d0a8c45de3d93f4e7304a172b8111ea8cd0c5e727431fccb06982b930d596c571c3319819d72221dffe82cde14211bdefc1795ffc275fc8a5ba5255036bb81da
7
- data.tar.gz: 537d0c329cf43df25ca7318b99d049cc590103e2b65bb90058dc246b6d0442404ec70eda473f6d97d6020f4b7f4163a270f0dcc2e8a9285298fd07ca4c712808
6
+ metadata.gz: 51e9ac58a76b225d55ad354de3a1c25b25f7b286e88e819c3d067ddbc568521bdd9b87d1da9b7528b24528ccf7517f4762ef11a39894dfcacda8584d812526ee
7
+ data.tar.gz: 2623b6ea0a7957f92d8686ca80c2f8e6bbf61cf1a04dd0b1d49e20f6e25aa8b6dfdf35f2faa68d9929ec67cecdce0618c57abdf584038713b2e26d75a316bcb2
@@ -6,6 +6,15 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+
10
+ #### Change log v.0.7.8
11
+
12
+ **Fix**: `unsubscribe` possibly wouldn't unsubscribe from a connection-bound subscription when instructed to do so. This was discovered during a review of a issue #45 submitted by @ojab.
13
+
14
+ **Fix**: Documentation typo fixed by @ojab in PR#46.
15
+
16
+ **Fix**: Documentation errors exposed by @ojab regarding the pub/sub specification draft and the WebSocket/SSE specification draft.
17
+
9
18
  #### Change log v.0.7.7
10
19
 
11
20
  **Fix**: (facil.io) fixed critical issue with cookies, where no more than a single cookie could be set (duplicate headers would be zeroed out before being set). Credit to @ojab for exposing the issue.
@@ -14,15 +14,17 @@ This should simplify the idiomatic `subscribe` / `publish` approach to real-time
14
14
 
15
15
  ## Pub/Sub handling
16
16
 
17
- Conforming Pub/Sub implementations **MUST** extend the WebSocket and SSE callback objects to implement the following pub/sub related methods (this requires that either the Pub/Sub implementation has knowledge about the Server OR that the Server has knowledge about the Pub/Sub implementation):
17
+ Conforming Pub/Sub implementations **MUST** implement the following pub/sub related methods within the WebSocket/SSE `client` object (as defined in the Rack WebSockets / EventSource specification draft):
18
18
 
19
- * `subscribe(to, opt = {}) { |from, message| optional_block }` where `opt` is a Hash object that supports the following possible keys (undefined keys *SHOULD* be ignored):
19
+ * `subscribe(to, opt = {}) { |from, message| optional_block }` where `to` is a named *channel* and `opt` is a Hash object that *SHOULD* support the following possible keys (unsupported keys *MUST* be ignored):
20
20
 
21
- * `:match` indicates a matching algorithm should be applied. Possible values should include [`:redis`](https://github.com/antirez/redis/blob/398b2084af067ae4d669e0ce5a63d3bc89c639d3/src/util.c#L46-L167), [`:nats`](https://nats.io/documentation/faq/#wildcards) or [`:rabbitmq`](https://www.rabbitmq.com/tutorials/tutorial-five-ruby.html). Pub/Sub implementations should support some or all of these common pattern resolution schemes.
21
+ * `:match` indicates a matching algorithm should be applied to the `to` variable (`to` is a pattern).
22
22
 
23
- * `:handler` is an alternative to the optional block. It should accept Proc like opbjects (objects that answer to `call(from, msg)`).
23
+ Possible values should include [`:redis`](https://github.com/antirez/redis/blob/398b2084af067ae4d669e0ce5a63d3bc89c639d3/src/util.c#L46-L167), [`:nats`](https://nats.io/documentation/faq/#wildcards) or [`:rabbitmq`](https://www.rabbitmq.com/tutorials/tutorial-five-ruby.html). Pub/Sub implementations *MAY* support none, some or all of these common pattern resolution schemes.
24
+
25
+ * `:handler` is an alternative to the optional block. It should accept Proc like objects (objects that answer to `.call(from, msg)`).
24
26
 
25
- * If an optional `block` (or `:handler`) is provided, if will be called when a publication was received. Otherwise, the message alone (**not** the channel data) should be sent directly to the WebSocket / EventSource client.
27
+ * If an optional `block` (or `:handler`) is provided, if will be called when a publication was received. Otherwise, the message alone (**not** the channel data) **MUST** be sent directly to the WebSocket / EventSource client.
26
28
 
27
29
  * `:as` accepts either `:text` or `:binary` Symbol objects.
28
30
 
@@ -30,19 +32,17 @@ Conforming Pub/Sub implementations **MUST** extend the WebSocket and SSE callbac
30
32
 
31
33
  This will dictate the encoding for outgoing WebSocket message when publications are directly sent to the client (as a text message or a binary blob). `:text` will be the default value for a missing `:as` option.
32
34
 
33
- If the `subscribe` method is called within a WebSocket / SSE Callback object, the subscription must be associated with the Callback object and closed automatically when the connection is closed.
35
+ If a subscription to `to` already exists, it should be *replaced* by the new subscription (the old subscription should be canceled / unsubscribed).
34
36
 
35
- If the `subscribe` method isn't called from within a connection, it should be considered a global (non connection related) subscription and a `block` or `:handler` **MUST** be provided.
37
+ When the `subscribe` method is called within a WebSocket / SSE Callback object, the subscription must be closed automatically when the connection is closed.
36
38
 
37
- The `subscribe` method must return a subscription object if a subscription was scheduled (not necessarily performed). If it's already known that the subscription would fail, the method should return `nil`.
38
-
39
- The subscription object **MUST** support the method `close` (that will close the subscription).
39
+ The `subscribe` method **MUST** return `nil` on a known failure (i.e., when the connection is already closed), or any truthful value on success.
40
40
 
41
- The subscription object **MAY** support the method `to_s` (that will return a String representing the stream / channel / pattern).
41
+ A global variation for this method (allowing global subscriptions to be created) **SHOULD** be made available as `Rack::PubSub.subscribe`.
42
42
 
43
- The subscription object **MUST** support the method `==(str)` where `str` is a String object (that will return true if the subscription matches the String.
43
+ When the `subscribe` method isn't called from within a connection, it should be considered a global (non connection related) subscription and an exception should be raised if a `block` or `:handler` isn't provided by the user.
44
44
 
45
- A global variation for this method (allowing global subscriptions to be created) MUST be defined as `Rack::PubSub.subscribe`.
45
+ * `unsubscribe(from)` should cancel a subscription to the `from` named channel / pattern.
46
46
 
47
47
  * `publish(to, message, engine = nil)` (preferably supporting named arguments) where:
48
48
 
@@ -31,7 +31,7 @@ The historical use of `upgrade.websocket?` and `upgrade.websocket` (iodine 0.4.x
31
31
 
32
32
  WebSocket and EventSource connection upgrade and handling is performed using a Callback Object.
33
33
 
34
- The Callback Object should be a class (or an instance of such class) where **instances** implement any of the following callbacks:
34
+ The Callback Object could be a any object which implements any of the following callbacks:
35
35
 
36
36
  * `on_open(client)` WILL be called once the connection had been established.
37
37
 
@@ -102,14 +102,12 @@ Server settings **MAY** (not required) be provided to allow for customization an
102
102
 
103
103
  * **Client**:
104
104
 
105
- When a client decides to upgrade a request, they will place an appropriate Callback Object (either a class or an instance) in the `env['rack.upgrade']` Hash key.
105
+ When a client decides to upgrade a request, they will place an appropriate Callback Object in the `env['rack.upgrade']` Hash key.
106
106
 
107
107
  * **Server**:
108
108
 
109
109
  1. The server will review the `env` Hash *before* sending the response. If the `env['rack.upgrade']` was set, the server will perform the upgrade.
110
110
 
111
- **If the callback handler is a Class object, the server will create a new instance of that class**.
112
-
113
111
  2. The server will send the correct response status and headers, as well as any headers present in the response object. The server will also perform any required housekeeping, such as closing the response body, if it exists.
114
112
 
115
113
  The response status provided by the response object shall be ignored and the correct response status shall be set by the server.
@@ -499,7 +499,7 @@ static VALUE iodine_pubsub_subscribe(int argc, VALUE *argv, VALUE self) {
499
499
  if (args.block) {
500
500
  IodineStore.remove(args.block);
501
501
  }
502
- return Qnil; /* cannot subscribe a closed connection. */
502
+ return Qnil; /* cannot subscribe a closed / invalid connection. */
503
503
  }
504
504
  if (args.block == Qnil && args.binary) {
505
505
  args.block = Qtrue;
@@ -518,9 +518,8 @@ static VALUE iodine_pubsub_subscribe(int argc, VALUE *argv, VALUE self) {
518
518
  fio_unsubscribe(sub);
519
519
  fio_unlock(&c->lock);
520
520
  return Qnil;
521
- } else {
522
- iodine_sub_add(&c->subscriptions, sub);
523
521
  }
522
+ iodine_sub_add(&c->subscriptions, sub);
524
523
  fio_unlock(&c->lock);
525
524
  } else {
526
525
  fio_lock(&sub_lock);
@@ -546,20 +545,20 @@ Returns `false` if the subscription didn't exist.
546
545
  static VALUE iodine_pubsub_unsubscribe(VALUE self, VALUE name) {
547
546
  // clang-format on
548
547
  iodine_connection_data_s *c = NULL;
548
+ fio_lock_i *s_lock = &sub_lock;
549
+ fio_subhash_s *subs = &sub_global;
549
550
  VALUE ret;
550
- if (TYPE(self) == T_MODULE) {
551
- fio_lock(&sub_lock);
552
- ret = iodine_sub_unsubscribe(&sub_global, IODINE_RSTRINFO(name));
553
- fio_unlock(&sub_lock);
554
- } else {
551
+ if (TYPE(self) != T_MODULE) {
555
552
  c = iodine_connection_validate_data(self);
556
- if (!c) {
553
+ if (!c || c->info.uuid == -1) {
557
554
  return Qnil; /* cannot unsubscribe a closed connection. */
558
555
  }
559
- fio_lock(&sub_lock);
560
- ret = iodine_sub_unsubscribe(&sub_global, IODINE_RSTRINFO(name));
561
- fio_unlock(&sub_lock);
556
+ s_lock = &c->lock;
557
+ subs = &c->subscriptions;
562
558
  }
559
+ fio_lock(s_lock);
560
+ ret = iodine_sub_unsubscribe(subs, IODINE_RSTRINFO(name));
561
+ fio_unlock(s_lock);
563
562
  return ret;
564
563
  }
565
564
 
@@ -514,7 +514,7 @@ static inline int ruby2c_response_send(iodine_http_request_handle_s *handle,
514
514
  VALUE body = rb_ary_entry(rbresponse, 2);
515
515
  if (handle->h->status < 200 || handle->h->status == 204 ||
516
516
  handle->h->status == 304) {
517
- if (rb_respond_to(body, close_method_id))
517
+ if (body && rb_respond_to(body, close_method_id))
518
518
  IodineCaller.call(body, close_method_id);
519
519
  body = Qnil;
520
520
  handle->type = IODINE_HTTP_NONE;
@@ -523,6 +523,7 @@ static inline int ruby2c_response_send(iodine_http_request_handle_s *handle,
523
523
  if (TYPE(body) == T_ARRAY) {
524
524
  if (RARRAY_LEN(body) == 0) { // only headers
525
525
  handle->type = IODINE_HTTP_EMPTY;
526
+ return 0;
526
527
  } else if (RARRAY_LEN(body) == 1) { // [String] is likely
527
528
  body = rb_ary_entry(body, 0);
528
529
  // fprintf(stderr, "Body was a single item array, unpacket to string\n");
@@ -634,7 +635,7 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
634
635
  // close rack.io
635
636
  IodineRackIO.close(tmp);
636
637
  // test handler's return value
637
- if (rbresponse == 0 || rbresponse == Qnil)
638
+ if (rbresponse == 0 || rbresponse == Qnil || TYPE(rbresponse) != T_ARRAY)
638
639
  goto internal_error;
639
640
  IodineStore.add(rbresponse);
640
641
 
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.7.7'.freeze
2
+ VERSION = '0.7.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.7.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-11 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -244,7 +244,7 @@ licenses:
244
244
  - MIT
245
245
  metadata:
246
246
  allowed_push_host: https://rubygems.org
247
- post_install_message: 'Thank you for installing Iodine 0.7.7.
247
+ post_install_message: 'Thank you for installing Iodine 0.7.8.
248
248
 
249
249
  '
250
250
  rdoc_options: []