instrumental_agent 0.13.1 → 0.13.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d22dc8e7673c5701cf1cdc654ebd8b953eff28c7
4
- data.tar.gz: 53fa9eb53ace63abe3a243b3ce8397bf3d53f01f
3
+ metadata.gz: 6cde80ee21af0e7064fda51df68d72943ccb8879
4
+ data.tar.gz: 441003be93bf1ec0ec287f431726e5bf789b9266
5
5
  SHA512:
6
- metadata.gz: bc8ec3269967f078690443c315c0dfe1d450603855b2f9cb31a01f3625cb00642cb1e5975cfdc7b3ee25c04c9f4b5249f4c1d5b1aa8fc7e0fed5086fb5f9fc49
7
- data.tar.gz: 3c846c8a723c0c5e9b5c1998a78d330caad7a7b67e663ebb8a5abd21e8866348af0538ef14149b7bd897190930703e9e2c990cb5168caa9fa929941354f762ea
6
+ metadata.gz: 8ba42e1733a75ed3d1c879c7116d04e1cdfb0f042375b14601b7f32b5800eb2bcf2c6f7f8e60bd41729a627be0e8e5076593569042666f9b817d1425995c1342
7
+ data.tar.gz: f838d3a4dc8a9ab272350300776c3473ff586a072e71673f0db66d7de0364f1e85860cd99a64f0e76b3d461b27574816655e04ee8311cbcc76817078f7ecd034
data/.travis.yml CHANGED
@@ -1,3 +1,4 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
4
  - 1.8.7
@@ -6,5 +7,3 @@ rvm:
6
7
  - 2.0.0
7
8
  - jruby-18mode
8
9
  - jruby-19mode
9
- - rbx-18mode
10
- - rbx-19mode
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ### 0.13.2 [August 17, 2015]
2
+ * DNS resolution fixes to prevent fork'd child deadlocks
3
+
1
4
  ### 0.13.1 [August 3, 2015]
2
5
  * Revert encrypted support
3
6
 
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
-
5
- if RUBY_VERSION < "1.9"
4
+ ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
5
+ if RUBY_VERSION < "1.9" && !%w{jruby rbx}.include?(ruby_engine)
6
6
  # Built and installed via ext/mkrf_conf.rb
7
7
  gem 'system_timer', '~> 1.2'
8
8
  end
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require 'bundler/setup'
1
2
  require 'bundler/gem_tasks'
2
3
  require 'rspec/core/rake_task'
3
4
 
