anycable-rails 0.6.4 → 1.0.0.rc2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -102
- data/MIT-LICENSE +1 -1
- data/README.md +37 -36
- data/lib/action_cable/subscription_adapter/any_cable.rb +2 -1
- data/lib/anycable/rails.rb +37 -2
- data/lib/anycable/rails/actioncable/channel.rb +4 -0
- data/lib/anycable/rails/actioncable/connection.rb +70 -50
- data/lib/anycable/rails/actioncable/connection/persistent_session.rb +30 -0
- data/lib/anycable/rails/actioncable/connection/serializable_identification.rb +42 -0
- data/lib/anycable/rails/actioncable/remote_connections.rb +11 -0
- data/lib/anycable/rails/channel_state.rb +48 -0
- data/lib/anycable/rails/compatibility.rb +7 -10
- data/lib/anycable/rails/compatibility/rubocop.rb +0 -1
- data/lib/anycable/rails/compatibility/rubocop/config/default.yml +3 -1
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb +1 -1
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb +4 -4
- data/lib/anycable/rails/config.rb +8 -4
- data/lib/anycable/rails/rack.rb +56 -0
- data/lib/anycable/rails/railtie.rb +17 -10
- data/lib/anycable/rails/refinements/subscriptions.rb +5 -0
- data/lib/anycable/rails/session_proxy.rb +79 -0
- data/lib/anycable/rails/version.rb +1 -1
- data/lib/generators/anycable/download/USAGE +14 -0
- data/lib/generators/anycable/download/download_generator.rb +77 -0
- data/lib/generators/anycable/setup/USAGE +2 -0
- data/lib/generators/anycable/setup/setup_generator.rb +258 -0
- data/lib/generators/anycable/setup/templates/Procfile.dev +3 -0
- data/lib/generators/anycable/setup/templates/config/anycable.yml.tt +43 -0
- data/lib/generators/anycable/setup/templates/config/cable.yml.tt +11 -0
- data/lib/generators/anycable/setup/templates/config/initializers/anycable.rb.tt +9 -0
- data/lib/generators/anycable/with_os_helpers.rb +55 -0
- metadata +42 -28
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/remote_disconnect.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0de4d95da59574a14f3f56219154cf3e12513a74e677520acf0cffbbf566e49
|
4
|
+
data.tar.gz: c6a4e9b87c3c59aac495663f8acc9f3150a8de5f43d5ab55d19c265039ba2af1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93f85efbfa20cffe71b3b52115b98321158577a36439b9875e6bbfb18ecee32c44fd31376a05f8883b8eff7d8b06b4d2d5abf762f86f6765248e3051869f3b17
|
7
|
+
data.tar.gz: 2ca2cd646321b0ed567af383847e4ae5f5cab116be0a7c410ea18d91f43378c024c47e3002c0aa70ddd0970a4e2bad50fd173c0b1fdf9088f229bad3ea53a05d
|
data/CHANGELOG.md
CHANGED
@@ -2,132 +2,56 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
## 0.
|
5
|
+
## 1.0.0.rc2 (2020-06-16)
|
6
6
|
|
7
|
-
- Fix
|
7
|
+
- Fix connection identifiers deserialization regression. ([@palkan][])
|
8
8
|
|
9
|
-
|
10
|
-
the `ActionCable::Channel::Base` patching in the core functionality (which uses `alias`).
|
9
|
+
Using non-strings or non-GlobalId-encoded objects was broken.
|
11
10
|
|
12
|
-
|
11
|
+
- Improve `anycable:setup` generator. ([@palkan][])
|
13
12
|
|
14
|
-
|
13
|
+
Update Docker snippet, do not enable persistent sessions automatically,
|
14
|
+
fix setting `config.action_cable.url` in environment configuration.
|
15
15
|
|
16
|
-
|
16
|
+
## 1.0.0.rc1 (2020-06-10)
|
17
17
|
|
18
|
-
- Add
|
18
|
+
- Add `state_attr_accessor` for channels. ([@palkan][])
|
19
19
|
|
20
|
-
|
20
|
+
Just like `attr_accessor` but "persists" the state between RPC calls.
|
21
21
|
|
22
|
-
|
22
|
+
- Add `Channel#stop_stream_from` support. ([@palkan][])
|
23
23
|
|
24
|
-
|
24
|
+
- Add `RemoteConnections` support. ([@palkan][])
|
25
25
|
|
26
|
-
-
|
26
|
+
- Add `AnyCable::Rails.enabled?` method which returns true if Action Cable uses AnyCable adapter. ([@palkan][])
|
27
27
|
|
28
|
-
|
28
|
+
- Add `anycable:download` generator to download `anycable-go` binary. ([@palkan][])
|
29
29
|
|
30
|
-
-
|
30
|
+
- **Ruby 2.5+ is required**. ([@palkan][])
|
31
31
|
|
32
|
-
-
|
32
|
+
- Support `disconnect` messages. ([@palkan][])
|
33
33
|
|
34
|
-
|
34
|
+
Added in Rails 6 (see [PR#34194](https://github.com/rails/rails/pull/34194)).
|
35
35
|
|
36
|
-
|
36
|
+
- Add ability to persist _dirty_ `request.session` between RPC calls. ([@palkan][])
|
37
37
|
|
38
|
-
|
38
|
+
This feature emulates the Action Cable behaviour where it's possible to use `request.session` as a shared Hash-like store.
|
39
|
+
This could be used by some applications (e.g., [StimulusReflex](https://github.com/hopsoft/stimulus_reflex)-based).
|
39
40
|
|
40
|
-
|
41
|
-
identifiers.
|
41
|
+
You must turn this feature on by setting `persistent_session_enabled: true` in the AnyCable configuration.
|
42
42
|
|
43
|
-
|
43
|
+
- Add ability to use Rack middlewares when build a request for a connection. ([@bibendi][])
|
44
44
|
|
45
|
-
|
45
|
+
- Add set up generator to configure a Rails application by running `bin/rails g anycable:setup`. ([@bibendi][])
|
46
46
|
|
47
|
-
-
|
47
|
+
- Require a minimum version of Ruby when installing the gem. ([@bibendi][])
|
48
48
|
|
49
|
-
- Add
|
49
|
+
- Add ability to develop the gem with Docker. ([@bibendi][])
|
50
50
|
|
51
|
-
-
|
52
|
-
|
53
|
-
- Action Cable monkey-patches are only loaded in the context of AnyCable CLI. ([@palkan][])
|
54
|
-
|
55
|
-
No need to think about `requie` and `group` for `anycable-rails`, just add it to Gemfile.
|
56
|
-
|
57
|
-
- Add `:any_cable` subscription adapter for Action Cable. ([@palkan][])
|
58
|
-
|
59
|
-
Use `:any_cable` adapter for Action Cable to broadcast data to AnyCable.
|
60
|
-
|
61
|
-
No more `pubsub` monkey-patches 🎉.
|
62
|
-
|
63
|
-
- Added Rails executor/reloader support. ([@palkan][])
|
64
|
-
|
65
|
-
- **[Breaking]** No more generators. ([@palkan][])
|
66
|
-
|
67
|
-
No need to generate AnyCable runner script since `anycable` gem ships with
|
68
|
-
the CLI.
|
69
|
-
|
70
|
-
- Add dynamic (`AnyCable::CompatibilityError`) compatibility checks. ([@DmitryTsepelev][])
|
71
|
-
|
72
|
-
- Added static (RuboCop) compatibility checks. ([@DmitryTsepelev][])
|
73
|
-
|
74
|
-
See https://github.com/anycable/anycable-rails/issues/52
|
75
|
-
|
76
|
-
## 0.5.4 (2018-06-13)
|
77
|
-
|
78
|
-
- Fix duplicate logs in development. ([@palkan][])
|
79
|
-
|
80
|
-
Fixes https://github.com/anycable/anycable_demo/issues/5.
|
81
|
-
|
82
|
-
## 0.5.3
|
83
|
-
|
84
|
-
- Fix return value of `Connection#handle_close`. ([@palkan][])
|
85
|
-
|
86
|
-
Should always be `true`, we do not expect a failure here.
|
87
|
-
|
88
|
-
## 0.5.2
|
89
|
-
|
90
|
-
- Add config/anycable.yml to Rails generator. ([@alekseyl][])
|
91
|
-
|
92
|
-
## 0.5.1
|
93
|
-
|
94
|
-
- Improve Rails integration. ([@palkan][])
|
95
|
-
|
96
|
-
Log to STDOUT in development.
|
97
|
-
Make order of initializers more deterministic.
|
98
|
-
Show warning if AnyCable is loaded after application initialization.
|
99
|
-
|
100
|
-
## 0.5.0
|
101
|
-
|
102
|
-
- [#17](https://github.com/anycable/anycable-rails/issues/17) Refactor logging. ([@palkan][])
|
103
|
-
|
104
|
-
Use Rails logger everywhere.
|
105
|
-
|
106
|
-
Add access logs ([anycable/anycable#20](https://github.com/anycable/anycable/issues/20)).
|
107
|
-
|
108
|
-
## 0.4.7
|
109
|
-
|
110
|
-
- Minor fixes. ([@palkan][])
|
111
|
-
|
112
|
-
## 0.4.6
|
113
|
-
|
114
|
-
- Disable mounting default Action Cable server when AnyCable is loaded. ([@palkan][])
|
115
|
-
|
116
|
-
## 0.4.5
|
117
|
-
|
118
|
-
- Handle tagged logger. ([@palkan][])
|
119
|
-
|
120
|
-
Ignore tagged logger features ('cause we do not have _persistent_ logger).
|
121
|
-
|
122
|
-
## 0.4.4
|
123
|
-
|
124
|
-
- Fix bug with ActiveRecord connections (https://github.com/anycable/anycable/issues/9). ([@palkan][])
|
125
|
-
|
126
|
-
## 0.4.0
|
127
|
-
|
128
|
-
- Initial version. ([@palkan][])
|
51
|
+
See [Changelog](https://github.com/anycable/anycable-rails/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
|
129
52
|
|
130
53
|
[@palkan]: https://github.com/palkan
|
131
54
|
[@alekseyl]: https://github.com/alekseyl
|
132
55
|
[@DmitryTsepelev]: https://github.com/DmitryTsepelev
|
133
56
|
[@sponomarev]: https://github.com/sponomarev
|
57
|
+
[@bibendi]: https://github.com/bibendi
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
[](https://gitpitch.com/anycable/anycable/master?grs=github)
|
1
|
+
[](https://gitpitch.com/anycable/anycable/master?grs=github)
|
2
|
+
[](https://rubygems.org/gems/anycable-rails)
|
3
|
+
[](https://github.com/anycable/anycable-rails/actions)
|
2
4
|
[](https://gitter.im/anycable/Lobby)
|
3
|
-
[](https://docs.anycable.io
|
5
|
+
[](https://docs.anycable.io/v1/#/ruby/rails)
|
4
6
|
|
5
7
|
# AnyCable Rails
|
6
8
|
|
@@ -10,27 +12,23 @@ With AnyCable you can use channels, client-side JS, broadcasting - (almost) all
|
|
10
12
|
|
11
13
|
You can even use Action Cable in development and not be afraid of [compatibility issues](#compatibility).
|
12
14
|
|
13
|
-
|
15
|
+
**Important** This is a readme for the upcoming v1.0 release. For v0.6.x see the readme from the [0-6-stable](https://github.com/anycable/anycable-rails/tree/0-6-stable) branch.
|
14
16
|
|
15
|
-
|
17
|
+
<!-- 💾 [Example Application](https://github.com/anycable/anycable_demo) -->
|
16
18
|
|
19
|
+
📑 [Documentation](https://docs.anycable.io/v1/#/ruby/rails).
|
17
20
|
|
18
21
|
<a href="https://evilmartians.com/">
|
19
22
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
20
23
|
|
21
24
|
## Requirements
|
22
25
|
|
23
|
-
- Ruby
|
24
|
-
- Rails
|
25
|
-
- Redis (see [other options]() for broadcasting)
|
26
|
-
|
27
|
-
## How It Works?
|
28
|
-
|
29
|
-
<img src="https://trello-attachments.s3.amazonaws.com/5781e0ed48e4679e302833d3/820x987/5b6a305417b04e20e75f49c5816e027c/Anycable_vs_ActionCable_copy.jpg" width="400" />
|
26
|
+
- Ruby >= 2.5
|
27
|
+
- Rails >= 5.2
|
28
|
+
- Redis (see [other options](https://github.com/anycable/anycable/issues/2) for broadcasting)
|
30
29
|
|
31
30
|
## Usage
|
32
31
|
|
33
|
-
|
34
32
|
Add `anycable-rails` gem to your Gemfile:
|
35
33
|
|
36
34
|
```ruby
|
@@ -40,14 +38,25 @@ gem "anycable-rails"
|
|
40
38
|
gem "redis", ">= 4.0"
|
41
39
|
```
|
42
40
|
|
43
|
-
|
41
|
+
### Interactive set up
|
44
42
|
|
45
|
-
|
43
|
+
After the gem was installed, you can run an interactive wizard to configure your Rails application for using with AnyCable by running a generator:
|
44
|
+
|
45
|
+
```sh
|
46
|
+
bundle exec rails g anycable:setup
|
47
|
+
```
|
48
|
+
|
49
|
+
### Manual set up
|
50
|
+
|
51
|
+
Specify AnyCable subscription adapter for Action Cable:
|
46
52
|
|
47
53
|
```yml
|
48
54
|
# config/cable.yml
|
49
|
-
|
55
|
+
development:
|
50
56
|
adapter: any_cable # or anycable
|
57
|
+
|
58
|
+
production:
|
59
|
+
adapter: any_cable
|
51
60
|
```
|
52
61
|
|
53
62
|
and specify AnyCable WebSocket server URL:
|
@@ -64,9 +73,9 @@ config.action_cable.url = "ws://localhost:3334/cable"
|
|
64
73
|
config.action_cable.url = "wss://ws.example.com/cable"
|
65
74
|
```
|
66
75
|
|
67
|
-
|
76
|
+
Then, run AnyCable RPC server:
|
68
77
|
|
69
|
-
```
|
78
|
+
```sh
|
70
79
|
$ bundle exec anycable
|
71
80
|
|
72
81
|
# don't forget to provide Rails env
|
@@ -74,38 +83,30 @@ $ bundle exec anycable
|
|
74
83
|
$ RAILS_ENV=production bundle exec anycable
|
75
84
|
```
|
76
85
|
|
77
|
-
And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io
|
86
|
+
And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io/v1/#/anycable-go/getting_started):
|
78
87
|
|
79
88
|
```sh
|
80
89
|
anycable-go --host=localhost --port=3334
|
81
90
|
```
|
82
91
|
|
83
|
-
See [documentation](https://docs.anycable.io
|
92
|
+
See [documentation](https://docs.anycable.io/v1/#/ruby/rails) for more information on AnyCable + Rails usage.
|
84
93
|
|
85
94
|
## Action Cable Compatibility
|
86
95
|
|
87
|
-
See [documentation](https://docs.anycable.io
|
88
|
-
|
89
|
-
## Links
|
96
|
+
See [documentation](https://docs.anycable.io/v1/#/ruby/compatibility).
|
90
97
|
|
91
|
-
|
92
|
-
|
93
|
-
- [From Action to Any](https://medium.com/@leshchuk/from-action-to-any-1e8d863dd4cf) by [@alekseyl](https://github.com/alekseyl)
|
94
|
-
|
95
|
-
## Talks
|
98
|
+
## Contributing
|
96
99
|
|
97
|
-
|
100
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable-rails](https://github.com/anycable/anycable-rails).
|
98
101
|
|
99
|
-
|
102
|
+
## Development
|
100
103
|
|
101
|
-
|
104
|
+
If you are familiar with Docker, you can use [DIP](https://github.com/bibendi/dip) to start developing the gem quickly.
|
102
105
|
|
103
|
-
|
104
|
-
- [ErlyCable](https://github.com/anycable/erlycable)
|
106
|
+
## License
|
105
107
|
|
106
|
-
|
108
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
107
109
|
|
108
|
-
|
110
|
+
## Security Contact
|
109
111
|
|
110
|
-
|
111
|
-
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
112
|
+
To report a security vulnerability, please contact us at `anycable@evilmartians.com`. We will coordinate the fix and disclosure.
|
data/lib/anycable/rails.rb
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
require "anycable"
|
4
4
|
require "anycable/rails/version"
|
5
5
|
require "anycable/rails/config"
|
6
|
+
require "anycable/rails/rack"
|
7
|
+
|
8
|
+
require "globalid"
|
6
9
|
|
7
10
|
module AnyCable
|
8
11
|
# Rails handler for AnyCable
|
@@ -11,8 +14,40 @@ module AnyCable
|
|
11
14
|
|
12
15
|
ADAPTER_ALIASES = %w[any_cable anycable].freeze
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
class << self
|
18
|
+
def enabled?
|
19
|
+
adapter = ::ActionCable.server.config.cable&.fetch("adapter", nil)
|
20
|
+
compatible_adapter?(adapter)
|
21
|
+
end
|
22
|
+
|
23
|
+
def compatible_adapter?(adapter)
|
24
|
+
ADAPTER_ALIASES.include?(adapter)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Serialize connection/channel state variable to string
|
28
|
+
# using GlobalID where possible or JSON (if json: true)
|
29
|
+
def serialize(obj, json: false)
|
30
|
+
obj.try(:to_gid_param) || (json ? obj.to_json : obj)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Deserialize previously serialized value from string to
|
34
|
+
# Ruby object.
|
35
|
+
# If the resulting object is a Hash, make it indifferent
|
36
|
+
def deserialize(str, json: false)
|
37
|
+
str.yield_self do |val|
|
38
|
+
next val unless val.is_a?(String)
|
39
|
+
|
40
|
+
gval = GlobalID::Locator.locate(val)
|
41
|
+
return gval if gval
|
42
|
+
|
43
|
+
next val unless json
|
44
|
+
|
45
|
+
JSON.parse(val)
|
46
|
+
end.yield_self do |val|
|
47
|
+
next val.with_indifferent_access if val.is_a?(Hash)
|
48
|
+
val
|
49
|
+
end
|
50
|
+
end
|
16
51
|
end
|
17
52
|
end
|
18
53
|
end
|
@@ -28,6 +28,10 @@ module ActionCable
|
|
28
28
|
connection.socket.subscribe identifier, broadcasting
|
29
29
|
end
|
30
30
|
|
31
|
+
def stop_stream_from(broadcasting)
|
32
|
+
connection.socket.unsubscribe identifier, broadcasting
|
33
|
+
end
|
34
|
+
|
31
35
|
def stop_all_streams
|
32
36
|
connection.socket.unsubscribe_from_all identifier
|
33
37
|
end
|
@@ -1,43 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "action_cable/connection"
|
4
|
+
require "anycable/rails/actioncable/connection/serializable_identification"
|
4
5
|
require "anycable/rails/refinements/subscriptions"
|
5
6
|
require "anycable/rails/actioncable/channel"
|
7
|
+
require "anycable/rails/actioncable/remote_connections"
|
8
|
+
require "anycable/rails/session_proxy"
|
6
9
|
|
7
10
|
module ActionCable
|
8
11
|
module Connection
|
9
12
|
# rubocop: disable Metrics/ClassLength
|
10
13
|
class Base # :nodoc:
|
11
|
-
# We store logger tags in
|
14
|
+
# We store logger tags in the connection state to be able
|
12
15
|
# to re-use them in the subsequent calls
|
13
16
|
LOG_TAGS_IDENTIFIER = "__ltags__"
|
14
17
|
|
15
18
|
using AnyCable::Refinements::Subscriptions
|
16
19
|
|
20
|
+
include SerializableIdentification
|
21
|
+
|
17
22
|
attr_reader :socket
|
18
23
|
|
24
|
+
delegate :env, :session, to: :request
|
25
|
+
|
19
26
|
class << self
|
20
27
|
def call(socket, **options)
|
21
|
-
new(socket, options)
|
28
|
+
new(socket, nil, options)
|
22
29
|
end
|
30
|
+
end
|
23
31
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
32
|
+
def initialize(socket, env, identifiers: "{}", subscriptions: [])
|
33
|
+
if env
|
34
|
+
# If env is set, then somehow we're in the context of Action Cable
|
35
|
+
# Return and print a warning in #process
|
36
|
+
@request = ActionDispatch::Request.new(env)
|
37
|
+
return
|
31
38
|
end
|
32
|
-
end
|
33
39
|
|
34
|
-
def initialize(socket, identifiers: "{}", subscriptions: [])
|
35
40
|
@ids = ActiveSupport::JSON.decode(identifiers)
|
36
41
|
|
37
|
-
@ltags =
|
42
|
+
@ltags = socket.cstate.read(LOG_TAGS_IDENTIFIER).yield_self do |raw_tags|
|
43
|
+
next unless raw_tags
|
44
|
+
ActiveSupport::JSON.decode(raw_tags)
|
45
|
+
end
|
38
46
|
|
39
47
|
@cached_ids = {}
|
40
|
-
@env = socket.env
|
41
48
|
@coder = ActiveSupport::JSON
|
42
49
|
@socket = socket
|
43
50
|
@subscriptions = ActionCable::Connection::Subscriptions.new(self)
|
@@ -46,15 +53,32 @@ module ActionCable
|
|
46
53
|
subscriptions.each { |id| @subscriptions.fetch(id) }
|
47
54
|
end
|
48
55
|
|
56
|
+
def process
|
57
|
+
# Use Rails logger here to print to stdout in development
|
58
|
+
logger.error invalid_request_message
|
59
|
+
logger.info finished_request_message
|
60
|
+
[404, {"Content-Type" => "text/plain"}, ["Page not found"]]
|
61
|
+
end
|
62
|
+
|
63
|
+
def invalid_request_message
|
64
|
+
"You're trying to connect to Action Cable server while using AnyCable. " \
|
65
|
+
"See https://docs.anycable.io/v1/#/troubleshooting?id=server-raises-an-argumenterror-exception-when-client-tries-to-connect"
|
66
|
+
end
|
67
|
+
|
49
68
|
def handle_open
|
50
69
|
logger.info started_request_message if access_logs?
|
51
70
|
|
52
|
-
verify_origin!
|
71
|
+
verify_origin! || return
|
53
72
|
|
54
73
|
connect if respond_to?(:connect)
|
74
|
+
|
75
|
+
socket.cstate.write(LOG_TAGS_IDENTIFIER, fetch_ltags.to_json)
|
76
|
+
|
55
77
|
send_welcome_message
|
56
78
|
rescue ActionCable::Connection::Authorization::UnauthorizedError
|
57
|
-
reject_request
|
79
|
+
reject_request(
|
80
|
+
ActionCable::INTERNAL[:disconnect_reasons]&.[](:unauthorized) || "unauthorized"
|
81
|
+
)
|
58
82
|
end
|
59
83
|
|
60
84
|
def handle_close
|
@@ -84,7 +108,12 @@ module ActionCable
|
|
84
108
|
end
|
85
109
|
# rubocop:enable Metrics/MethodLength
|
86
110
|
|
87
|
-
def close
|
111
|
+
def close(reason: nil, reconnect: nil)
|
112
|
+
transmit(
|
113
|
+
type: ActionCable::INTERNAL[:message_types].fetch(:disconnect, "disconnect"),
|
114
|
+
reason: reason,
|
115
|
+
reconnect: reconnect
|
116
|
+
)
|
88
117
|
socket.close
|
89
118
|
end
|
90
119
|
|
@@ -92,37 +121,14 @@ module ActionCable
|
|
92
121
|
socket.transmit encode(cable_message)
|
93
122
|
end
|
94
123
|
|
95
|
-
# Generate identifiers info.
|
96
|
-
# Converts GlobalID compatible vars to corresponding global IDs params.
|
97
|
-
def identifiers_hash
|
98
|
-
obj = { LOG_TAGS_IDENTIFIER => fetch_ltags }
|
99
|
-
|
100
|
-
identifiers.each_with_object(obj) do |id, acc|
|
101
|
-
obj = instance_variable_get("@#{id}")
|
102
|
-
next unless obj
|
103
|
-
|
104
|
-
acc[id] = obj.try(:to_gid_param) || obj
|
105
|
-
end.compact
|
106
|
-
end
|
107
|
-
|
108
|
-
def identifiers_json
|
109
|
-
identifiers_hash.to_json
|
110
|
-
end
|
111
|
-
|
112
|
-
# Fetch identifier and deserialize if neccessary
|
113
|
-
def fetch_identifier(name)
|
114
|
-
@cached_ids[name] ||= @cached_ids.fetch(name) do
|
115
|
-
val = ids[name.to_s]
|
116
|
-
next val unless val.is_a?(String)
|
117
|
-
|
118
|
-
GlobalID::Locator.locate(val) || val
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
124
|
def logger
|
123
125
|
@logger ||= TaggedLoggerProxy.new(AnyCable.logger, tags: ltags || [])
|
124
126
|
end
|
125
127
|
|
128
|
+
def request
|
129
|
+
@request ||= build_rack_request
|
130
|
+
end
|
131
|
+
|
126
132
|
private
|
127
133
|
|
128
134
|
attr_reader :ids, :ltags
|
@@ -158,19 +164,33 @@ module ActionCable
|
|
158
164
|
end
|
159
165
|
|
160
166
|
def verify_origin!
|
161
|
-
return unless socket.env.key?("HTTP_ORIGIN")
|
167
|
+
return true unless socket.env.key?("HTTP_ORIGIN")
|
162
168
|
|
163
|
-
return if allow_request_origin?
|
169
|
+
return true if allow_request_origin?
|
164
170
|
|
165
|
-
|
166
|
-
ActionCable::
|
167
|
-
"Origin is not allowed"
|
171
|
+
reject_request(
|
172
|
+
ActionCable::INTERNAL[:disconnect_reasons]&.[](:invalid_request) || "invalid_request"
|
168
173
|
)
|
174
|
+
false
|
169
175
|
end
|
170
176
|
|
171
|
-
def reject_request
|
177
|
+
def reject_request(reason, reconnect = false)
|
172
178
|
logger.info finished_request_message("Rejected") if access_logs?
|
173
|
-
close
|
179
|
+
close(
|
180
|
+
reason: reason,
|
181
|
+
reconnect: reconnect
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
def build_rack_request
|
186
|
+
environment = Rails.application.env_config.merge(socket.env)
|
187
|
+
AnyCable::Rails::Rack.app.call(environment)
|
188
|
+
|
189
|
+
ActionDispatch::Request.new(environment)
|
190
|
+
end
|
191
|
+
|
192
|
+
def request_loaded?
|
193
|
+
instance_variable_defined?(:@request)
|
174
194
|
end
|
175
195
|
end
|
176
196
|
# rubocop:enable Metrics/ClassLength
|