perimeter_x 1.2.0 → 2.2.0

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.
Files changed (34) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -0
  4. data/Dockerfile +12 -7
  5. data/Gemfile.lock +36 -30
  6. data/Rakefile +1 -0
  7. data/changelog.md +58 -0
  8. data/examples/app/controllers/home_controller.rb +1 -1
  9. data/lib/perimeter_x.rb +195 -71
  10. data/lib/perimeterx/configuration.rb +74 -22
  11. data/lib/perimeterx/internal/clients/perimeter_x_activity_client.rb +32 -6
  12. data/lib/perimeterx/internal/exceptions/px_config_exception.rb +6 -0
  13. data/lib/perimeterx/internal/first_party/px_first_party.rb +124 -0
  14. data/lib/perimeterx/internal/{perimeter_x_cookie_v1.rb → payload/perimeter_x_cookie_v1.rb} +1 -1
  15. data/lib/perimeterx/internal/{perimeter_x_cookie_v3.rb → payload/perimeter_x_cookie_v3.rb} +1 -1
  16. data/lib/perimeterx/internal/{perimeter_x_cookie.rb → payload/perimeter_x_payload.rb} +12 -4
  17. data/lib/perimeterx/internal/payload/perimeter_x_token_v1.rb +38 -0
  18. data/lib/perimeterx/internal/payload/perimeter_x_token_v3.rb +36 -0
  19. data/lib/perimeterx/internal/perimeter_x_context.rb +74 -32
  20. data/lib/perimeterx/internal/validators/hash_schema_validator.rb +26 -0
  21. data/lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb +29 -21
  22. data/lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb +33 -9
  23. data/lib/perimeterx/utils/px_constants.rb +35 -17
  24. data/lib/perimeterx/utils/px_http_client.rb +60 -3
  25. data/lib/perimeterx/utils/px_template_factory.rb +18 -8
  26. data/lib/perimeterx/utils/templates/block_template.mustache +175 -0
  27. data/lib/perimeterx/utils/templates/ratelimit.mustache +9 -0
  28. data/lib/perimeterx/version.rb +1 -1
  29. data/perimeter_x.gemspec +3 -3
  30. data/readme.md +115 -31
  31. metadata +24 -20
  32. data/lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb +0 -65
  33. data/lib/perimeterx/utils/templates/block.mustache +0 -146
  34. data/lib/perimeterx/utils/templates/captcha.mustache +0 -185
@@ -1,41 +1,89 @@
1
1
  require 'perimeterx/utils/px_logger'
2
+ require 'perimeterx/utils/px_constants'
2
3
 
3
4
  module PxModule
4
5
  class PerimeterXContext
5
6
 
6
7
  attr_accessor :context
7
8
  attr_accessor :px_config
9
+
10
+ # class methods
11
+
12
+ def self.extract_ip(req, px_config)
13
+ # Get IP from header/custom function
14
+ if px_config[:ip_headers].length() > 0
15
+ px_config[:ip_headers].each do |ip_header|
16
+ if req.headers[ip_header]
17
+ return PerimeterXContext.force_utf8(req.headers[ip_header])
18
+ end
19
+ end
20
+ elsif px_config[:ip_header_function] != nil
21
+ return px_config[:ip_header_function].call(req)
22
+ end
23
+ return req.ip
24
+ end
25
+
26
+ def self.force_utf8(str)
27
+ return str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
28
+ end
29
+
30
+ # instance methods
8
31
 
9
32
  def initialize(px_config, req)
10
- @logger = px_config[:logger];
11
- @logger.debug("PerimeterXContext[initialize] ")
33
+ @logger = px_config[:logger]
34
+ @logger.debug('PerimeterXContext[initialize]')
12
35
  @context = Hash.new
13
36
 
14
37
  @context[:px_cookie] = Hash.new
15
38
  @context[:headers] = Hash.new
39
+ @context[:cookie_origin] = 'cookie'
40
+ @context[:made_s2s_risk_api_call] = false
41
+ @context[:first_party_enabled] = px_config[:first_party_enabled]
42
+
16
43
  cookies = req.cookies