@@ -0,0 +1,69 @@
1
+ Certificate:
2
+ Data:
3
+ Version: 3 (0x2)
4
+ Serial Number: 903804111 (0x35def4cf)
5
+ Signature Algorithm: sha1WithRSAEncryption
6
+ Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
7
+ Validity
8
+ Not Before: Aug 22 16:41:51 1998 GMT
9
+ Not After : Aug 22 16:41:51 2018 GMT
10
+ Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
11
+ Subject Public Key Info:
12
+ Public Key Algorithm: rsaEncryption
13
+ RSA Public Key: (1024 bit)
14
+ Modulus (1024 bit):
15
+ 00:c1:5d:b1:58:67:08:62:ee:a0:9a:2d:1f:08:6d:
16
+ 91:14:68:98:0a:1e:fe:da:04:6f:13:84:62:21:c3:
17
+ d1:7c:ce:9f:05:e0:b8:01:f0:4e:34:ec:e2:8a:95:
18
+ 04:64:ac:f1:6b:53:5f:05:b3:cb:67:80:bf:42:02:
19
+ 8e:fe:dd:01:09:ec:e1:00:14:4f:fc:fb:f0:0c:dd:
20
+ 43:ba:5b:2b:e1:1f:80:70:99:15:57:93:16:f1:0f:
21
+ 97:6a:b7:c2:68:23:1c:cc:4d:59:30:ac:51:1e:3b:
22
+ af:2b:d6:ee:63:45:7b:c5:d9:5f:50:d2:e3:50:0f:
23
+ 3a:88:e7:bf:14:fd:e0:c7:b9
24
+ Exponent: 65537 (0x10001)
25
+ X509v3 extensions:
26
+ X509v3 CRL Distribution Points:
27
+ DirName:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority/CN=CRL1
28
+
29
+ X509v3 Private Key Usage Period:
30
+ Not After: Aug 22 16:41:51 2018 GMT
31
+ X509v3 Key Usage:
32
+ Certificate Sign, CRL Sign
33
+ X509v3 Authority Key Identifier:
34
+ keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
35
+
36
+ X509v3 Subject Key Identifier:
37
+ 48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
38
+ X509v3 Basic Constraints:
39
+ CA:TRUE
40
+ 1.2.840.113533.7.65.0:
41
+ 0...V3.0c....
42
+ Signature Algorithm: sha1WithRSAEncryption
43
+ 58:ce:29:ea:fc:f7:de:b5:ce:02:b9:17:b5:85:d1:b9:e3:e0:
44
+ 95:cc:25:31:0d:00:a6:92:6e:7f:b6:92:63:9e:50:95:d1:9a:
45
+ 6f:e4:11:de:63:85:6e:98:ee:a8:ff:5a:c8:d3:55:b2:66:71:
46
+ 57:de:c0:21:eb:3d:2a:a7:23:49:01:04:86:42:7b:fc:ee:7f:
47
+ a2:16:52:b5:67:67:d3:40:db:3b:26:58:b2:28:77:3d:ae:14:
48
+ 77:61:d6:fa:2a:66:27:a0:0d:fa:a7:73:5c:ea:70:f1:94:21:
49
+ 65:44:5f:fa:fc:ef:29:68:a9:a2:87:79:ef:79:ef:4f:ac:07:
50
+ 77:38
51
+ -----BEGIN CERTIFICATE-----
52
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
53
+ UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
54
+ dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
55
+ MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
56
+ dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
57
+ AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
58
+ BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
59
+ cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
60
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
61
+ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
62
+ aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
63
+ ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
64
+ IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
65
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
66
+ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
67
+ 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
68
+ 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
69
+ -----END CERTIFICATE-----
@@ -0,0 +1,80 @@
1
+ Certificate:
2
+ Data:
3
+ Version: 3 (0x2)
4
+ Serial Number: 1227750 (0x12bbe6)
5
+ Signature Algorithm: sha1WithRSAEncryption
6
+ Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
7
+ Validity
8
+ Not Before: May 21 04:00:00 2002 GMT
9
+ Not After : Aug 21 04:00:00 2018 GMT
10
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
11
+ Subject Public Key Info:
12
+ Public Key Algorithm: rsaEncryption
13
+ RSA Public Key: (2048 bit)
14
+ Modulus (2048 bit):
15
+ 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df:
16
+ 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8:
17
+ 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29:
18
+ bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4:
19
+ 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3:
20
+ ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92:
21
+ 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d:
22
+ 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14:
23
+ 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd:
24
+ d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6:
25
+ d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5:
26
+ 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39:
27
+ 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05:
28
+ 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2:
29
+ fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32:
30
+ eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07:
31
+ 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b:
32
+ e4:f9
33
+ Exponent: 65537 (0x10001)
34
+ X509v3 extensions:
35
+ X509v3 Authority Key Identifier:
36
+ keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
37
+
38
+ X509v3 Subject Key Identifier:
39
+ C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
40
+ X509v3 Basic Constraints: critical
41
+ CA:TRUE
42
+ X509v3 Key Usage: critical
43
+ Certificate Sign, CRL Sign
44
+ X509v3 CRL Distribution Points:
45
+ URI:http://crl.geotrust.com/crls/secureca.crl
46
+
47
+ X509v3 Certificate Policies:
48
+ Policy: X509v3 Any Policy
49
+ CPS: https://www.geotrust.com/resources/repository
50
+
51
+ Signature Algorithm: sha1WithRSAEncryption
52
+ 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7:
53
+ c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38:
54
+ b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3:
55
+ 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38:
56
+ ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef:
57
+ 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb:
58
+ 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84:
59
+ 3f:12
60
+ -----BEGIN CERTIFICATE-----
61
+ MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
62
+ MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
63
+ aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
64
+ WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
65
+ AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
66
+ CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
67
+ OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
68
+ T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
69
+ JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
70
+ Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
71
+ PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
72
+ aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
73
+ TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
74
+ LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
75
+ BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
76
+ dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
77
+ AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
78
+ NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
79
+ b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
80
+ -----END CERTIFICATE-----
@@ -0,0 +1,94 @@
1
+ Certificate:
2
+ Data:
3
+ Version: 3 (0x2)
4
+ Serial Number: 146039 (0x23a77)
5
+ Signature Algorithm: sha256WithRSAEncryption
6
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
7
+ Validity
8
+ Not Before: Aug 29 21:39:32 2014 GMT
9
+ Not After : May 20 21:39:32 2022 GMT
10
+ Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G3
11
+ Subject Public Key Info:
12
+ Public Key Algorithm: rsaEncryption
13
+ RSA Public Key: (2048 bit)
14
+ Modulus (2048 bit):
15
+ 00:af:54:9b:d9:58:5d:1e:2c:56:c6:d5:e8:7f:f4:
16
+ 7d:16:03:ff:d0:8b:5a:e4:8e:a7:dd:54:2e:d4:04:
17
+ c0:5d:98:9c:8d:90:0f:bc:10:65:5f:da:9a:d6:44:
18
+ 7c:c0:9f:b5:e9:4a:8c:0b:06:43:04:bb:f4:96:e2:
19
+ 26:f6:61:01:91:66:31:22:c3:34:34:5f:3f:3f:91:
20
+ 2f:44:5f:dc:c7:14:b6:03:9f:86:4b:0e:a3:ff:a0:
21
+ 80:02:83:c3:d3:1f:69:52:d6:9d:64:0f:c9:83:e7:
22
+ 1b:c4:70:ac:94:e7:c3:a4:6a:2c:bd:b8:9e:69:d8:
23
+ be:0a:8f:16:63:5a:68:71:80:7b:30:de:15:04:bf:
24
+ cc:d3:bf:3e:48:05:55:7a:b3:d7:10:0c:03:fc:9b:
25
+ fd:08:a7:8c:8c:db:a7:8e:f1:1e:63:dc:b3:01:2f:
26
+ 7f:af:57:c3:3c:48:a7:83:68:21:a7:2f:e7:a7:3f:
27
+ f0:b5:0c:fc:f5:84:d1:53:bc:0e:72:4f:60:0c:42:
28
+ b8:98:ad:19:88:57:d7:04:ec:87:bf:7e:87:4e:a3:
29
+ 21:f9:53:fd:36:98:48:8d:d6:f8:bb:48:f2:29:c8:
30
+ 64:d1:cc:54:48:53:8b:af:b7:65:1e:bf:29:33:29:
31
+ d9:29:60:48:f8:ff:91:bc:57:58:e5:35:2e:bb:69:
32
+ b6:59
33
+ Exponent: 65537 (0x10001)
34
+ X509v3 extensions:
35
+ X509v3 Authority Key Identifier:
36
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
37
+
38
+ X509v3 Subject Key Identifier:
39
+ C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
40
+ X509v3 Basic Constraints: critical
41
+ CA:TRUE, pathlen:0
42
+ X509v3 Key Usage: critical
43
+ Certificate Sign, CRL Sign
44
+ X509v3 CRL Distribution Points:
45
+ URI:http://g.symcb.com/crls/gtglobal.crl
46
+
47
+ Authority Information Access:
48
+ OCSP - URI:http://g.symcd.com
49
+
50
+ X509v3 Certificate Policies:
51
+ Policy: 2.16.840.1.113733.1.7.54
52
+ CPS: http://www.geotrust.com/resources/cps
53
+
54
+ Signature Algorithm: sha256WithRSAEncryption
55
+ a3:58:1e:c6:43:32:ac:ac:2f:93:78:b7:ea:ae:54:40:47:2d:
56
+ 7e:78:8d:50:f6:f8:66:ac:d6:4f:73:d6:44:ef:af:0b:cc:5b:
57
+ c1:f4:4f:9a:8f:49:7e:60:af:c2:27:c7:16:f1:fb:93:81:90:
58
+ a9:7c:ef:6f:7e:6e:45:94:16:84:bd:ec:49:f1:c4:0e:f4:af:
59
+ 04:59:83:87:0f:2c:3b:97:c3:5a:12:9b:7b:04:35:7b:a3:95:
60
+ 33:08:7b:93:71:22:42:b3:a9:d9:6f:4f:81:92:fc:07:b6:79:
61
+ bc:84:4a:9d:77:09:f1:c5:89:f2:f0:b4:9c:54:aa:12:7b:0d:
62
+ ba:4f:ef:93:19:ec:ef:7d:4e:61:a3:8e:76:9c:59:cf:8c:94:
63
+ b1:84:97:f7:1a:b9:07:b8:b2:c6:4f:13:79:db:bf:4f:51:1b:
64
+ 7f:69:0d:51:2a:c1:d6:15:ff:37:51:34:65:51:f4:1e:be:38:
65
+ 6a:ec:0e:ab:bf:3d:7b:39:05:7b:f4:f3:fb:1a:a1:d0:c8:7e:
66
+ 4e:64:8d:cd:8c:61:55:90:fe:3a:ca:5d:25:0f:f8:1d:a3:4a:
67
+ 74:56:4f:1a:55:40:70:75:25:a6:33:2e:ba:4b:a5:5d:53:9a:
68
+ 0d:30:e1:8d:5f:61:2c:af:cc:ef:b0:99:a1:80:ff:0b:f2:62:
69
+ 4c:70:26:98
70
+ -----BEGIN CERTIFICATE-----
71
+ MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
72
+ MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
73
+ YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
74
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
75
+ U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
76
+ VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
77
+ SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
78
+ 1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
79
+ DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
80
+ QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
81
+ YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
82
+ qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
83
+ VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
84
+ JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
85
+ BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
86
+ MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
87
+ dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
88
+ rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
89
+ fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
90
+ kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
91
+ uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
92
+ ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
93
+ gP8L8mJMcCaY
94
+ -----END CERTIFICATE-----
@@ -19,10 +19,4 @@ Gem::Specification.new do |s|
19
19
  s.add_development_dependency(%q<rake>, [">= 0"])
