cable_x 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a00a68c2fd12c796e0c65e951579307e93edb3faa6467747dbc55a2abbd744d2
4
- data.tar.gz: 7b7a074b2674f927807fed9861d482598ec03a44fbaff7197e58b96eacc99bf4
3
+ metadata.gz: 73434793887fad45097125d4a9b449cee07ed4f7c99ded1173b620017906d4b4
4
+ data.tar.gz: 87731a5da2804aacb83abebfc6c64b647e7db7d987ed6d11104ee190b2acf48f
5
5
  SHA512:
6
- metadata.gz: cf0a175541d6b23fc81b03445ef5d7ebf7f556f3ed5b179defb4ba0455979573b1bc3b83c4168f43b99871f2fa46a2ff0fd33e0dc0558db6ed55dd62bda23fe8
7
- data.tar.gz: 977170bef821fc56a6f08b08887f09146cbd79f112d160cb1a98808d53e436ca9f8b063eb046bc3cf2352c572e296fc634219e57312513b81a3ac140698545b5
6
+ metadata.gz: 43f1f5576068478a6ea0c0a02f5f42b3f822b28a937297fd46cf0fbbebb9c4b695d9dfe85ace6e924680875ae6aea941fb8cb37fa69f94f33c2e7b1c45838ed1
7
+ data.tar.gz: 3c571c23fc5a40288110468f971ba411356b0c5a4451aa9fb2aaabdd519211a0e8e9c12484aedac84186c195a92a4ea2a8a3f9e34a37cce5d10fd6db45ddec5a
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Build Status](https://travis-ci.com/code-vedas/rails-cable-x.svg?branch=master)](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 Android, IOS, Angular, React, JS
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
- attr_accessor :device_id
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 = SecureRandom.hex(20)
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
@@ -12,12 +12,21 @@ module CableX
12
12
  isolate_namespace CableX
13
13
 
14
14
  def self.server
15
- config = Rails.application.config_for(:cable_x) rescue nil
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CableX
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
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.1
4
+ version: 0.1.2
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-04-20 00:00:00.000000000 Z
11
+ date: 2020-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,9 @@ files:
66
66
  - lib/cable_x.rb
67
67
  - lib/cable_x/cable/channel.rb
68
68
  - lib/cable_x/cable/connection.rb
69
+ - lib/cable_x/cable/rate_limit/block_check.rb
70
+ - lib/cable_x/cable/rate_limit/rate_limit.rb
71
+ - lib/cable_x/cable/rate_limit/rate_limit_redis.rb
69
72
  - lib/cable_x/channel/cable_x_channel.rb
70
73
  - lib/cable_x/channel/process/controller.rb
71
74
  - lib/cable_x/channel/process/request.rb