17
- if (!cookies.empty?)
44
+
45
+ @context[:ip] = PerimeterXContext.extract_ip(req, px_config)
46
+
47
+ # Get token from header
48
+ if req.headers[PxModule::TOKEN_HEADER]
49
+ @context[:cookie_origin] = 'header'
50
+ token = PerimeterXContext.force_utf8(req.headers[PxModule::TOKEN_HEADER])
51
+ if token.match(PxModule::MOBILE_TOKEN_V3_REGEX)
52
+ @context[:px_cookie][:v3] = token[2..-1]
53
+ elsif token.match(PxModule::MOBILE_ERROR_REGEX)
54
+ @context[:mobile_error] = token
55
+ if req.headers[PxModule::ORIGINAL_TOKEN_HEADER]
56
+ token = PerimeterXContext.force_utf8(req.headers[PxModule::ORIGINAL_TOKEN_HEADER])
57
+ if token.match(PxModule::MOBILE_TOKEN_V3_REGEX)
58
+ @context[:px_cookie][:v3] = token[2..-1]
59
+ end
60
+ end
61
+ end
62
+ elsif !cookies.empty? # Get cookie from jar
18
63
  # Prepare hashed cookies
19
64
  cookies.each do |k, v|
20
65
  case k.to_s
21
- when "_px3"
22
- @context[:px_cookie][:v3] = v
23
- when "_px"
24
- @context[:px_cookie][:v1] = v
25
- when "_pxCaptcha"
26
- @context[:px_captcha] = v
66
+ when '_px3'
67
+ @context[:px_cookie][:v3] = PerimeterXContext.force_utf8(v)
68
+ when '_px'
69
+ @context[:px_cookie][:v1] = PerimeterXContext.force_utf8(v)
70
+ when '_pxvid'
71
+ if v.is_a?(String) && v.match(PxModule::VID_REGEX)
72
+ @context[:vid_source] = "vid_cookie"
73
+ @context[:vid] = PerimeterXContext.force_utf8(v)
74
+ end
27
75
  end
28
76
  end #end case
29
77
  end #end empty cookies
30
78
 
31
79
  req.headers.each do |k, v|
32
- if (k.start_with? "HTTP_")
33
- header = k.to_s.gsub("HTTP_", "")
34
- header = header.gsub("_", "-").downcase
35
- @context[:headers][header.to_sym] = v
80
+ if (k.start_with? 'HTTP_')
81
+ header = k.to_s.gsub('HTTP_', '')
82
+ header = header.gsub('_', '-').downcase
83
+ @context[:headers][header.to_sym] = PerimeterXContext.force_utf8(v)
36
84
  end
37
85
  end #end headers foreach
38
-
86
+
39
87
  @context[:hostname]= req.server_name
40
88
  @context[:user_agent] = req.user_agent ? req.user_agent : ''
41
89
  @context[:uri] = px_config[:custom_uri] ? px_config[:custom_uri].call(req) : req.fullpath
@@ -43,18 +91,10 @@ module PxModule
43
91
  @context[:format] = req.format.symbol
44
92
  @context[:score] = 0
45
93
 
46
- if px_config.key?(:custom_user_ip)
47
- @context[:ip] = req.headers[px_config[:custom_user_ip]]
48
- elsif px_config.key?(:px_custom_user_ip_method)
49
- @context[:ip] = px_config[:px_custom_user_ip_method].call(req)
50
- else
51
- @context[:ip] = req.ip
52
- end
53
-
54
94
  if req.server_protocol
55
- httpVer = req.server_protocol.split("/")
95
+ httpVer = req.server_protocol.split('/')
56
96
  if httpVer.size > 0
57
- @context[:http_version] = httpVer[1];
97
+ @context[:http_version] = httpVer[1]
58
98
  end
59
99
  end
60
100
  @context[:http_method] = req.method
@@ -65,19 +105,21 @@ module PxModule
65
105
  sensitive_routes.each do |sensitive_route|
