active_utils 2.2.3 → 3.3.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/.github/probots.yml +2 -0
  3. data/.travis.yml +39 -3
  4. data/CHANGELOG.md +92 -0
  5. data/CONTRIBUTING.md +32 -0
  6. data/Gemfile +1 -1
  7. data/README.md +30 -16
  8. data/active_utils.gemspec +4 -1
  9. data/gemfiles/Gemfile.activesupport-master +4 -0
  10. data/gemfiles/Gemfile.activesupport42 +4 -0
  11. data/gemfiles/Gemfile.activesupport50 +4 -0
  12. data/gemfiles/Gemfile.activesupport52 +4 -0
  13. data/lib/active_utils/{common/connection.rb → connection.rb} +9 -3
  14. data/lib/active_utils/{common/country.rb → country.rb} +18 -3
  15. data/lib/active_utils/currency_code.rb +56 -0
  16. data/lib/active_utils/{common/error.rb → error.rb} +8 -6
  17. data/lib/active_utils/{common/network_connection_retries.rb → network_connection_retries.rb} +27 -11
  18. data/lib/active_utils/{common/post_data.rb → post_data.rb} +1 -1
  19. data/lib/active_utils/{common/posts_data.rb → posts_data.rb} +19 -10
  20. data/lib/active_utils/{common/requires_parameters.rb → requires_parameters.rb} +1 -1
  21. data/lib/active_utils/{common/validateable.rb → validateable.rb} +1 -1
  22. data/lib/active_utils/version.rb +1 -1
  23. data/lib/active_utils.rb +17 -16
  24. data/lib/certs/cacert.pem +1701 -2393
  25. data/test/test_helper.rb +7 -4
  26. data/test/unit/connection_test.rb +43 -15
  27. data/test/unit/country_test.rb +19 -0
  28. data/test/unit/network_connection_retries_test.rb +88 -11
  29. data/test/unit/post_data_test.rb +6 -6
  30. data/test/unit/posts_data_test.rb +19 -4
  31. data/test/unit/validateable_test.rb +1 -1
  32. metadata +38 -41
  33. checksums.yaml.gz.sig +0 -0
  34. data/lib/active_utils/common/currency_code.rb +0 -50
  35. data/lib/active_utils/common/utils.rb +0 -20
  36. data/test/unit/utils_test.rb +0 -7
  37. data.tar.gz.sig +0 -1
  38. metadata.gz.sig +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: def25d8c6aeca09233b68a4e1d6e5748215d0d50
4
- data.tar.gz: 778d5f3ff833254e76024bc5e5b45bb439cda634
2
+ SHA256:
3
+ metadata.gz: 3c236e83dc0c4b35da1b23d174deee446185fa5ba2eebd342bf28f329c33823d
4
+ data.tar.gz: 0cbc00453c11d9fde11335b86c62413d41bd4b29998922875a0c34de844e47c7
5
5
  SHA512:
6
- metadata.gz: 843e2ba1585d9ce106af3ab0fa782665afdd82c2819fd3105986a93d42bb94d207e09e0210f40f3b01bb813fd75bdefe09911e766a489402734b69fd1bcb83d5
7
- data.tar.gz: 7497572318783cb10d8f3eaacdbbb153ed8e5703d36260724d6b3e69d2afe224e337b25d5b9323ba8a71ef0178c31483b68315d786b1791fe574b98b0a93a3f6
6
+ metadata.gz: f8b71761d493d48d0a774bfaeab6d9ad06a608cc4188307070bcdba77ede74ff4ab16bac8a4bad04f29dc74280864034eaba9c1f3008b173ccb300a86a792ac8
7
+ data.tar.gz: d744cab2ae63bff0abcee7e4b1f627d87bc5836f9e8df7483d7b3da9e2693311177406bac67c4dc9399b045074baaa10325ae58f4c05ca817bc67b45d899fc4a
@@ -0,0 +1,2 @@
1
+ enabled:
2
+ - cla
data/.travis.yml CHANGED
@@ -1,5 +1,41 @@
1
1
  language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 2.1.2
5
2
  script: bundle exec rake test