20
20
  s.add_development_dependency(%q<rspec>, ["~> 2.0"])
21
21
  s.add_development_dependency(%q<fuubar>, [">= 0"])
22
- if RUBY_VERSION >= "1.9.2"
23
- s.add_development_dependency(%q<guard>, [">= 0"])
24
- s.add_development_dependency(%q<guard-rspec>, [">= 0"])
25
- s.add_development_dependency(%q<growl>, [">= 0"])
26
- s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
27
- end
28
22
  end
@@ -1,22 +1,28 @@
1
1
  require 'instrumental/version'
2
2
  require 'instrumental/system_timer'
3
3
  require 'logger'
4
+ require 'openssl' rescue nil
5
+ require 'resolv'
4
6
  require 'thread'
5
7
  require 'socket'
6
8
 
7
9
 
8
10
  module Instrumental
9
11
  class Agent
10
- BACKOFF = 2.0
11
- MAX_RECONNECT_DELAY = 15
12
- MAX_BUFFER = 5000
13
- REPLY_TIMEOUT = 10
14
- CONNECT_TIMEOUT = 20
15
- EXIT_FLUSH_TIMEOUT = 5
16
- HOSTNAME = Socket.gethostbyname(Socket.gethostname).first rescue Socket.gethostname
12
+ BACKOFF = 2.0
13
+ CONNECT_TIMEOUT = 20
14
+ EXIT_FLUSH_TIMEOUT = 5
15
+ HOSTNAME = Socket.gethostbyname(Socket.gethostname).first rescue Socket.gethostname
16
+ MAX_BUFFER = 5000
17
+ MAX_RECONNECT_DELAY = 15
18
+ REPLY_TIMEOUT = 10
19
+ RESOLUTION_FAILURES_BEFORE_WAITING = 3
20
+ RESOLUTION_WAIT = 30
21
+ RESOLVE_TIMEOUT = 1
17
22
 