66
106
  return true if uri.start_with? sensitive_route
67
107
  end
68
- return false
108
+ false
69
109
  end
70
110
 
71
111
  def set_block_action_type(action)
72
112
  @context[:block_action] = case action
73
- when "c"
74
- "captcha"
75
- when "b"
76
- return "block"
77
- when "j"
78
- return "challenge"
113
+ when 'c'
114
+ 'captcha'
115
+ when 'b'
116
+ return 'block'
117
+ when 'j'
118
+ return 'challenge'
119
+ when 'r'
120
+ return 'rate_limit'
79
121
  else
80
- return "captcha"
122
+ return captcha
81
123
  end
82
124
  end
83
125
 
@@ -0,0 +1,26 @@
1
+ def validate_hash_schema(hash, schema)
2
+ hash.each do |key, value|
3
+ if schema.key?(key) && value != nil
4
+ # validate value types in hash are according to schema
5
+ if !schema[key][:types].include?(value.class)
6
+ raise PxConfigurationException.new("PerimeterX: Type of #{key} should be one of #{schema[key][:types]} but instead is #{value.class}")
7
+ end
8
+
9
+ # validate arrays elments types are according to schema
10
+ if value.class == Array
11
+ value.each do |element|
12
+ if !schema[key][:allowed_element_types].include?(element.class)
13
+ raise PxConfigurationException.new("PerimeterX: #{key} may only contain elements of the following types: #{schema[key][:allowed_element_types]} but includes element of type #{element.class}")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ # validate required fields exist in hash
21
+ schema.each do |key, value|
22
+ if value[:required] && hash[key].nil?
23
+ raise PxConfigurationException.new("PerimeterX: #{key} configuration is missing")
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,9 @@
1
1
  require 'perimeterx/utils/px_constants'
2
- require 'perimeterx/internal/perimeter_x_cookie'
3
- require 'perimeterx/internal/perimeter_x_cookie_v1'
4
- require 'perimeterx/internal/perimeter_x_cookie_v3'
2
+ require 'perimeterx/internal/payload/perimeter_x_payload'
3
+ require 'perimeterx/internal/payload/perimeter_x_token_v1'
4
+ require 'perimeterx/internal/payload/perimeter_x_token_v3'
5
+ require 'perimeterx/internal/payload/perimeter_x_cookie_v1'
6
+ require 'perimeterx/internal/payload/perimeter_x_cookie_v3'
5
7
 
6
8
  module PxModule
7
9
  class PerimeterxCookieValidator
@@ -16,57 +18,63 @@ module PxModule
16
18
 
17
19
  def verify(px_ctx)
18
20
  begin
19
- # Case no cookie
20
21
  if px_ctx.context[:px_cookie].empty?
21
- @logger.warn("PerimeterxCookieValidator:[verify]: cookie not found")
22
+ @logger.warn("PerimeterxCookieValidator:[verify]: no cookie")
22
23
  px_ctx.context[:s2s_call_reason] = PxModule::NO_COOKIE
23
24
  return false, px_ctx
24
25
  end
25
-
26
+
26
27
  # Deserialize cookie start
27
- cookie = PerimeterxCookie.px_cookie_factory(px_ctx, @px_config)
28
- if (!cookie.deserialize())
28
+ cookie = PerimeterxPayload.px_cookie_factory(px_ctx, @px_config)
29
+ if !cookie.deserialize()
29
30
  @logger.warn("PerimeterxCookieValidator:[verify]: invalid cookie")
31
+ px_ctx.context[:px_orig_cookie] = px_ctx.get_px_cookie
30
32
  px_ctx.context[:s2s_call_reason] = PxModule::COOKIE_DECRYPTION_FAILED
31
33
  return false, px_ctx
32
34
  end
33
35
  px_ctx.context[:decoded_cookie] = cookie.decoded_cookie
34
36
  px_ctx.context[:score] = cookie.cookie_score()
35
37
  px_ctx.context[:uuid] = cookie.decoded_cookie[:u]
