manticore 0.9.0-java → 0.9.2-java
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/.github/workflows/jruby-ci.yml +52 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +4 -1
- data/Rakefile +31 -6
- data/lib/manticore/client.rb +22 -11
- data/lib/manticore/version.rb +1 -1
- data/lib/manticore.rb +3 -0
- data/lib/org/manticore/manticore-ext.jar +0 -0
- data/manticore.gemspec +5 -5
- data/spec/manticore/client_spec.rb +56 -2
- data/spec/spec_helper.rb +19 -1
- metadata +12 -15
- data/.travis.yml +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f135d2f44775f0b19d86715a09d9bfdbf9f5c3b3bd2561f703fdc5b5ad670852
|
|
4
|
+
data.tar.gz: c1c61c04ce83f4ad1b639221cd33c975dda4e097be0e139e58f76f414422d694
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c683ad66fee84b2ca28e41ff360304b6a035dd89922a7e59f212bc59b8b45a0d63216045881de6b6412b1adc3bc599d4380d4c45e37338a5e29ca9a2ab60a93e
|
|
7
|
+
data.tar.gz: fc4bb202b9a1401ee7e3d86e56d4836dbd2f4bcece55631848d7c4bbd762728891fd3444dcaa786a5df4c22810c1b4a83cbb74d93add92bb8e320900596d5e2b
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: JRuby CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
env:
|
|
6
|
+
JRUBY_OPTS: '-J-ea -J-Djruby.ji.ambiguous.calls.debug=true'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
include:
|
|
15
|
+
- { jruby: 'jruby-head', jdk: '21', experimental: true }
|
|
16
|
+
- { jruby: 'jruby-10.0.0.1', jdk: '21' }
|
|
17
|
+
- { jruby: 'jruby-10.0.2.0', jdk: '21' }
|
|
18
|
+
- { jruby: 'jruby-10.0.2.0', jdk: '25' }
|
|
19
|
+
- { jruby: 'jruby-9.4.12.0', jdk: '21', jruby_opts: '-Xcompile.invokedynamic -Xjit.threshold=0' }
|
|
20
|
+
- { jruby: 'jruby-9.4.14.0', jdk: '21' }
|
|
21
|
+
- { jruby: 'jruby-9.4.13.0', jdk: '17' }
|
|
22
|
+
- { jruby: 'jruby-9.4.14.0', jdk: '11' }
|
|
23
|
+
- { jruby: 'jruby-9.4.14.0', jdk: '8' }
|
|
24
|
+
- { jruby: 'jruby-9.3.15.0', jdk: '11' }
|
|
25
|
+
- { jruby: 'jruby-9.3.15.0', jdk: '8' }
|
|
26
|
+
|
|
27
|
+
continue-on-error: ${{ matrix.experimental || false }}
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Set up JDK
|
|
33
|
+
uses: actions/setup-java@v5
|
|
34
|
+
with:
|
|
35
|
+
java-version: ${{ matrix.jdk }}
|
|
36
|
+
distribution: ${{ matrix.distro || 'temurin' }}
|
|
37
|
+
|
|
38
|
+
- name: Set up JRuby
|
|
39
|
+
uses: ruby/setup-ruby@v1
|
|
40
|
+
with:
|
|
41
|
+
ruby-version: ${{ matrix.jruby }}
|
|
42
|
+
bundler-cache: true
|
|
43
|
+
|
|
44
|
+
- name: Bundle install
|
|
45
|
+
run: |
|
|
46
|
+
bundle install
|
|
47
|
+
|
|
48
|
+
- name: Run tests
|
|
49
|
+
run: |
|
|
50
|
+
jruby -rbundler/setup -S rake generate_certs
|
|
51
|
+
echo "JRUBY_OPTS=${JRUBY_OPTS} ${{ matrix.jruby_opts || '' }}" >> $GITHUB_ENV
|
|
52
|
+
jruby -rbundler/setup -S rake spec
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
### v0.9.2
|
|
2
|
+
|
|
3
|
+
* [fix] avoid `File.exists?` due JRuby 10
|
|
4
|
+
* [fix] don't send entity when get/delete have no body (#116)
|
|
5
|
+
* [feat] Raises InvalidUriException for java URISyntaxException (#112)
|
|
6
|
+
* [fix] Don't strip the decoded certificate, ~~chomp should be enough~~ (#113) (#119)
|
|
7
|
+
|
|
8
|
+
### v0.9.1
|
|
9
|
+
|
|
10
|
+
* [fix] work-around JRuby 9.3.4 compatibility
|
|
11
|
+
* [refactor] delay closing async request queue on client.close
|
|
12
|
+
|
|
1
13
|
### v0.9.0
|
|
2
14
|
|
|
3
15
|
* [feat] revamped client.close to release resources (#108)
|
data/Gemfile
CHANGED
|
@@ -4,8 +4,11 @@ source 'https://rubygems.org'
|
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
6
|
group :development, :test do
|
|
7
|
+
# NOTE: should eventually become a runtime dependency
|
|
8
|
+
gem "base64", require: false
|
|
9
|
+
|
|
7
10
|
gem "rake-compiler", require: false
|
|
8
|
-
gem "simplecov"
|
|
11
|
+
gem "simplecov", require: false
|
|
9
12
|
|
|
10
13
|
gem "rspec", "~> 3.0"
|
|
11
14
|
gem "rspec-its"
|
data/Rakefile
CHANGED
|
@@ -26,29 +26,54 @@ end
|
|
|
26
26
|
|
|
27
27
|
# Generate all the stuff we need for a full test run
|
|
28
28
|
task :generate_certs do
|
|
29
|
+
require "base64"
|
|
29
30
|
root = File.expand_path("../spec/ssl", __FILE__)
|
|
30
31
|
openssl = `which openssl`.strip
|
|
31
32
|
keytool = `which keytool`.strip
|
|
32
33
|
|
|
33
34
|
Dir.glob("#{root}/*").each { |f| File.unlink f }
|
|
34
35
|
|
|
36
|
+
print 'Generating a key that ends with a whitespace character'
|
|
37
|
+
whitespace_found = false
|
|
38
|
+
until whitespace_found
|
|
39
|
+
putc '.'
|
|
40
|
+
key_str = ''
|
|
41
|
+
IO.popen("#{openssl} genrsa 4096 2>/dev/null") { |openssl_io| key_str = openssl_io.read }
|
|
42
|
+
key_parts = key_str.scan(/(?:^-----BEGIN(.* )PRIVATE KEY-----\n)(.*?)(?:-----END\1PRIVATE KEY.*$)/m)
|
|
43
|
+
key_parts.each do |_type, b64key|
|
|
44
|
+
body = Base64.decode64 b64key
|
|
45
|
+
body != body.strip && whitespace_found = true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
puts ' Found'
|
|
49
|
+
IO.popen("#{openssl} pkcs8 -topk8 -nocrypt -out #{root}/client_whitespace.key", 'r+') do |openssl_io|
|
|
50
|
+
openssl_io.puts key_str
|
|
51
|
+
openssl_io.close_write
|
|
52
|
+
end
|
|
53
|
+
|
|
35
54
|
cmds = [
|
|
36
55
|
# Create the CA
|
|
37
56
|
"#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/root-ca.key",
|
|
38
|
-
"#{openssl} req -
|
|
39
|
-
"#{openssl} req -
|
|
57
|
+
"#{openssl} req -newkey rsa:4096 -x509 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-ca.crt -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore CA/OU=Manticore/CN=localhost\"",
|
|
58
|
+
"#{openssl} req -newkey rsa:4096 -x509 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-untrusted-ca.crt -subj \"/C=US/ST=The Darknet/L=The Darknet/O=Manticore CA/OU=Manticore/CN=localhost\"",
|
|
40
59
|
|
|
41
60
|
# Create the client CSR, key, and signed cert
|
|
42
61
|
"#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/client.key",
|
|
43
|
-
"#{openssl} req -sha256 -key #{root}/client.key -
|
|
62
|
+
"#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/client.key -out #{root}/client.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"",
|
|
44
63
|
"#{openssl} x509 -req -in #{root}/client.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client.crt -sha256 -days 1",
|
|
45
|
-
|
|
64
|
+
# OpenSSL 3 rejects negative -days; use 0 days to produce an immediately-expired cert
|
|
65
|
+
"#{openssl} x509 -req -in #{root}/client.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client-expired.crt -sha256 -days 0",
|
|
66
|
+
|
|
67
|
+
# Create the client_whitespace CSR and signed cert
|
|
68
|
+
"#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/client_whitespace.key -out #{root}/client_whitespace.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"",
|
|
69
|
+
"#{openssl} x509 -req -in #{root}/client_whitespace.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client_whitespace.crt -sha256 -days 1",
|
|
46
70
|
|
|
47
71
|
# Create the server cert
|
|
48
72
|
"#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/host.key",
|
|
49
|
-
"#{openssl} req -sha256 -key #{root}/host.key -
|
|
73
|
+
"#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/host.key -out #{root}/host.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost\"",
|
|
50
74
|
"#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host.crt -sha256 -days 1",
|
|
51
|
-
|
|
75
|
+
# OpenSSL 3 rejects negative -days; use 0 days to produce an immediately-expired cert
|
|
76
|
+
"#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host-expired.crt -sha256 -days 0",
|
|
52
77
|
"#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-untrusted-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host-untrusted.crt -sha256 -days 1",
|
|
53
78
|
|
|
54
79
|
"#{keytool} -import -file #{root}/root-ca.crt -alias rootCA -keystore #{root}/truststore.jks -noprompt -storepass test123",
|
data/lib/manticore/client.rb
CHANGED
|
@@ -69,7 +69,6 @@ module Manticore
|
|
|
69
69
|
include_package "org.apache.http.client.config"
|
|
70
70
|
include_package "org.apache.http.config"
|
|
71
71
|
include_package "org.apache.http.conn.socket"
|
|
72
|
-
include_package "org.apache.http.impl.client"
|
|
73
72
|
include_package "org.apache.http.impl.conn"
|
|
74
73
|
include_package "org.apache.http.entity"
|
|
75
74
|
include_package "org.apache.http.message"
|
|
@@ -93,7 +92,12 @@ module Manticore
|
|
|
93
92
|
java_import "org.apache.http.conn.ssl.TrustSelfSignedStrategy"
|
|
94
93
|
java_import "org.apache.http.client.utils.URIBuilder"
|
|
95
94
|
java_import "org.apache.http.impl.DefaultConnectionReuseStrategy"
|
|
95
|
+
java_import "org.apache.http.impl.NoConnectionReuseStrategy"
|
|
96
96
|
java_import "org.apache.http.impl.auth.BasicScheme"
|
|
97
|
+
java_import "org.apache.http.impl.client.BasicAuthCache"
|
|
98
|
+
java_import "org.apache.http.impl.client.BasicCookieStore"
|
|
99
|
+
java_import "org.apache.http.impl.client.BasicCredentialsProvider"
|
|
100
|
+
java_import "org.apache.http.impl.client.HttpClientBuilder"
|
|
97
101
|
java_import "org.apache.http.ssl.SSLContextBuilder"
|
|
98
102
|
java_import "org.apache.http.ssl.TrustStrategy"
|
|
99
103
|
|
|
@@ -159,7 +163,6 @@ module Manticore
|
|
|
159
163
|
# @option options [integer] connect_timeout (10) Sets the timeout for connections. Raises Manticore::Timeout on failure.
|
|
160
164
|
# @option options [integer] socket_timeout (10) Sets SO_TIMEOUT for open connections. A value of 0 is an infinite timeout. Raises Manticore::Timeout on failure.
|
|
161
165
|
# @option options [boolean] tcp_no_delay (true) Enable or disable Nagle's algorithm
|
|
162
|
-
# @option options [integer] request_timeout (60) Sets the timeout for a given request. Raises Manticore::Timeout on failure.
|
|
163
166
|
# @option options [integer] max_redirects (5) Sets the maximum number of redirects to follow.
|
|
164
167
|
# @option options [integer] automatic_retries (3) Sets the number of times the client will automatically retry failed requests.
|
|
165
168
|
# @option options [boolean] retry_non_idempotent (false) If true, Manticore will automatically retry failed requests with non-idempotent verbs. Otherwise, it only automatically retries
|
|
@@ -214,7 +217,7 @@ module Manticore
|
|
|
214
217
|
|
|
215
218
|
@keepalive = options.fetch(:keepalive, true)
|
|
216
219
|
if @keepalive == false
|
|
217
|
-
builder.set_connection_reuse_strategy
|
|
220
|
+
builder.set_connection_reuse_strategy NoConnectionReuseStrategy::INSTANCE # return false
|
|
218
221
|
else
|
|
219
222
|
builder.set_connection_reuse_strategy DefaultConnectionReuseStrategy.new
|
|
220
223
|
end
|
|
@@ -258,7 +261,8 @@ module Manticore
|
|
|
258
261
|
# @macro http_method_shared_sync
|
|
259
262
|
def get(url, options = {}, &block)
|
|
260
263
|
options = treat_params_as_query(options)
|
|
261
|
-
|
|
264
|
+
get_class = options[:body] ? HttpGetWithEntity : HttpGet
|
|
265
|
+
request get_class, url, options, &block
|
|
262
266
|
end
|
|
263
267
|
|
|
264
268
|
# Perform a HTTP PUT request
|
|
@@ -284,7 +288,8 @@ module Manticore
|
|
|
284
288
|
# @macro http_method_shared_sync
|
|
285
289
|
def delete(url, options = {}, &block)
|
|
286
290
|
options = treat_params_as_query(options)
|
|
287
|
-
|
|
291
|
+
delete_class = options[:body] ? HttpDeleteWithEntity : HttpDelete
|
|
292
|
+
request delete_class, url, options, &block
|
|
288
293
|
end
|
|
289
294
|
|
|
290
295
|
# Perform a HTTP OPTIONS request
|
|
@@ -373,7 +378,6 @@ module Manticore
|
|
|
373
378
|
# @executor&.shutdown rescue nil
|
|
374
379
|
# @client&.close
|
|
375
380
|
# @pool&.shutdown rescue nil
|
|
376
|
-
@async_requests.close
|
|
377
381
|
case await
|
|
378
382
|
when false, nil
|
|
379
383
|
@executor&.shutdown_now rescue nil
|
|
@@ -384,6 +388,7 @@ module Manticore
|
|
|
384
388
|
else
|
|
385
389
|
nil
|
|
386
390
|
end
|
|
391
|
+
@async_requests.close
|
|
387
392
|
end
|
|
388
393
|
|
|
389
394
|
# @private
|
|
@@ -511,7 +516,11 @@ module Manticore
|
|
|
511
516
|
|
|
512
517
|
def uri_from_url_and_options(url, options)
|
|
513
518
|
url = url.to_s if url.is_a?(URI)
|
|
514
|
-
|
|
519
|
+
begin
|
|
520
|
+
builder = URIBuilder.new(url)
|
|
521
|
+
rescue Java::JavaNet::URISyntaxException => e
|
|
522
|
+
raise Manticore::InvalidUriException.new(e)
|
|
523
|
+
end
|
|
515
524
|
pairs = struct_to_name_value_pairs(options[:query])
|
|
516
525
|
builder.add_parameters pairs unless pairs.empty?
|
|
517
526
|
builder.to_string
|
|
@@ -720,7 +729,7 @@ module Manticore
|
|
|
720
729
|
|
|
721
730
|
cert_str = if ssl_options[:client_cert].is_a?(OpenSSL::X509::Certificate)
|
|
722
731
|
ssl_options[:client_cert].to_s
|
|
723
|
-
elsif ssl_options[:client_cert].is_a?(String) && File.
|
|
732
|
+
elsif ssl_options[:client_cert].is_a?(String) && File.exist?(ssl_options[:client_cert])
|
|
724
733
|
File.read(ssl_options[:client_cert])
|
|
725
734
|
else
|
|
726
735
|
ssl_options[:client_cert].to_s
|
|
@@ -731,7 +740,7 @@ module Manticore
|
|
|
731
740
|
|
|
732
741
|
key_str = if ssl_options[:client_key].is_a?(OpenSSL::PKey::PKey)
|
|
733
742
|
ssl_options[:client_key].to_pem_pkcs8
|
|
734
|
-
elsif ssl_options[:client_key].is_a?(String) && File.
|
|
743
|
+
elsif ssl_options[:client_key].is_a?(String) && File.exist?(ssl_options[:client_key])
|
|
735
744
|
File.read(ssl_options[:client_key])
|
|
736
745
|
else
|
|
737
746
|
ssl_options[:client_key].to_s
|
|
@@ -741,7 +750,8 @@ module Manticore
|
|
|
741
750
|
key_parts = key_str.scan(KEY_EXTRACTION_REGEXP)
|
|
742
751
|
key_parts.each do |type, b64key|
|
|
743
752
|
body = Base64.decode64 b64key
|
|
744
|
-
|
|
753
|
+
# Do not chomp binary DER content; trimming can corrupt the key structure.
|
|
754
|
+
spec = PKCS8EncodedKeySpec.new(body.to_java_bytes)
|
|
745
755
|
type = type.strip
|
|
746
756
|
type = "RSA" if type == ""
|
|
747
757
|
key = KeyFactory.getInstance(type).generatePrivate(spec)
|
|
@@ -780,10 +790,11 @@ module Manticore
|
|
|
780
790
|
end
|
|
781
791
|
end
|
|
782
792
|
|
|
783
|
-
class LoggingStandardRetryHandler <
|
|
793
|
+
class LoggingStandardRetryHandler < org.apache.http.impl.client.StandardHttpRequestRetryHandler
|
|
784
794
|
def retryRequest(exception, executionCount, context)
|
|
785
795
|
context.setAttribute "retryCount", executionCount
|
|
786
796
|
super(exception, executionCount, context)
|
|
787
797
|
end
|
|
788
798
|
end
|
|
799
|
+
private_constant :LoggingStandardRetryHandler
|
|
789
800
|
end
|
data/lib/manticore/version.rb
CHANGED
data/lib/manticore.rb
CHANGED
|
@@ -54,6 +54,9 @@ module Manticore
|
|
|
54
54
|
# The client has been closed so it's no longer usable
|
|
55
55
|
class ClientStoppedException < ManticoreException; end
|
|
56
56
|
|
|
57
|
+
# Client tried to use illegal characters in URI
|
|
58
|
+
class InvalidUriException < ManticoreException; end
|
|
59
|
+
|
|
57
60
|
# Socket breaks, etc
|
|
58
61
|
class SocketException < ManticoreException; end
|
|
59
62
|
|
|
Binary file
|
data/manticore.gemspec
CHANGED
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
spec.required_ruby_version = '>= 2.3' # JRuby >= 9.1
|
|
23
23
|
|
|
24
24
|
private_key = File.expand_path("~/.gemcert/gem-private_key.pem")
|
|
25
|
-
if File.
|
|
25
|
+
if File.exist? private_key
|
|
26
26
|
spec.signing_key = private_key
|
|
27
27
|
spec.cert_chain = ['gem-public_cert.pem']
|
|
28
28
|
end
|
|
@@ -31,9 +31,9 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
|
|
32
32
|
spec.add_development_dependency "jar-dependencies", "~> 0.4.1"
|
|
33
33
|
|
|
34
|
-
spec.requirements << "jar org.apache.httpcomponents:httpclient, '~> 4.5.
|
|
35
|
-
spec.requirements << "jar org.apache.httpcomponents:httpmime, '~> 4.5.
|
|
34
|
+
spec.requirements << "jar org.apache.httpcomponents:httpclient, '~> 4.5.14'"
|
|
35
|
+
spec.requirements << "jar org.apache.httpcomponents:httpmime, '~> 4.5.14'"
|
|
36
36
|
spec.requirements << "jar commons-logging:commons-logging, '~> 1.2'"
|
|
37
|
-
spec.requirements << "jar commons-codec:commons-codec, '~> 1.
|
|
38
|
-
spec.requirements << "jar org.apache.httpcomponents:httpcore, '~> 4.4.
|
|
37
|
+
spec.requirements << "jar commons-codec:commons-codec, '~> 1.11'"
|
|
38
|
+
spec.requirements << "jar org.apache.httpcomponents:httpcore, '~> 4.4.16'"
|
|
39
39
|
end
|
|
@@ -245,6 +245,23 @@ describe Manticore::Client do
|
|
|
245
245
|
end
|
|
246
246
|
end
|
|
247
247
|
|
|
248
|
+
context 'when client_key ending on whitespace character' do
|
|
249
|
+
let(:client) do
|
|
250
|
+
Manticore::Client.new(
|
|
251
|
+
ssl: {
|
|
252
|
+
verify: :default,
|
|
253
|
+
ca_file: File.expand_path('../ssl/root-ca.crt', __dir__),
|
|
254
|
+
client_cert: File.read(File.expand_path('../ssl/client_whitespace.crt', __dir__)),
|
|
255
|
+
client_key: File.read(File.expand_path('../ssl/client_whitespace.key', __dir__))
|
|
256
|
+
}
|
|
257
|
+
)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it 'raises no exception' do
|
|
261
|
+
expect(client).not_to be_nil
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
248
265
|
context "when off" do
|
|
249
266
|
let(:client) { Manticore::Client.new :ssl => {:verify => :disable} }
|
|
250
267
|
|
|
@@ -516,14 +533,14 @@ describe Manticore::Client do
|
|
|
516
533
|
it "can send an array of parameters as :params" do
|
|
517
534
|
response = client.get(local_server, params: {"foo" => ["baz", "bar"], "bar" => {"baz" => ["bin", 1, :b]}})
|
|
518
535
|
j = JSON.load(response.body)
|
|
519
|
-
expect(j["body"]).to
|
|
536
|
+
expect(j["body"]).to be_nil
|
|
520
537
|
expect(j["uri"]["query"]).to include("foo=baz")
|
|
521
538
|
end
|
|
522
539
|
|
|
523
540
|
it "can send an array of parameters as :query" do
|
|
524
541
|
response = client.get(local_server, query: {"foo" => ["baz", "bar"]})
|
|
525
542
|
j = JSON.load(response.body)
|
|
526
|
-
expect(j["body"]).to
|
|
543
|
+
expect(j["body"]).to be_nil
|
|
527
544
|
expect(j["uri"]["query"]).to include("foo=baz")
|
|
528
545
|
end
|
|
529
546
|
|
|
@@ -538,6 +555,27 @@ describe Manticore::Client do
|
|
|
538
555
|
j = JSON.load(response.body)
|
|
539
556
|
expect(CGI.parse j["uri"]["query"]).to eq({"foo" => ["bar"], "baz" => ["bin"]})
|
|
540
557
|
end
|
|
558
|
+
|
|
559
|
+
it "raises InvalidUriException for illegal character in URI" do
|
|
560
|
+
expect { client.get(local_server + "?foo=bar{{{", query: {"baz" => "bin"})}
|
|
561
|
+
.to raise_exception(Manticore::InvalidUriException)
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
describe "body" do
|
|
565
|
+
let(:params) { { body: body } }
|
|
566
|
+
context "when there is no body" do
|
|
567
|
+
let(:body) { nil }
|
|
568
|
+
it "does not send http get with entity" do
|
|
569
|
+
expect(client.get("http://google.com", params).request).to_not respond_to(:entity)
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
context "when there is a body" do
|
|
573
|
+
let(:body) { "hello" }
|
|
574
|
+
it "sends http get with entity" do
|
|
575
|
+
expect(client.get("http://google.com", params).request).to respond_to(:entity)
|
|
576
|
+
end
|
|
577
|
+
end
|
|
578
|
+
end
|
|
541
579
|
end
|
|
542
580
|
|
|
543
581
|
describe "#post" do
|
|
@@ -609,6 +647,22 @@ describe Manticore::Client do
|
|
|
609
647
|
response = client.delete(local_server, body: "This is a delete body")
|
|
610
648
|
expect(JSON.load(response.body)["body"]).to eq "This is a delete body"
|
|
611
649
|
end
|
|
650
|
+
|
|
651
|
+
describe "body" do
|
|
652
|
+
let(:params) { { body: body } }
|
|
653
|
+
context "when there is no body" do
|
|
654
|
+
let(:body) { nil }
|
|
655
|
+
it "does not send http get with entity" do
|
|
656
|
+
expect(client.delete("http://google.com", params).request).to_not respond_to(:entity)
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
context "when there is a body" do
|
|
660
|
+
let(:body) { "hello" }
|
|
661
|
+
it "sends http get with entity" do
|
|
662
|
+
expect(client.delete("http://google.com", params).request).to respond_to(:entity)
|
|
663
|
+
end
|
|
664
|
+
end
|
|
665
|
+
end
|
|
612
666
|
end
|
|
613
667
|
|
|
614
668
|
describe "#head" do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -119,7 +119,23 @@ def start_ssl_server(port, options = {})
|
|
|
119
119
|
%w[CN localhost],
|
|
120
120
|
]
|
|
121
121
|
cert_file = options[:cert] || File.expand_path("../ssl/host.crt", __FILE__)
|
|
122
|
-
cert
|
|
122
|
+
if options[:cert] && !File.exist?(cert_file)
|
|
123
|
+
# Generate an expired self-signed certificate if the requested cert file
|
|
124
|
+
# is missing (e.g., OpenSSL 3 rejects negative/zero -days during fixture generation).
|
|
125
|
+
pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path("../ssl/host.key", __FILE__))
|
|
126
|
+
cert = OpenSSL::X509::Certificate.new
|
|
127
|
+
cert.version = 2
|
|
128
|
+
cert.serial = 1
|
|
129
|
+
name = OpenSSL::X509::Name.parse('/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost')
|
|
130
|
+
cert.subject = name
|
|
131
|
+
cert.issuer = name
|
|
132
|
+
cert.public_key = pkey.public_key
|
|
133
|
+
cert.not_before = Time.now - 2 * 24 * 60 * 60
|
|
134
|
+
cert.not_after = Time.now - 24 * 60 * 60
|
|
135
|
+
cert.sign pkey, OpenSSL::Digest::SHA256.new
|
|
136
|
+
else
|
|
137
|
+
cert = OpenSSL::X509::Certificate.new File.read(cert_file)
|
|
138
|
+
end
|
|
123
139
|
cert.version = 0 # HACK: Work around jruby-openssl in jruby-head not setting cert.version
|
|
124
140
|
pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path("../ssl/host.key", __FILE__))
|
|
125
141
|
@servers[port] = Thread.new {
|
|
@@ -131,6 +147,8 @@ def start_ssl_server(port, options = {})
|
|
|
131
147
|
:SSLPrivateKey => pkey,
|
|
132
148
|
:AccessLog => [],
|
|
133
149
|
:Logger => WEBrick::Log.new("/dev/null"),
|
|
150
|
+
# Disable TLS 1.3 to avoid interop issues with some JRuby/JDK combos during mTLS
|
|
151
|
+
:SSLOptions => (defined?(OpenSSL::SSL::OP_NO_TLSv1_3) ? OpenSSL::SSL::OP_NO_TLSv1_3 : 0),
|
|
134
152
|
}.merge(options)
|
|
135
153
|
)
|
|
136
154
|
server.mount_proc "/" do |req, res|
|
metadata
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: manticore
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.2
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Heald
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-10-20 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: openssl_pkcs8_pure
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '0'
|
|
19
|
-
name: openssl_pkcs8_pure
|
|
20
|
-
prerelease: false
|
|
21
19
|
type: :runtime
|
|
20
|
+
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: jar-dependencies
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: 0.4.1
|
|
33
|
-
name: jar-dependencies
|
|
34
|
-
prerelease: false
|
|
35
33
|
type: :development
|
|
34
|
+
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
@@ -45,9 +44,9 @@ executables: []
|
|
|
45
44
|
extensions: []
|
|
46
45
|
extra_rdoc_files: []
|
|
47
46
|
files:
|
|
47
|
+
- ".github/workflows/jruby-ci.yml"
|
|
48
48
|
- ".gitignore"
|
|
49
49
|
- ".gitlab-ci.yml"
|
|
50
|
-
- ".travis.yml"
|
|
51
50
|
- APACHE-LICENSE-2.0.txt
|
|
52
51
|
- CHANGELOG.md
|
|
53
52
|
- Gemfile
|
|
@@ -90,7 +89,6 @@ homepage: https://github.com/cheald/manticore
|
|
|
90
89
|
licenses:
|
|
91
90
|
- MIT
|
|
92
91
|
metadata: {}
|
|
93
|
-
post_install_message:
|
|
94
92
|
rdoc_options: []
|
|
95
93
|
require_paths:
|
|
96
94
|
- lib
|
|
@@ -105,13 +103,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
105
103
|
- !ruby/object:Gem::Version
|
|
106
104
|
version: '0'
|
|
107
105
|
requirements:
|
|
108
|
-
- jar org.apache.httpcomponents:httpclient, '~> 4.5.
|
|
109
|
-
- jar org.apache.httpcomponents:httpmime, '~> 4.5.
|
|
106
|
+
- jar org.apache.httpcomponents:httpclient, '~> 4.5.14'
|
|
107
|
+
- jar org.apache.httpcomponents:httpmime, '~> 4.5.14'
|
|
110
108
|
- jar commons-logging:commons-logging, '~> 1.2'
|
|
111
|
-
- jar commons-codec:commons-codec, '~> 1.
|
|
112
|
-
- jar org.apache.httpcomponents:httpcore, '~> 4.4.
|
|
113
|
-
rubygems_version: 3.
|
|
114
|
-
signing_key:
|
|
109
|
+
- jar commons-codec:commons-codec, '~> 1.11'
|
|
110
|
+
- jar org.apache.httpcomponents:httpcore, '~> 4.4.16'
|
|
111
|
+
rubygems_version: 3.6.3
|
|
115
112
|
specification_version: 4
|
|
116
113
|
summary: Manticore is an HTTP client built on the Apache HttpCore components
|
|
117
114
|
test_files:
|
data/.travis.yml
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
dist: trusty # due Oracle JDK
|
|
2
|
-
language: ruby
|
|
3
|
-
cache:
|
|
4
|
-
- bundler
|
|
5
|
-
- directories:
|
|
6
|
-
- $HOME/.m2
|
|
7
|
-
before_install:
|
|
8
|
-
- gem install bundler -v 1.17.3
|
|
9
|
-
matrix:
|
|
10
|
-
include:
|
|
11
|
-
- rvm: jruby-head
|
|
12
|
-
jdk: openjdk11
|
|
13
|
-
- rvm: jruby-9.3.4.0 # Ruby 2.6
|
|
14
|
-
jdk: openjdk11
|
|
15
|
-
- rvm: jruby-9.2.20.0 # Ruby 2.5
|
|
16
|
-
jdk: oraclejdk8
|
|
17
|
-
- rvm: jruby-9.2.20.0
|
|
18
|
-
jdk: openjdk11
|
|
19
|
-
- rvm: jruby-9.1.17.0 # Ruby 2.3
|
|
20
|
-
jdk: openjdk8
|
|
21
|
-
allow_failures:
|
|
22
|
-
- rvm: jruby-head
|