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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 281400646207bd8e4b34bed53610787e5b5d222c72fe5e82dd1d42d8f071f1be
4
- data.tar.gz: 421a4a8f1c4f8e06a7d12377812da2613877877904c73d3d8375348fbb9e2103
3
+ metadata.gz: f135d2f44775f0b19d86715a09d9bfdbf9f5c3b3bd2561f703fdc5b5ad670852
4
+ data.tar.gz: c1c61c04ce83f4ad1b639221cd33c975dda4e097be0e139e58f76f414422d694
5
5
  SHA512:
6
- metadata.gz: c72e625dc8aa526a1336c239ced7d46cebf9b16817f9c309b1caaa80028a14e959cbe342e745db69dfef8fd284b1413085a518322406ecab3e7a28725815a34f
7
- data.tar.gz: 37774c46167abf4c8cb637580dc2cf91afc4311b8a284c17d48441ba00824ba0af41e47121780837caffef60632aa3c26bb075b323011a2fcb56fb055495e83c
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 -sha256 -x509 -newkey rsa:4096 -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\"",
39
- "#{openssl} req -sha256 -x509 -newkey rsa:4096 -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\"",
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 -newkey rsa:4096 -out #{root}/client.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"",
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
- "#{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 -7",
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 -newkey rsa:4096 -out #{root}/host.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost\"",
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
- "#{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 -7",
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",
@@ -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 { |response, context| false }
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
- request HttpGetWithEntity, url, options, &block
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
- request HttpDeleteWithEntity, url, options, &block
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
- builder = URIBuilder.new(url)
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.exists?(ssl_options[:client_cert])
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.exists?(ssl_options[:client_key])
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
- spec = PKCS8EncodedKeySpec.new(body.strip.to_java_bytes)
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 < Java::OrgApacheHttpImplClient::StandardHttpRequestRetryHandler
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
@@ -1,3 +1,3 @@
1
1
  module Manticore
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.2"
3
3
  end
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.exists? private_key
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.13'"
35
- spec.requirements << "jar org.apache.httpcomponents:httpmime, '~> 4.5.13'"
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.9'"
38
- spec.requirements << "jar org.apache.httpcomponents:httpcore, '~> 4.4.14'"
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 eq ""
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 eq ""
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 = OpenSSL::X509::Certificate.new File.read(cert_file)
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.0
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: 2022-06-02 00:00:00.000000000 Z
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.13'
109
- - jar org.apache.httpcomponents:httpmime, '~> 4.5.13'
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.9'
112
- - jar org.apache.httpcomponents:httpcore, '~> 4.4.14'
113
- rubygems_version: 3.2.29
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