36
- px_ctx.context[:vid] = cookie.decoded_cookie[:v]
37
38
  px_ctx.context[:block_action] = px_ctx.set_block_action_type(cookie.cookie_block_action())
38
39
  px_ctx.context[:cookie_hmac] = cookie.cookie_hmac()
39
40
 
40
- if (cookie.expired?)
41
+ vid = cookie.decoded_cookie[:v]
42
+ if vid.is_a?(String) && vid.match(PxModule::VID_REGEX)
43
+ px_ctx.context[:vid_source] = "risk_cookie"
44
+ px_ctx.context[:vid] = vid
45
+ end
46
+
47
+ if cookie.expired?
41
48
  @logger.warn("PerimeterxCookieValidator:[verify]: cookie expired")
42
49
  px_ctx.context[:s2s_call_reason] = PxModule::EXPIRED_COOKIE
43
50
  return false, px_ctx
44
51
  end
45
52
 
46
- if (cookie.high_score?)
53
+ if cookie.high_score?
47
54
  @logger.warn("PerimeterxCookieValidator:[verify]: cookie high score")
48
- px_ctx.context[:s2s_call_reason] = PxModule::COOKIE_HIGH_SCORE
55
+ px_ctx.context[:blocking_reason] = 'cookie_high_score'
49
56
  return true, px_ctx
50
57
  end
51
58
 
52
- if (!cookie.secured?)
59
+ if !cookie.secured?
53
60
  @logger.warn("PerimeterxCookieValidator:[verify]: cookie invalid hmac")
54
- px_ctx.context[:s2s_call_reason] = PxModule::COOKIE_VALIDATION_FAILED
61
+ px_ctx.context[:s2s_call_reason] = PxModule:: COOKIE_VALIDATION_FAILED
62
+ return false, px_ctx
63
+ end
64
+
65
+ if px_ctx.context[:sensitive_route]
66
+ @logger.info("PerimeterxCookieValidator:[verify]: cookie was verified but route is sensitive")
67
+ px_ctx.context[:s2s_call_reason] = PxModule::SENSITIVE_ROUTE
55
68
  return false, px_ctx
56
69
  end
57
-
58
- if (px_ctx.context[:sensitive_route])
59
- @logger.info("PerimeterxCookieValidator:[verify]: cookie was verified but route is sensitive")
60
- px_ctx.context[:s2s_call_reason] = PxModule::SENSITIVE_ROUTE
61
- return false, px_ctx
62
- end
63
70
 
64
71
  @logger.debug("PerimeterxCookieValidator:[verify]: cookie validation passed succesfully")
65
72
 
73
+ px_ctx.context[:pass_reason] = 'cookie'
66
74
  return true, px_ctx
67
75
  rescue Exception => e
68
76
  @logger.error("PerimeterxCookieValidator:[verify]: exception while verifying cookie => #{e.message}")
69
- px_ctx.context[:px_orig_cookie] = cookie.px_cookie
77
+ px_ctx.context[:px_orig_cookie] = px_ctx.context[:px_cookie]
70
78
  px_ctx.context[:s2s_call_reason] = PxModule::COOKIE_DECRYPTION_FAILED
71
79
  return false, px_ctx
72
80
  end
@@ -5,11 +5,11 @@ module PxModule
5
5
 
6
6
  def initialize(px_config, http_client)
7
7
  super(px_config, http_client)
8
- @logger.debug("PerimeterxS2SValidator[initialize]")
8
+ @logger.debug('PerimeterxS2SValidator[initialize]')
9
9
  end
10
10
 
11
11
  def send_risk_request(px_ctx)
12
- @logger.debug("PerimeterxS2SValidator[send_risk_request]: send_risk_request")
12
+ @logger.debug('PerimeterxS2SValidator[send_risk_request]: send_risk_request')
13
13
 
14
14
  risk_mode = PxModule::RISK_MODE_ACTIVE
15
15
  if @px_config[:module_mode] == PxModule::MONITOR_MODE
@@ -31,6 +31,17 @@ module PxModule
31
31
  :risk_mode => risk_mode
32
32
  }
