cable_x 0.1.1 → 0.1.6
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/README.md +1 -1
- data/lib/cable_x/cable/connection.rb +61 -2
- data/lib/cable_x/cable/rate_limit/block_check.rb +29 -0
- data/lib/cable_x/cable/rate_limit/rate_limit.rb +32 -0
- data/lib/cable_x/cable/rate_limit/rate_limit_redis.rb +35 -0
- data/lib/cable_x/engine.rb +11 -2
- data/lib/cable_x/version.rb +1 -1
- metadata +6 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12dfea97139c9364d319c3bfbf8ea093a1e552bf8cbd5ce60873c65e1dfac9f1
|
4
|
+
data.tar.gz: 84212609c6d83a9883f06973d1f26d7c9e21255699c363dec5b75e8e2b0866c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2873873b9abdeabc33b147b9a488480a23480ec699a50299b3d2af5157e72f585b07c6796546f32162b531c35e33c1c0f3df147271dc8ee0967ad3b1ed32646
|
7
|
+
data.tar.gz: 6219397aa479e469aa8e8048c3b33f55a16f02632d1aa48069dd1883fbec35f1fe28e4ebb0778386ed8e16db0cdc3ab9f5461fbe30a6fce659d0ef24101dedf7
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
[](https://travis-ci.com/code-vedas/rails-cable-x)
|
6
6
|
|
7
7
|
# CableX
|
8
|
-
Standard MVC over cable for realtime applications to enjoy seamless experience over cable. Use specialized clients for
|
8
|
+
Standard MVC over cable for realtime applications to enjoy seamless experience over cable. Use specialized clients for [Angular](https://github.com/Code-Vedas/ngx-cable-x),[JS](https://github.com/Code-Vedas/cable-x-js),[React](https://github.com/Code-Vedas/cable-x-js),Android, IOS
|
9
9
|
|
10
10
|
Clients for Android, IOS, Angular, React, JS coming soon.
|
11
11
|
## Usage
|
@@ -1,15 +1,74 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './rate_limit/block_check'
|
4
|
+
require_relative './rate_limit/rate_limit'
|
5
|
+
require_relative './rate_limit/rate_limit_redis'
|
6
|
+
|
3
7
|
module CableX
|
4
8
|
module Cable
|
5
9
|
##
|
6
10
|
# Connection class to serve entry point
|
7
11
|
class Connection < ActionCable::Connection::Base
|
8
|
-
|
12
|
+
include RateLimit::RateLimitRedis
|
13
|
+
include RateLimit::CheckRateLimit
|
14
|
+
include RateLimit::BlockCheck
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_accessor :rate_limit, :redis_config
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :device_id, :rate_limit, :redis_config, :redis
|
9
21
|
identified_by :device_id
|
10
22
|
|
11
23
|
def connect
|
12
|
-
self.device_id =
|
24
|
+
self.device_id = Digest::SHA1.hexdigest(request_str)
|
25
|
+
setup_rate_limit
|
26
|
+
rescue StandardError => _e
|
27
|
+
reject_unauthorized_connection
|
28
|
+
end
|
29
|
+
|
30
|
+
def receive(message)
|
31
|
+
if (blocked_unit = check_block) || (blocked_unit = do_rate_limit)
|
32
|
+
disconnect_client(blocked_unit)
|
33
|
+
elsif check_message(message)
|
34
|
+
super(message)
|
35
|
+
else
|
36
|
+
malformed_message_response
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def close(reason, reconnect = false)
|
41
|
+
transmit(type: ActionCable::INTERNAL[:message_types][:disconnect],
|
42
|
+
reason: reason,
|
43
|
+
reconnect: reconnect)
|
44
|
+
websocket.close
|
45
|
+
end
|
46
|
+
|
47
|
+
def malformed_message_response
|
48
|
+
transmit(type: 'error',
|
49
|
+
message: 'malformed_message')
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_message(message)
|
53
|
+
JSON.parse(message) rescue false
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup_rate_limit
|
57
|
+
self.rate_limit = self.class.rate_limit
|
58
|
+
self.redis_config = self.class.redis_config
|
59
|
+
if rate_limit
|
60
|
+
self.redis = Redis.new(url: redis_config[:url])
|
61
|
+
raise StandardError, 'Rate limiting: Slow down!. Try after some time' if check_block
|
62
|
+
end
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def request_str
|
67
|
+
headers_to_get = %w[SERVER_PROTOCOL SERVER_SOFTWARE REQUEST_METHOD REQUEST_PATH HTTP_USER_AGENT\
|
68
|
+
HTTP_CONNECTION HTTP_ORIGIN REMOTE_ADDR ORIGINAL_FULLPATH ORIGINAL_SCRIPT_NAME\
|
69
|
+
action_dispatch.authorized_host]
|
70
|
+
headers = request.headers.to_h
|
71
|
+
headers_to_get.map { |key| headers[key] }.join('-').gsub(' ', '')
|
13
72
|
end
|
14
73
|
end
|
15
74
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CableX
|
4
|
+
module Cable
|
5
|
+
module RateLimit
|
6
|
+
##
|
7
|
+
# Process Rate Limit
|
8
|
+
module BlockCheck
|
9
|
+
def check_block
|
10
|
+
check_block_unit('second') || check_block_unit('minute') || check_block_unit('hour') if rate_limit
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_block_unit(unit)
|
14
|
+
unit if redis_exists block_device_key(unit)
|
15
|
+
end
|
16
|
+
|
17
|
+
def block_device(unit)
|
18
|
+
redis_set block_device_key(unit), true, rate_limit[:cool_down].send('second') * 1000
|
19
|
+
unit
|
20
|
+
end
|
21
|
+
|
22
|
+
def disconnect_client(unit)
|
23
|
+
close("Rate limiting: Limit exceeded for per #{unit} Slow down!. Try after some time", false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# "Rate limiting: Slow down!. Try after some time"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CableX
|
4
|
+
module Cable
|
5
|
+
module RateLimit
|
6
|
+
##
|
7
|
+
# Process Rate Limit
|
8
|
+
module CheckRateLimit
|
9
|
+
def do_rate_limit
|
10
|
+
check_rate_limit if rate_limit
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_rate_limit
|
14
|
+
check_unit('second') || check_unit('minute') || check_unit('hour')
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_unit(unit)
|
18
|
+
check_value = rate_limit[unit.to_s.to_sym]
|
19
|
+
return unless check_value
|
20
|
+
|
21
|
+
key = device_key unit
|
22
|
+
redis_set key, 0, 1.send(unit) * 1000 unless redis_exists(key)
|
23
|
+
redis_incr key
|
24
|
+
block_connection = (redis_get(key) || -1).to_i >= check_value
|
25
|
+
return unless block_connection
|
26
|
+
|
27
|
+
block_device unit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CableX
|
4
|
+
module Cable
|
5
|
+
module RateLimit
|
6
|
+
##
|
7
|
+
# Process Rate Limit
|
8
|
+
module RateLimitRedis
|
9
|
+
def redis_set(key, value, expire_millisecond)
|
10
|
+
redis.set key, value, px: expire_millisecond
|
11
|
+
end
|
12
|
+
|
13
|
+
def redis_incr(key)
|
14
|
+
redis.incr key
|
15
|
+
end
|
16
|
+
|
17
|
+
def redis_exists(key)
|
18
|
+
redis.exists? key
|
19
|
+
end
|
20
|
+
|
21
|
+
def redis_get(key)
|
22
|
+
redis.get key
|
23
|
+
end
|
24
|
+
|
25
|
+
def device_key(schedule)
|
26
|
+
"#{redis_config[:channel_prefix]}-rl-#{schedule}-#{device_id}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def block_device_key(schedule)
|
30
|
+
"#{redis_config[:channel_prefix]}-rl-block-#{schedule}-#{device_id}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/cable_x/engine.rb
CHANGED
@@ -12,12 +12,21 @@ module CableX
|
|
12
12
|
isolate_namespace CableX
|
13
13
|
|
14
14
|
def self.server
|
15
|
-
|
16
|
-
self.allowed_request_origins = config[:allowed_request_origins] if config
|
15
|
+
setup_rate_limiting
|
17
16
|
server = CableX::Server.server
|
18
17
|
server.config.connection_class = -> { CableX::Cable::Connection }
|
19
18
|
server.config.allowed_request_origins = allowed_request_origins
|
20
19
|
server
|
21
20
|
end
|
21
|
+
|
22
|
+
def self.setup_rate_limiting
|
23
|
+
cable_config = Rails.application.config_for(:cable) rescue nil
|
24
|
+
cable_x_config = Rails.application.config_for(:cable_x) rescue nil
|
25
|
+
self.allowed_request_origins = cable_x_config[:allowed_request_origins]
|
26
|
+
return unless cable_x_config && cable_config && cable_config[:adapter] == 'redis'
|
27
|
+
|
28
|
+
CableX::Cable::Connection.redis_config = cable_config
|
29
|
+
CableX::Cable::Connection.rate_limit = cable_x_config[:rate_limit]
|
30
|
+
end
|
22
31
|
end
|
23
32
|
end
|
data/lib/cable_x/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cable_x
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nitesh Purohit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,34 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '5.1'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: coveralls
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.8.23
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.8.23
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 4.0.0
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 4.0.0
|
55
27
|
description: Standard MVC over cable for realtime applications to enjoy seamless experience
|
56
28
|
over cable. Use specialized clients for Android, IOS, Angular, React, JS
|
57
29
|
email:
|
@@ -66,6 +38,9 @@ files:
|
|
66
38
|
- lib/cable_x.rb
|
67
39
|
- lib/cable_x/cable/channel.rb
|
68
40
|
- lib/cable_x/cable/connection.rb
|
41
|
+
- lib/cable_x/cable/rate_limit/block_check.rb
|
42
|
+
- lib/cable_x/cable/rate_limit/rate_limit.rb
|
43
|
+
- lib/cable_x/cable/rate_limit/rate_limit_redis.rb
|
69
44
|
- lib/cable_x/channel/cable_x_channel.rb
|
70
45
|
- lib/cable_x/channel/process/controller.rb
|
71
46
|
- lib/cable_x/channel/process/request.rb
|
@@ -99,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
74
|
- !ruby/object:Gem::Version
|
100
75
|
version: 1.8.11
|
101
76
|
requirements: []
|
102
|
-
rubygems_version: 3.0.
|
77
|
+
rubygems_version: 3.0.8
|
103
78
|
signing_key:
|
104
79
|
specification_version: 4
|
105
80
|
summary: Standard MVC over cable for realtime applications to enjoy seamless experience
|