18
- attr_accessor :host, :port, :synchronous, :queue
19
- attr_reader :connection, :enabled
23
+
24
+ attr_accessor :host, :port, :synchronous, :queue, :dns_resolutions, :last_connect_at
25
+ attr_reader :connection, :enabled, :secure
20
26
 
21
27
  def self.logger=(l)
22
28
  @logger = l
@@ -42,17 +48,35 @@ module Instrumental
42
48
 
43
49
  # defaults
44
50
  # host: collector.instrumentalapp.com
45
- # port: 8000
51
+ # port: 8001
46
52
  # enabled: true
47
53
  # synchronous: false
54
+ # secure: true
55
+ # verify: true
48
56
  @api_key = api_key
49
57
  @host, @port = options[:collector].to_s.split(':')
50
58
  @host ||= 'collector.instrumentalapp.com'
51
- @port = (@port || 8000).to_i
59
+ requested_secure = options[:secure] == true
60
+ desired_secure = options[:secure].nil? ? allows_secure? : !!options[:secure]
61
+ if !allows_secure? && desired_secure
62
+ logger.warn "Cannot connect to Instrumental via encrypted transport, SSL not available"
63
+ if requested_secure
64
+ options[:enabled] = false
65
+ logger.error "You requested secure protocol to connect to Instrumental, but it is not available on this system (OpenSSL is not defined). Connecting to Instrumental has been disabled."
66
+ end
67
+ desired_secure = false
68
+ end
69
+ @secure = desired_secure
70
+ @verify_cert = options[:verify_cert].nil? ? true : !!options[:verify_cert]
71
+ default_port = @secure ? 8001 : 8000
72
+ @port = (@port || default_port).to_i
52
73
  @enabled = options.has_key?(:enabled) ? !!options[:enabled] : true