3
+ sudo: false
4
+
5
+ rvm:
6
+ - "2.0"
7
+ - "2.1"
8
+ - "2.2"
9
+ - "2.3"
10
+ - "2.4"
11
+ - "2.5"
12
+
13
+ before_install:
14
+ - gem update bundler
15
+
16
+ gemfile:
17
+ - gemfiles/Gemfile.activesupport42
18
+ - gemfiles/Gemfile.activesupport50
19
+ - gemfiles/Gemfile.activesupport52
20
+ - gemfiles/Gemfile.activesupport-master
21
+
22
+ matrix:
23
+ exclude:
24
+ - rvm: "2.0"
25
+ gemfile: gemfiles/Gemfile.activesupport50
26
+ - rvm: "2.0"
27
+ gemfile: gemfiles/Gemfile.activesupport52
28
+ - rvm: "2.0"
29
+ gemfile: gemfiles/Gemfile.activesupport-master
30
+ - rvm: "2.1"
31
+ gemfile: gemfiles/Gemfile.activesupport50
32
+ - rvm: "2.1"
33
+ gemfile: gemfiles/Gemfile.activesupport52
34
+ - rvm: "2.1"
35
+ gemfile: gemfiles/Gemfile.activesupport-master
36
+ - rvm: "2.2"
37
+ gemfile: gemfiles/Gemfile.activesupport-master
38
+ - rvm: "2.3"
39
+ gemfile: gemfiles/Gemfile.activesupport-master
40
+ - rvm: "2.4"
41
+ gemfile: gemfiles/Gemfile.activesupport-master
data/CHANGELOG.md ADDED
@@ -0,0 +1,92 @@
1
+ # ActiveUtils changelog
2
+
3
+ ### Version 3.3.19 (February 24, 2020)
4
+ - Support `net/http` default proxy settings from `ENV['http_proxy']`
5
+ - Support usage of custom ssl certificate with `ENV['SSL_CERT_FILE']`, default variable for Ruby
6
+
7
+ ### Version 3.3.17 (February 24, 2020)
8
+ - Add support for PATCH HTTP method in `ActiveUtils#Connection`
9
+
10
+ ### Version 3.3.16 (December 18, 2018)
11
+ - Add `VU` to `ActiveUtils::Country::COUNTRIES_THAT_DO_NOT_USE_POSTALCODES`
12
+
13
+ ### Version 3.3.15 (November 29, 2018)
14
+ - Remove support to Ruby 1.9 and ActiveSupport `< 4`
15
+ - Remove the upperbound constraint on ActiveSupport
16
+
17
+ ### Version 3.3.14 (November 28, 2018)
18
+ - Add `MW` to `ActiveUtils::Country::COUNTRIES_THAT_DO_NOT_USE_POSTALCODES`
19
+
20
+ ### Version 3.3.13 (November 26, 2018)
21
+ - Add support for custom retriable exceptions in `NetworkConnectionRetries#retry_exceptions`
22
+
23
+ ### Version 3.3.12 (July 11, 2018)
24
+ - Update CA bundle
25
+
26
+ ### Version 3.3.11 (March 14, 2018)
27
+ - Add the DigiCert Global Root G2 to the CA bundle
28
+
29
+ ### Version 3.3.10 (February 28, 2018)
30
+ - Support ActiveSupport 5.2
31
+
32
+ ### Version 3.3.9 (September 28, 2017)
33
+ - Add remaining currencies to `ActiveUtils::CurrencyCode::ISO_CURRENCIES`
34
+ - Update bundler in `travis.yml`
35
+
36
+ ### Version 3.3.8 (August 15, 2017)
37
+ - Add `BO` to `ActiveUtils::Country::COUNTRIES_THAT_DO_NOT_USE_POSTALCODES`
38
+
39
+ ### Version 3.3.7 (June 26, 2017)
40
+ - Add `CVE` to `ActiveUtils::CurrencyCode::ISO_CURRENCIES`
41
+
42
+ ### Version 3.3.6 (May 23, 2017)
43
+ - Add `South Sudan` country in `ActiveUtils::Country::COUNTRIES_THAT_DO_NOT_USE_POSTALCODES`
44
+
45
+ ### Version 3.3.5 (May 18, 2017)
46
+ - Add `South Sudan` and `Antarctica` countries in `ActiveUtils::Country::COUNTRIES`
47
+
48
+ ### Version 3.3.4 (Apr. 18, 2017)
49
+ - Add `Ghana` country in `ActiveUtils::Country::COUNTRIES_THAT_DO_NOT_USE_POSTALCODES`
50
+
51
+ ### Version 3.3.3 (Apr. 7, 2017)
52
+ - Add the `Aland Islands` country in `ActiveUtils::Country::COUNTRIES`
53
+
54
+ ### Version 3.3.2 (Mar. 28, 2017)
55
+ - Changed country name of "Libyan Arab Jamahiriya" to Libya, as per country name change in 2011.
56
+
57
+ ### Version 3.3.1 (Mar. 28, 2017)
58
+ - Bump ActiveSupport requirement to **< 5.2.0**.
59
+
60
+ ### Version 3.3.0 (Mar. 10, 2017)
61
+ - Reduced default PostsData open_timeout from 60 seconds to 2, and read_timeout from 60 seconds to 10. Subclasses can and should override those values.
62
+ - Replace Kosovo's alpha 2 and alpha 3 ISO codes from `KV` to `XK` and from `KSV` to `XKX`.
63
+
64
+ ### Version 3.2.5 (Feb. 2, 2017)
65
+ - Add the `TMT` currency in the supported currency codes
66
+
67
+ ### Version 3.2.4 (Dec. 16, 2016)
68
+ - Add the `Bonaire` country in `ActiveUtils::Country::COUNTRIES`
69
+
70
+ ### Version 3.2.3 (Nov. 21, 2016)
71
+ - Add the `:delay` option in `ActiveUtils::NetworkConnectionRetries`
72
+
73
+ ### Version 3.2.2 (Jul. 4, 2016)
74
+ - Add tests for Rails 5 support
75
+
76
+ ### Version 3.2.1 (Oct. 26, 2015)
77
+ - Add the malaysian currency code "RM" in `ActiveUtils::CurrencyCode`
78
+
79
+ ### Version 3.2.0 (Oct. 13, 2015)
80
+ - Add #uses_postal_codes? to `ActiveUtils::Country`
81
+
82
+ ### Version 3.1.0 (Sept. 30, 2015)
83
+ - Use ActiveUtils::HTTPRequestError as base exception class
84
+ - Add proxy address and port configuration
85
+ - Add support for Sin Maarten
86
+
87
+ ### Version 3.0.0 (Jan. 16, 2015)
88
+
89
+ - Fully decoupled from ActiveMerchant: no longer uses `ActiveMerchant::` as namespace, but uses `ActiveUtils::` instead.
90
+ - Bump ActiveSupport requirement to **>= 3.2**.
91
+ - The `Utils` module to generate unique identifiers has been removed. Use `SecureRandom` instead.
92
+ - Improved test setup.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,32 @@
1
+ # Contributing to ActiveUtils
2
+
3
+ We gladly accept bugfixes to this library. Please read the guidelines for reporting issues and submitting pull requests below.
4
+
5
+ ### Reporting issues
6
+
7
+ - Include the version of ActiveUtils, Ruby, and ActiveSupport you are using.
8
+ - If you run into an unexpected exception, please include a stacktrace.
9
+ - Try to include a code snippet that demonstrates the problem.
10
+
11
+ ### Pull request guidelines
12
+
13
+ 1. [Fork it](http://github.com/Shopify/active_utils/fork) and clone your new repo
14
+ 2. Create a branch (`git checkout -b my_awesome_feature`)
15
+ 3. Commit your changes (`git add my/awesome/file.rb; git commit -m "Added my awesome feature"`)
16
+ 4. Push your changes to your fork (`git push origin my_awesome_feature`)
17
+ 5. Open a [Pull Request](https://github.com/shopify/active_utils/pulls)
18
+
19
+ The most important guidelines:
20
+
21
+ - All changes should be covered by tests.
22
+ - Your code should support all the Ruby versions and ActiveSupport versions we have enabled on Travis CI.
23
+ - Do not update the CHANGELOG, or the `ActiveUtils::VERSION` constant.
24
+
25
+ Final note: maybe you should also update the mirrored version in ActiveMerchant.
26
+
27
+ ### Releasing
28
+
29
+ 1. Check the [semantic versioning page](http://semver.org) for info on how to version the new release.
30
+ 2. Update the `ActiveUtils::VERSION` constant in **lib/active_utils/version.rb**.
31
+ 3. Add a `CHANGELOG.md` entry for the new release with the date.
32
+ 4. Release the gem to rubygems using ShipIt (this will create tag/push during deploy)
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/README.md CHANGED
@@ -1,16 +1,30 @@
1
- # Active Utils
2
-
3
- Active Utils extracts commonly used modules and classes used by [Active Merchant](http://github.com/Shopify/active_merchant), [Active Shipping](http://github.com/Shopify/active_shipping), and [Active Fulfillment](http://github.com/Shopify/active_fulfillment).
4
-
5
- ### Includes
6
-
7
- * Connection - base class for making HTTP requests
8
- * Country - find countries mapped by name, country codes, and numeric values
9
- * Error - common error classes used throughout the Active projects
10
- * PostData - helper class for managing required fields that are to be POST-ed
11
- * PostsData - making SSL HTTP requests
12
- * RequiresParameters - helper method to ensure the required parameters are passed in
13
- * Utils - common utils such as uid generator
14
- * Validateable - module used for making models validateable
15
- * NetworkConnectionRetries - module for retrying network connections when connection errors occur
16
- * CurrencyCode - ensure currency codes are ISO, and convert colloquial codes to ISO.
1
+ # ActiveUtils [![Build Status](https://travis-ci.org/Shopify/active_utils.svg?branch=master)](https://travis-ci.org/Shopify/active_utils)
2
+
3
+ ActiveUtils extracts commonly used modules and classes extracted from [Active Merchant](http://github.com/Shopify/active_merchant), to be used for other integration libraries.
4
+
5
+ ### Included modules and classes
6
+
7
+ * `Connection` - base class for making HTTP requests
8
+ * `Country` - find countries mapped by name, country codes, and numeric values
9
+ * `Error` - common error classes used throughout the Active projects
10
+ * `PostData` - helper class for managing required fields that are to be POST-ed
11
+ * `PostsData` - making SSL HTTP requests
12
+ * `RequiresParameters` - helper method to ensure the required parameters are passed in
13
+ * `Validateable` - module used for making models validateable
14
+ * `NetworkConnectionRetries` - module for retrying network connections when connection errors occur
15
+ * `CurrencyCode` - ensure currency codes are ISO, and convert colloquial codes to ISO.
16
+
17
+ ### Libraries that depend on ActiveUtils
18
+
19
+ - [ActiveShipping](https://github.com/Shopify/active_shipping)
20
+ - [ActiveFulfillment](https://github.com/Shopify/active_fulfillment)
21
+ - [OffsitePayments](https://github.com/Shopify/offsite_payments)
22
+
23
+ ### ActiveMerchant link
24
+
25
+ While most of the code in this library was extracted from ActiveMerchant, ActiveMerchant itself doesn't use this library anymore. For PCI compliance reasons, we aim to keep the number of dependencies of ActiveMerchant as low as possible. For this reason, many of these classes and modules are mirrored in ActiveMerchant (e.g. `ActiveUtils::Connection` vs. `ActiveMerchant::Connection`. When making changes to this library, you may want to mirror those changes in ActiveMerchant.
26
+
27
+ ### Misc
28
+
29
+ - This project is MIT licensed.
30
+ - Contributions are gladly accepted! See `CONTRIBUTING.md` for more information.
data/active_utils.gemspec CHANGED
@@ -14,12 +14,15 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.rubyforge_project = "active_utils"
16
16
 
17
- s.add_dependency('activesupport', '>= 2.3.11')
17
+ s.add_dependency('activesupport', '>= 4.2')
18
18
  s.add_dependency('i18n')
19
19
 
20
20
  s.add_development_dependency('rake')
21
+ s.add_development_dependency('minitest')
21
22
  s.add_development_dependency('mocha')
22
23
 
24
+ s.metadata['allowed_push_host'] = 'https://rubygems.org'
25
+
23
26
  s.files = `git ls-files`.split("\n")
24
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
28
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec path: '..'
3
+
4
+ gem 'activesupport', github: 'rails/rails'
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec path: '..'
3
+
4
+ gem 'activesupport', '~> 4.2.0'
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec path: '..'
3
+
4
+ gem 'activesupport', '~> 5.0.0'
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gemspec path: '..'
3
+
4
+ gem 'activesupport', github: 'rails/rails', branch: '5-2-stable'
@@ -3,7 +3,7 @@ require 'net/http'
3
3
  require 'net/https'
4
4
  require 'benchmark'
5
5
 
6
- module ActiveMerchant
6
+ module ActiveUtils
7
7
  class Connection
8
8
  include NetworkConnectionRetries
9
9
 
@@ -11,9 +11,12 @@ module ActiveMerchant
11
11
  OPEN_TIMEOUT = 60
12
12
  READ_TIMEOUT = 60
13
13
  VERIFY_PEER = true
14
- CA_FILE = (File.dirname(__FILE__) + '/../../certs/cacert.pem')
14
+ # allow using proxy for https calls by pointing to it's certificate
15
+ # SSL_CERT_FILE is variable used by Ruby to look for certificate for net/http
16
+ CA_FILE = ENV.fetch('SSL_CERT_FILE', File.dirname(__FILE__) + '/../certs/cacert.pem')
15
17
  CA_PATH = nil
16
18
  RETRY_SAFE = false
19
+ PROXY_ADDRESS = :ENV
17
20
  RUBY_184_POST_HEADERS = { "Content-Type" => "application/x-www-form-urlencoded" }
18
21
 
19
22
  attr_accessor :endpoint
@@ -45,7 +48,7 @@ module ActiveMerchant
45
48
  @max_retries = MAX_RETRIES
46
49
  @ignore_http_status = false
47
50
  @ssl_version = nil
48
- @proxy_address = nil
51
+ @proxy_address = PROXY_ADDRESS
49
52
  @proxy_port = nil
50
53
  end
51
54
 
@@ -69,6 +72,9 @@ module ActiveMerchant
69
72
  when :put
70
73
  debug body
71
74
  http.put(endpoint.request_uri, body, headers)
75
+ when :patch
76
+ debug body
77
+ http.patch(endpoint.request_uri, body, headers)
72
78
  when :delete
73
79
  # It's kind of ambiguous whether the RFC allows bodies
74
80
  # for DELETE requests. But Net::HTTP's delete method
@@ -1,7 +1,7 @@
1
1
  #!ruby19
2
2
  # encoding: utf-8
3
3
 
4
- module ActiveMerchant #:nodoc:
4
+ module ActiveUtils #:nodoc:
5
5
  class InvalidCountryCodeError < StandardError
6
6
  end
7
7
 
@@ -64,12 +64,14 @@ module ActiveMerchant #:nodoc:
64
64
 
65
65
  COUNTRIES = [
66
66
  { :alpha2 => 'AF', :name => 'Afghanistan', :alpha3 => 'AFG', :numeric => '004' },
67
+ { :alpha2 => 'AX', :name => 'Aland Islands', :alpha3 => 'ALA', :numeric => '248' },
67
68
  { :alpha2 => 'AL', :name => 'Albania', :alpha3 => 'ALB', :numeric => '008' },
68
69
  { :alpha2 => 'DZ', :name => 'Algeria', :alpha3 => 'DZA', :numeric => '012' },
69
70
  { :alpha2 => 'AS', :name => 'American Samoa', :alpha3 => 'ASM', :numeric => '016' },
70
71
  { :alpha2 => 'AD', :name => 'Andorra', :alpha3 => 'AND', :numeric => '020' },
71
72
  { :alpha2 => 'AO', :name => 'Angola', :alpha3 => 'AGO', :numeric => '024' },
72
73
  { :alpha2 => 'AI', :name => 'Anguilla', :alpha3 => 'AIA', :numeric => '660' },
74
+ { :alpha2 => 'AQ', :name => 'Antarctica', :alpha3 => 'ATA', :numeric => '010' },
73
75
  { :alpha2 => 'AG', :name => 'Antigua and Barbuda', :alpha3 => 'ATG', :numeric => '028' },
74
76
  { :alpha2 => 'AR', :name => 'Argentina', :alpha3 => 'ARG', :numeric => '032' },
75
77
  { :alpha2 => 'AM', :name => 'Armenia', :alpha3 => 'ARM', :numeric => '051' },
@@ -88,6 +90,7 @@ module ActiveMerchant #:nodoc:
88
90
  { :alpha2 => 'BM', :name => 'Bermuda', :alpha3 => 'BMU', :numeric => '060' },
89
91
  { :alpha2 => 'BT', :name => 'Bhutan', :alpha3 => 'BTN', :numeric => '064' },
90
92
  { :alpha2 => 'BO', :name => 'Bolivia', :alpha3 => 'BOL', :numeric => '068' },
93
+ { :alpha2 => 'BQ', :name => 'Bonaire, Sint Eustatius and Saba', :alpha3 => 'BES', :numeric => '535' },
91
94
  { :alpha2 => 'BA', :name => 'Bosnia and Herzegovina', :alpha3 => 'BIH', :numeric => '070' },
92
95
  { :alpha2 => 'BW', :name => 'Botswana', :alpha3 => 'BWA', :numeric => '072' },
93
96
  { :alpha2 => 'BV', :name => 'Bouvet Island', :alpha3 => 'BVD', :numeric => '074' },
@@ -179,7 +182,7 @@ module ActiveMerchant #:nodoc:
179
182
  { :alpha2 => 'KI', :name => 'Kiribati', :alpha3 => 'KIR', :numeric => '296' },
180
183
  { :alpha2 => 'KP', :name => 'Korea, Democratic People\'s Republic of', :alpha3 => 'PRK', :numeric => '408' },
181
184
  { :alpha2 => 'KR', :name => 'Korea, Republic of', :alpha3 => 'KOR', :numeric => '410' },
182
- { :alpha2 => 'KV', :name => 'Kosovo', :alpha3 => 'KSV', :numeric => '377' },
185
+ { :alpha2 => 'XK', :name => 'Kosovo', :alpha3 => 'XKX', :numeric => '377' },
183
186
  { :alpha2 => 'KW', :name => 'Kuwait', :alpha3 => 'KWT', :numeric => '414' },
184
187
  { :alpha2 => 'KG', :name => 'Kyrgyzstan', :alpha3 => 'KGZ', :numeric => '417' },
185
188
  { :alpha2 => 'LA', :name => 'Lao People\'s Democratic Republic', :alpha3 => 'LAO', :numeric => '418' },
@@ -187,7 +190,7 @@ module ActiveMerchant #:nodoc:
187
190
  { :alpha2 => 'LB', :name => 'Lebanon', :alpha3 => 'LBN', :numeric => '422' },
188
191
  { :alpha2 => 'LS', :name => 'Lesotho', :alpha3 => 'LSO', :numeric => '426' },
189
192
  { :alpha2 => 'LR', :name => 'Liberia', :alpha3 => 'LBR', :numeric => '430' },
190
- { :alpha2 => 'LY', :name => 'Libyan Arab Jamahiriya', :alpha3 => 'LBY', :numeric => '434' },
193
+ { :alpha2 => 'LY', :name => 'Libya', :alpha3 => 'LBY', :numeric => '434' },
191
194
  { :alpha2 => 'LI', :name => 'Liechtenstein', :alpha3 => 'LIE', :numeric => '438' },
192
195
  { :alpha2 => 'LT', :name => 'Lithuania', :alpha3 => 'LTU', :numeric => '440' },
193
196
  { :alpha2 => 'LU', :name => 'Luxembourg', :alpha3 => 'LUX', :numeric => '442' },
@@ -262,12 +265,14 @@ module ActiveMerchant #:nodoc:
262
265
  { :alpha2 => 'SC', :name => 'Seychelles', :alpha3 => 'SYC', :numeric => '690' },
263
266
  { :alpha2 => 'SL', :name => 'Sierra Leone', :alpha3 => 'SLE', :numeric => '694' },
264
267
  { :alpha2 => 'SG', :name => 'Singapore', :alpha3 => 'SGP', :numeric => '702' },
268
+ { :alpha2 => 'SX', :name => 'Sint Maarten (Netherlands Part)', :alpha3 => 'SXM', :numeric => '534' },
265
269
  { :alpha2 => 'SK', :name => 'Slovakia', :alpha3 => 'SVK', :numeric => '703' },
266
270
  { :alpha2 => 'SI', :name => 'Slovenia', :alpha3 => 'SVN', :numeric => '705' },
267
271
  { :alpha2 => 'SB', :name => 'Solomon Islands', :alpha3 => 'SLB', :numeric => '090' },
268
272
  { :alpha2 => 'SO', :name => 'Somalia', :alpha3 => 'SOM', :numeric => '706' },
269
273
  { :alpha2 => 'ZA', :name => 'South Africa', :alpha3 => 'ZAF', :numeric => '710' },
270
274
  { :alpha2 => 'GS', :name => 'South Georgia and the South Sandwich Islands', :alpha3 => 'SGS', :numeric => '239' },
275
+ { :alpha2 => 'SS', :name => 'South Sudan', :alpha3 => 'SSD', :numeric => '728' },
271
276
  { :alpha2 => 'ES', :name => 'Spain', :alpha3 => 'ESP', :numeric => '724' },
272
277
  { :alpha2 => 'LK', :name => 'Sri Lanka', :alpha3 => 'LKA', :numeric => '144' },
273
278
  { :alpha2 => 'SD', :name => 'Sudan', :alpha3 => 'SDN', :numeric => '736' },
@@ -312,6 +317,16 @@ module ActiveMerchant #:nodoc:
312
317
  { :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' }
313
318
  ]
314
319
 
320
+ COUNTRIES_THAT_DO_NOT_USE_POSTALCODES = %w(
321
+ QA BZ BS BF BJ AG AE AI AO AW HK
322
+ FJ ML MW JM ZW YE UG TV TT TG TD PA
323
+ CW GH SS BO VU DJ SL TO
324
+ )
325
+
326
+ def uses_postal_codes?
327
+ !COUNTRIES_THAT_DO_NOT_USE_POSTALCODES.include?(code(:alpha2).value)
328
+ end
329
+
315
330
  def self.find(name)
316
331
  raise InvalidCountryCodeError, "Cannot lookup country for an empty name" if name.blank?
317
332
 
@@ -0,0 +1,56 @@
1
+ module ActiveUtils
2
+ class InvalidCurrencyCodeError < StandardError
3
+ end
4
+
5
+ class CurrencyCode
6
+ ISO_CURRENCIES = [
7
+ "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN",
8
+ "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYR", "BYN", "BZD", "CAD",
9
+ "CDF", "CHE", "CHF", "CHW", "CLP", "CLF", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK",
10
+ "DKK", "DJF", "DOP", "DZD", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP",
11
+ "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IRR", "ISK",
12
+ "IQD", "JEP", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPY", "KRW", "KWD", "KYD", "KZT",
13
+ "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT",
14
+ "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR",
15
+ "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF",
16
+ "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP",
17
+ "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "USN",
18
+ "UYI", "UYU", "UZS", "VEF", "VND", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD",
19
+ "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", "YER", "ZAR", "ZMW", "ZWL"
20
+ ]
21
+
22
+ NON_ISO_TO_ISO = {
23
+ "ARN" => "ARS", # Argentinian Pesos
24
+ "AZM" => "AZN", # Azerbaijan New Manat
25
+ "CHP" => "CLP", # Chilean Pesos
26
+ "DHS" => "AED", # UAE Dirhams
27
+ "ECD" => "XCD", # East Caribbean Dollars
28
+ "GHC" => "GHS", # Ghana Cedi
29
+ "JAD" => "JMD", # Jamaican Dollars
30
+ "JYE" => "JPY", # Japanese Yen
31
+ "KUD" => "KWD", # Kuwaiti Dinars
32
+ "MZM" => "MZN", # Mozambique Metical
33
+ "NMP" => "MXN", # Mexican Pesos
34
+ "NTD" => "TWD", # New Taiwan Dollars / Taiwan New Dollars
35
+ "RDD" => "DOP", # Dominican Pesos
36
+ "RM" => "MYR", # Malaysia Ringgit
37
+ "RMB" => "CNY", # Chinese Renminbi
38
+ "SFR" => "CHF", # Swiss Francs
39
+ "SID" => "SGD", # Singapore Dollars
40
+ "SOL" => "PES", # Peruvian Sol
41
+ "UKL" => "GBP", # Great Britain Pounds
42
+ "WON" => "KRW" # South Korean Won
43
+ }
44
+
45
+ def self.standardize(code)
46
+ code = code.upcase unless code.nil?
47
+
48
+ return code if is_iso?(code)
49
+ NON_ISO_TO_ISO[code] || raise(InvalidCurrencyCodeError, "#{code} is not an ISO currency, nor can it be converted to one.")
50
+ end
51
+
52
+ def self.is_iso?(code)
53
+ ISO_CURRENCIES.include? code
54
+ end
55
+ end
56
+ end
@@ -1,14 +1,16 @@
1
- module ActiveMerchant #:nodoc:
2
- class ActiveMerchantError < StandardError #:nodoc:
1
+ module ActiveUtils #:nodoc:
2
+ class HTTPRequestError < StandardError #:nodoc:
3
3
  end
4
4
 
5
- class ConnectionError < ActiveMerchantError # :nodoc:
5
+ ActiveUtilsError = HTTPRequestError #:nodoc:
6
+
7
+ class ConnectionError < HTTPRequestError # :nodoc:
6
8
  end
7
9
 
8
10
  class RetriableConnectionError < ConnectionError # :nodoc:
9
11
  end
10
12
 
11
- class ResponseError < ActiveMerchantError # :nodoc:
13
+ class ResponseError < HTTPRequestError # :nodoc:
12
14
  attr_reader :response
13
15
 
14
16
  def initialize(response, message = nil)
@@ -21,9 +23,9 @@ module ActiveMerchant #:nodoc:
21
23
  end
22
24
  end
23
25
 
24
- class ClientCertificateError < ActiveMerchantError # :nodoc
26
+ class ClientCertificateError < HTTPRequestError # :nodoc
25
27
  end
26
28
 
27
- class InvalidResponseError < ActiveMerchantError # :nodoc
29
+ class InvalidResponseError < HTTPRequestError # :nodoc
28
30
  end
29
31
  end
@@ -1,4 +1,4 @@
1
- module ActiveMerchant
1
+ module ActiveUtils
2
2
  module NetworkConnectionRetries
3
3
  DEFAULT_RETRIES = 3
4
4
  DEFAULT_CONNECTION_ERRORS = {
@@ -10,25 +10,30 @@ module ActiveMerchant
10
10
  OpenSSL::SSL::SSLError => "The SSL connection to the remote server could not be established"
11
11
  }
12
12
 
13
+ DEFAULT_RETRY_ERRORS = {
14
+ Errno::ECONNREFUSED => "The remote server refused the connection"
15
+ }
16
+
13
17
  def self.included(base)
14
18
  base.send(:attr_accessor, :retry_safe)
15
19
  end
16
20
 
17
21
  def retry_exceptions(options={})
18
22
  connection_errors = DEFAULT_CONNECTION_ERRORS.merge(options[:connection_exceptions] || {})
23
+ retry_errors = DEFAULT_RETRY_ERRORS.merge(options[:retriable_exceptions] || {})
19
24
 
20
25
  retry_network_exceptions(options) do
21
26
  begin
22
27
  yield
23
- rescue Errno::ECONNREFUSED => e
24
- raise ActiveMerchant::RetriableConnectionError, "The remote server refused the connection"
28
+ rescue *retry_errors.keys => e
29
+ raise ActiveUtils::RetriableConnectionError, derived_error_message(retry_errors, e.class)
25
30
  rescue OpenSSL::X509::CertificateError => e
26
31
  NetworkConnectionRetries.log(options[:logger], :error, e.message, options[:tag])
27
- raise ActiveMerchant::ClientCertificateError, "The remote server did not accept the provided SSL certificate"
32
+ raise ActiveUtils::ClientCertificateError, "The remote server did not accept the provided SSL certificate"
28
33
  rescue Zlib::BufError => e
29
- raise ActiveMerchant::InvalidResponseError, "The remote server replied with an invalid response"
34
+ raise ActiveUtils::InvalidResponseError, "The remote server replied with an invalid response"
30
35
  rescue *connection_errors.keys => e
31
- raise ActiveMerchant::ConnectionError, connection_errors[e.class]
36
+ raise ActiveUtils::ConnectionError, derived_error_message(connection_errors, e.class)
32
37
  end
33
38
  end
34
39
  end
@@ -45,16 +50,22 @@ module ActiveMerchant
45
50
  result = yield
46
51
  log_with_retry_details(options[:logger], initial_retries-retries + 1, Time.now.to_f - request_start, "success", options[:tag])
47
52
  result
48
- rescue ActiveMerchant::RetriableConnectionError => e
53
+ rescue ActiveUtils::RetriableConnectionError => e
49
54
  retries -= 1
50
55
 
51
56
  log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
52
- retry unless retries.zero?
53
- raise ActiveMerchant::ConnectionError, e.message
54
- rescue ActiveMerchant::ConnectionError, ActiveMerchant::InvalidResponseError => e
57
+ unless retries.zero?
58
+ Kernel.sleep(options[:delay]) if options[:delay]
59
+ retry
60
+ end
61
+ raise ActiveUtils::ConnectionError, e.message
62
+ rescue ActiveUtils::ConnectionError, ActiveUtils::InvalidResponseError => e
55
63
  retries -= 1
56
64
  log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
57
- retry if (options[:retry_safe] || retry_safe) && !retries.zero?
65
+ if (options[:retry_safe] || retry_safe) && !retries.zero?
66
+ Kernel.sleep(options[:delay]) if options[:delay]
67
+ retry
68
+ end
58
69
  raise
59
70
  end
60
71
  end
@@ -69,5 +80,10 @@ module ActiveMerchant
69
80
  def log_with_retry_details(logger, attempts, time, message, tag)
70
81
  NetworkConnectionRetries.log(logger, :info, "connection_attempt=%d connection_request_time=%.4fs connection_msg=\"%s\"" % [attempts, time, message], tag)
71
82
  end
83
+
84
+ def derived_error_message(errors, klass)
85
+ key = (errors.keys & klass.ancestors).first
86
+ key ? errors[key] : nil
87
+ end
72
88
  end
73
89
  end
@@ -1,6 +1,6 @@
1
1
  require 'cgi'
2
2
 
3
- module ActiveMerchant
3
+ module ActiveUtils
4
4
  class PostData < Hash
5
5
  class_attribute :required_fields, :instance_writer => false
6
6
  self.required_fields = []
@@ -1,27 +1,32 @@
1
- module ActiveMerchant #:nodoc:
1
+ module ActiveUtils #:nodoc:
2
2
  module PostsData #:nodoc:
3
3
 
4
4
  def self.included(base)
5
- base.superclass_delegating_accessor :ssl_strict
5
+ base.class_attribute :ssl_strict
6
6
  base.ssl_strict = true
7
7
 
8
- base.superclass_delegating_accessor :ssl_version
8
+ base.class_attribute :ssl_version
9
9
  base.ssl_version = nil
10
10
 
11
11
  base.class_attribute :retry_safe
12
12
  base.retry_safe = false
13
13
 
14
- base.superclass_delegating_accessor :open_timeout
15
- base.open_timeout = 60
14
+ base.class_attribute :open_timeout
15
+ base.open_timeout = 2
16
16
 
17
- base.superclass_delegating_accessor :read_timeout
18
- base.read_timeout = 60
17
+ base.class_attribute :read_timeout
18
+ base.read_timeout = 10
19
19
 
20
- base.superclass_delegating_accessor :max_retries
20
+ base.class_attribute :max_retries
21
21
  base.max_retries = Connection::MAX_RETRIES
22
22
 
23
- base.superclass_delegating_accessor :logger
24
- base.superclass_delegating_accessor :wiredump_device
23
+ base.class_attribute :logger
24
+ base.class_attribute :wiredump_device
25
+
26
+ base.class_attribute :proxy_address
27
+ base.proxy_address = Connection::PROXY_ADDRESS
28
+
29
+ base.class_attribute :proxy_port
25
30
  end
26
31
 
27
32
  def ssl_get(endpoint, headers={})
@@ -38,6 +43,7 @@ module ActiveMerchant #:nodoc:
38
43
 
39
44
  def raw_ssl_request(method, endpoint, data, headers = {})
40
45
  logger.warn "#{self.class} using ssl_strict=false, which is insecure" if logger unless ssl_strict
46
+ logger.warn "#{self.class} posting to plaintext endpoint, which is insecure" if logger unless endpoint =~ /^https:/
41
47
 
42
48
  connection = new_connection(endpoint)
43
49
  connection.open_timeout = open_timeout
@@ -55,6 +61,9 @@ module ActiveMerchant #:nodoc:
55
61
 
56
62
  connection.ignore_http_status = @options[:ignore_http_status] if @options
57
63
 
64
+ connection.proxy_address = proxy_address
65
+ connection.proxy_port = proxy_port
66
+
58
67
  connection.request(method, data, headers)
59
68
  end
60
69