33
33
  }
34
+
35
+ #Check for cookie_origin
36
+ if !px_ctx.context[:px_cookie].empty?
37
+ request_body[:additional][:cookie_origin] = px_ctx.context[:cookie_origin]
38
+ end
39
+
40
+ #Override s2s_call_reason in case of mobile error
41
+ if !px_ctx.context[:mobile_error].nil?
42
+ request_body[:additional][:s2s_call_reason] = "mobile_error_#{px_ctx.context[:mobile_error]}"
43
+ end
44
+
34
45
  #Check for hmac
35
46
  @logger.debug("px_ctx cookie_hmac key = #{px_ctx.context.key?(:cookie_hmac)}, value is: #{px_ctx.context[:cookie_hmac]}")
36
47
  if px_ctx.context.key?(:cookie_hmac)
@@ -66,11 +77,19 @@ module PxModule
66
77
  };
67
78
 
68
79
  # Custom risk handler
80
+ risk_start = Time.now
69
81
  if (risk_mode == PxModule::ACTIVE_MODE && @px_config.key?(:custom_risk_handler))
70
- response = @px_config[:custom_risk_handler].call(PxModule::API_V2_RISK, request_body, headers, @px_config[:api_timeout], @px_config[:api_timeout_connection])
82
+ response = @px_config[:custom_risk_handler].call(PxModule::API_V3_RISK, request_body, headers, @px_config[:api_timeout], @px_config[:api_timeout_connection])
71
83
  else
72
- response = @http_client.post(PxModule::API_V2_RISK , request_body, headers, @px_config[:api_timeout], @px_config[:api_timeout_connection])
84
+ response = @http_client.post(PxModule::API_V3_RISK , request_body, headers, @px_config[:api_timeout], @px_config[:api_timeout_connection])
85
+ end
86
+
87
+ # Set risk_rtt
88
+ if(response)
89
+ risk_end = Time.now
90
+ px_ctx.context[:risk_rtt] = ((risk_end-risk_start)*1000).round
73
91
  end
92
+
74
93
  return response
75
94
  end
76
95
 
@@ -78,6 +97,7 @@ module PxModule
78
97
  @logger.debug("PerimeterxS2SValidator[verify]")
79
98
  response = send_risk_request(px_ctx)
80
99
  if (!response)
100
+ px_ctx.context[:pass_reason] = "s2s_timeout"
81
101
  return px_ctx
82
102
  end
83
103
  px_ctx.context[:made_s2s_risk_api_call] = true
@@ -85,7 +105,7 @@ module PxModule
85
105
  # From here response should be valid, if success or error
86
106
  response_body = eval(response.body);
87
107
  # When success
88
- if (response.code == 200 && response_body.key?(:score) && response_body.key?(:action))
108
+ if (response.code == 200 && response_body.key?(:score) && response_body.key?(:action) && response_body.key?(:status) && response_body[:status] == 0 )
89
109
  @logger.debug("PerimeterxS2SValidator[verify]: response ok")
90
110
  score = response_body[:score]
91
111
  px_ctx.context[:score] = score
@@ -96,14 +116,18 @@ module PxModule
96
116
  px_ctx.context[:blocking_reason] = 'challenge'
97
117
  elsif (score >= @px_config[:blocking_score])
98
118
  px_ctx.context[:blocking_reason] = 's2s_high_score'
119
+ else
120
+ px_ctx.context[:pass_reason] = 's2s'
99
121
  end #end challange or blocking score
100
122
  end #end success response
101
123
 
102
124
  # When error
103
- if(response.code != 200)
104
- @logger.warn("PerimeterxS2SValidator[verify]: bad response, return code #{response.code}")
105
- px_ctx.context[:uuid] = ""
106
- px_ctx.context[:s2s_error_msg] = response_body[:message]
125
+ risk_error_status = response_body && response_body.key?(:status) && response_body[:status] == -1
126
+ if(response.code != 200 || risk_error_status)
127
+ @logger.warn("PerimeterxS2SValidator[verify]: bad response, returned code #{response.code} #{risk_error_status ? "risk status: -1" : ""}")
128
+ px_ctx.context[:pass_reason] = 'request_failed'
129
+ px_ctx.context[:uuid] = (!response_body || response_body[:uuid].nil?)? "" : response_body[:uuid]
130
+ px_ctx.context[:s2s_error_msg] = !response_body || response_body[:message].nil? ? 'unknown' : response_body[:message]
107
131
  end