53
74
  @synchronous = !!options[:synchronous]
54
75
  @pid = Process.pid
55
76
  @allow_reconnect = true
77
+ @certs = certificates
78
+ @dns_resolutions = 0
79
+ @last_connect_at = 0
56
80
 
57
81
  setup_cleanup_at_exit if @enabled
58
82
  end
@@ -179,6 +203,9 @@ module Instrumental
179
203
  @thread.kill
180
204
  @thread = nil
181
205
  end
206
+ if @queue
207
+ @queue.clear
208
+ end
182
209
  end
183
210
 
184
211
  # Called when a process is exiting to give it some extra time to
@@ -239,22 +266,29 @@ module Instrumental
239
266
  logger.error "Exception occurred: #{e.message}\n#{e.backtrace.join("\n")}"
240
267
  end
241
268
 
242
- def ipv4_address_for_host(host, port)
243
- addresses = Socket.getaddrinfo(host, port, 'AF_INET')
244
- if (result = addresses.first)
245
- _, _, _, address, _ = result
246
- address
247
- else
248
- raise Exception.new("Couldn't get address information for host #{host}")
269
+ def ipv4_address_for_host(host, port, moment_to_connect = Time.now.to_i)
270
+ self.dns_resolutions = dns_resolutions + 1
271
+ time_since_last_connect = moment_to_connect - last_connect_at
272
+ if dns_resolutions < RESOLUTION_FAILURES_BEFORE_WAITING || time_since_last_connect >= RESOLUTION_WAIT
273
+ self.last_connect_at = moment_to_connect
274
+ with_timeout(RESOLVE_TIMEOUT) do
275
+ address = Resolv.getaddresses(host).select { |address| address =~ Resolv::IPv4::Regex }.first
276
+ self.dns_resolutions = 0
277
+ address
278
+ end
249
279
  end
280
+ rescue Exception => e
281
+ logger.warn "Couldn't resolve address for #{host}:#{port}"
282
+ report_exception(e)
283
+ nil
250
284
  end
251
285
 
252
286
  def send_command(cmd, *args)
253
287
  cmd = "%s %s\n" % [cmd, args.collect { |a| a.to_s }.join(" ")]
254
288
  if enabled?
255
- start_connection_worker if !running?
256
289
 
257
- if @queue.size < MAX_BUFFER
290
+ start_connection_worker if !running?
291
+ if @queue && @queue.size < MAX_BUFFER
258
292
  @queue_full_warning = false
259
293
  logger.debug "Queueing: #{cmd.chomp}"
260
294
  queue_message(cmd, { :synchronous => @synchronous })
@@ -291,10 +325,41 @@ module Instrumental
291
325
  message
292
326
  end
293
327
 
328
+ def wait_exceptions
329
+ classes = [Errno::EAGAIN]
330
+ if defined?(IO::EAGAINWaitReadable)
331
+ classes << IO::EAGAINWaitReadable
332
+ end
333
+ if defined?(IO::EWOULDBLOCKWaitReadable)
334
+ classes << IO::EWOULDBLOCKWaitReadable
335
+ end
336
+ if defined?(IO::WaitReadable)
337
+ classes << IO::WaitReadable
338
+ end
339
+ classes
340
+ end
341
+
342
+
294
343
  def test_connection
295
344
  begin
296
- @socket.read_nonblock(1)
297
- rescue Errno::EAGAIN
345
+ # In the case where the socket is an OpenSSL::SSL::SSLSocket,
346
+ # on Ruby 1.8.6, 1.8.7 or 1.9.1, read_nonblock does not exist,
347
+ # and so the case of testing socket liveliness via a nonblocking
348
+ # read that catches a wait condition won't work.
349
+ #
350
+ # We grab the SSL socket's underlying IO object and perform the
351
+ # non blocking read there in order to ensure the socket is still
352
+ # valid
353
+ if @socket.respond_to?(:read_nonblock)
354
+ @socket.read_nonblock(1)
355
+ elsif @socket.respond_to?(:io)
356
+ # The SSL Socket may send down additional data at close time,
357
+ # so we perform two nonblocking reads, one to pull any pending
358
+ # data on the socket, and the second to actually perform the connection
359
+ # liveliness test
360
+ @socket.io.read_nonblock(1024) && @socket.io.read_nonblock(1024)
361
+ end
362
+ rescue *wait_exceptions
298
363
  # noop
299
364
  end
300
365
  end
@@ -302,13 +367,17 @@ module Instrumental
302
367
  def start_connection_worker
303
368
  if enabled?
304
369
  disconnect
305
- @pid = Process.pid
306
- @queue = Queue.new
307
- @sync_mutex = Mutex.new
308
- @failures = 0
309
- logger.info "Starting thread"
310
- @thread = Thread.new do
311
- run_worker_loop
370
+ @queue ||= Queue.new
371
+ address = ipv4_address_for_host(@host, @port)
372
+ if address
373
+ @pid = Process.pid
374
+ @sync_mutex = Mutex.new
375
+ @failures = 0
376
+ @sockaddr_in = Socket.pack_sockaddr_in(@port, address)
377
+ logger.info "Starting thread"
378
+ @thread = Thread.new do
379
+ run_worker_loop
380
+ end
312
381
  end
313
382
  end
314
383
  end
@@ -323,15 +392,30 @@ module Instrumental
323
392
  end
324
393
  end
325
394
 