108
132
 
109
133
  @logger.debug("PerimeterxS2SValidator[verify]: done")
@@ -4,33 +4,34 @@ module PxModule
4
4
  # Misc
5
5
  MONITOR_MODE = 1
6
6
  ACTIVE_MODE = 2
7
- RISK_MODE_ACTIVE = "active_blocking"
8
- RISK_MODE_MONITOR = "monitor"
7
+ RISK_MODE_ACTIVE = 'active_blocking'
8
+ RISK_MODE_MONITOR = 'monitor'
9
9
  SDK_NAME = "RUBY SDK v#{PxModule::VERSION}"
10
10
 
11
11
  # Routes
12
- API_V1_S2S = "/api/v1/collector/s2s"
13
- API_V1_CAPTCHA = "/api/v1/risk/captcha"
14
- API_V2_RISK = "/api/v2/risk"
12
+ API_V1_S2S = '/api/v1/collector/s2s'
13
+ API_V3_RISK = '/api/v3/risk'
15
14
 
16
15
  # Activity Types
17
- BLOCK_ACTIVITY = "block"
18
- PAGE_REQUESTED_ACTIVITY = "page_requested"
16
+ BLOCK_ACTIVITY = 'block'
17
+ PAGE_REQUESTED_ACTIVITY = 'page_requested'
19
18
 
20
19
  # PxContext
21
- NO_COOKIE = "no_cookie"
22
- INVALID_COOKIE = "invalid_cookie"
23
- EXPIRED_COOKIE = "cookie_expired"
24
- COOKIE_HIGH_SCORE = "cookie_high_score"
25
- COOKIE_VALIDATION_FAILED = "cookie_validation_failed"
26
- COOKIE_DECRYPTION_FAILED = "cookie_decryption_failed"
27
- SENSITIVE_ROUTE = "sensitive_route"
20
+ NO_COOKIE = 'no_cookie'
21
+ INVALID_COOKIE = 'invalid_cookie'
22
+ EXPIRED_COOKIE = 'cookie_expired'
23
+ COOKIE_HIGH_SCORE = 'cookie_high_score'
24
+ COOKIE_VALIDATION_FAILED = 'cookie_validation_failed'
25
+ COOKIE_DECRYPTION_FAILED = 'cookie_decryption_failed'
26
+ SENSITIVE_ROUTE = 'sensitive_route'
28
27
 
29
28
  # Templates
30
- BLOCK_TEMPLATE = "block.mustache"
31
- CAPTCHA_TEMPLATE = "captcha.mustache"
29
+ CHALLENGE_TEMPLATE = 'block_template'
30
+ TEMPLATE_EXT = '.mustache'
31
+ RATELIMIT_TEMPLATE = 'ratelimit'
32
32
 
33
- # Tempalte Props
33
+
34
+ # Template Props
34
35
  PROP_REF_ID = :refId
35
36
  PROP_APP_ID = :appId
36
37
  PROP_VID = :vid
@@ -39,7 +40,24 @@ module PxModule
39
40
  PROP_CUSTOM_LOGO = :customLogo
40
41
  PROP_CSS_REF = :cssRef
41
42
  PROP_JS_REF = :jsRef
43
+ PROP_BLOCK_SCRIPT = :blockScript
44
+ PROP_JS_CLIENT_SRC = :jsClientSrc
45
+ PROP_HOST_URL = :hostUrl
46
+ PROP_FIRST_PARTY_ENABLED = :firstPartyEnabled
47
+
48
+ # Hosts
49
+ CLIENT_HOST = 'client.perimeterx.net'
50
+ CAPTCHA_HOST = 'captcha.px-cdn.net'
42
51
 