326
-
395
+ def open_socket(sockaddr_in, secure, verify_cert)
396
+ sock = Socket.new(Socket::PF_INET, Socket::SOCK_STREAM, 0)
397
+ sock.connect(sockaddr_in)
398
+ if secure
399
+ context = OpenSSL::SSL::SSLContext.new
400
+ if verify_cert
401
+ context.set_params(:verify_mode => OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
402
+ else
403
+ context.set_params(:verify_mode => OpenSSL::SSL::VERIFY_NONE)
404
+ end
405
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(sock, context)
406
+ ssl_socket.sync_close = true
407
+ ssl_socket.connect
408
+ sock = ssl_socket
409
+ end
410
+ sock
411
+ end
327
412
 
328
413
  def run_worker_loop
329
414
  command_and_args = nil
330
415
  command_options = nil
331
416
  logger.info "connecting to collector"
332
- @socket = Socket.new(Socket::PF_INET, Socket::SOCK_STREAM, 0)
333
417
  with_timeout(CONNECT_TIMEOUT) do
334
- @socket.connect Socket.pack_sockaddr_in(port, ipv4_address_for_host(host, port))
418
+ @socket = open_socket(@sockaddr_in, @secure, @verify_cert)
335
419
  end
336
420
  logger.info "connected to collector at #{host}:#{port}"
337
421
  hello_options = {
@@ -347,37 +431,46 @@ module Instrumental
347
431
  @failures = 0
348
432
  loop do
349
433
  command_and_args, command_options = @queue.pop
350
- sync_resource = command_options && command_options[:sync_resource]
351
- test_connection
352
- case command_and_args
353
- when 'exit'
354
- logger.info "Exiting, #{@queue.size} commands remain"
355
- return true
356
- when 'flush'
357
- release_resource = true
358
- else
359
- logger.debug "Sending: #{command_and_args.chomp}"
360
- @socket.puts command_and_args
361
- end
362
- command_and_args = nil
363
- command_options = nil
364
- if sync_resource
365
- @sync_mutex.synchronize do
366
- sync_resource.signal
434
+ if command_and_args
435
+ sync_resource = command_options && command_options[:sync_resource]
436
+ test_connection
437
+ case command_and_args
438
+ when 'exit'
439
+ logger.info "Exiting, #{@queue.size} commands remain"
440
+ return true
441
+ when 'flush'
442
+ release_resource = true
443
+ else
444
+ logger.debug "Sending: #{command_and_args.chomp}"
445
+ @socket.puts command_and_args
446
+ end
447
+ command_and_args = nil
448
+ command_options = nil
449
+ if sync_resource
450
+ @sync_mutex.synchronize do
451
+ sync_resource.signal
452
+ end
367
453
  end
368
454
  end
369
455
  end
370
456
  rescue Exception => err
371
- if err.is_a?(EOFError)
457
+ allow_reconnect = @allow_reconnect
458
+ case err
459
+ when EOFError
372
460
  # nop
373
- elsif err.is_a?(Errno::ECONNREFUSED)
374
- logger.error "unable to connect to Instrumental."
461
+ when Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EADDRINUSE
462
+ # If the connection has been refused by Instrumental
463
+ # or we cannot reach the server
464
+ # or the connection state of this socket is in a race
465
+ logger.error "unable to connect to Instrumental, hanging up with #{@queue.size} messages remaining"
466
+ allow_reconnect = false
375
467
  else
376
468
  report_exception(err)
377
469
  end
378
- if @allow_reconnect == false ||
470
+ if allow_reconnect == false ||
379
471
  (command_options && command_options[:allow_reconnect] == false)
380
472
  logger.info "Not trying to reconnect"
473
+ @failures = 0
381
474
  return
382
475
  end
383
476
  if command_and_args
@@ -401,14 +494,20 @@ module Instrumental
401
494
  end
402
495
 
403
496
  def running?
404
- !@thread.nil? && @pid == Process.pid
497
+ !@thread.nil? && @pid == Process.pid && @thread.alive?
498
+ end
499
+
500
+ def flush_socket(socket)
501
+ socket.flush
405
502
  end
406
503
 
407
504
  def disconnect
408
505
  if connected?
409
506
  logger.info "Disconnecting..."
410
507
  begin
411
- with_timeout(EXIT_FLUSH_TIMEOUT) { @socket.flush }
508
+ with_timeout(EXIT_FLUSH_TIMEOUT) do
509
+ flush_socket(@socket)
510
+ end
412
511
  rescue Timeout::Error
413
512
  logger.info "Timed out flushing socket..."
414
513
  end
@@ -417,6 +516,21 @@ module Instrumental
417
516
  @socket = nil
418
517
  end
419
518
 
519
+ def allows_secure?
520
+ defined?(OpenSSL)
521
+ end
522
+
523
+ def certificates
524
+ if allows_secure?
525
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
526
+ %w{equifax geotrust rapidssl}.map do |name|
527
+ OpenSSL::X509::Certificate.new(File.open(File.join(base_dir, "certs", "#{name}.ca.pem")))
528
+ end
529
+ else
530
+ []
531
+ end
532
+ end
533
+
420
534
  end
421
535
 
422
536
  end