43
52
  VISIBLE = 'visible'
44
53
  HIDDEN = 'hidden'
54
+
55
+ # Mobile SDK
56
+ TOKEN_HEADER = 'X-PX-AUTHORIZATION'
57
+ ORIGINAL_TOKEN_HEADER = 'X-PX-ORIGINAL-TOKEN'
58
+
59
+ # Regular Expressions
60
+ VID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
61
+ MOBILE_TOKEN_V3_REGEX = /\A3:(.*)\z/
62
+ MOBILE_ERROR_REGEX = /\A[0-9]\z/
45
63
  end
@@ -1,6 +1,7 @@
1
1
  require 'perimeterx/utils/px_logger'
2
2
  require 'typhoeus'
3
3
  require 'concurrent'
4
+ require 'net/http'
4
5
 
5
6
  module PxModule
6
7
  class PxHttpClient
@@ -12,10 +13,10 @@ module PxModule
12
13
  def initialize(px_config)
13
14
  @px_config = px_config
14
15
  @logger = px_config[:logger]
15
- @logger.debug("PxHttpClient[initialize]: HTTP client is being initilized with base_uri: #{px_config[:perimeterx_server_host]}")
16
+ @logger.debug("PxHttpClient[initialize]: HTTP client is being initilized with base_uri: #{px_config[:backend_url]}")
16
17
  end
17
18
 
18
- # Runs a POST commant to Perimeter X servers
19
+ # Runs a POST command to Perimeter X servers
19
20
  # Params:
20
21
  # +path+:: string containing uri
21
22
  # +body+:: hash object, containing the request body, must be converted to json format
@@ -28,7 +29,7 @@ module PxModule
28
29
  begin
29
30
  @logger.debug("PxHttpClient[post]: posting to #{path} headers {#{headers.to_json()}} body: {#{body.to_json()}} ")
30
31
  response = Typhoeus.post(
31
- "#{px_config[:perimeterx_server_host]}#{path}",
32
+ "#{px_config[:backend_url]}#{path}",
32
33
  headers: headers,
33
34
  body: body.to_json,
34
35
  timeout: api_timeout,
@@ -45,5 +46,61 @@ module PxModule
45
46
  return response
46
47
  end
47
48
 
49
+
50
+ def post_xhr(url, body, headers)
51
+ s = Time.now
52
+ begin
53
+ @logger.debug("PxHttpClient[post]: sending xhr post request to #{url} with headers {#{headers.to_json()}}")
54
+
55
+ #set url
56
+ uri = URI(url)
57
+ req = Net::HTTP::Post.new(uri)
58
+
59
+ # set body
60
+ req.body=body
61
+
62
+ # set headers
63
+ headers.each do |key, value|
64
+ req[key] = value
65
+ end
66
+
67
+ # send request
68
+ response = Net::HTTP.start(uri.hostname, uri.port) {|http|
69
+ http.request(req)
70
+ }
71
+
72
+ ensure
73
+ e = Time.now
74
+ @logger.debug("PxHttpClient[get]: runtime: #{(e-s) * 1000.0}")
75
+ end
76
+ return response
77
+ end
78
+
79
+
80
+ def get(url, headers)
81
+ s = Time.now
82
+ begin
83
+ @logger.debug("PxHttpClient[get]: sending get request to #{url} with headers {#{headers.to_json()}}")
84
+
85
+ #set url
86
+ uri = URI(url)
87
+ req = Net::HTTP::Get.new(uri)
88
+
89
+ # set headers
90
+ headers.each do |key, value|
91
+ req[key] = value
92
+ end
93
+
94
+ # send request
95
+ response = Net::HTTP.start(uri.hostname, uri.port) {|http|
96
+ http.request(req)
97
+ }
98
+
99
+ ensure
100
+ e = Time.now
101
+ @logger.debug("PxHttpClient[get]: runtime: #{(e-s) * 1000.0}")
102
+ end
103
+ return response
104
+ end
48
105
  end
49
106
  end