manticore 0.6.0-java → 0.7.0-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 +5 -5
- data/.gitlab-ci.yml +42 -0
- data/.travis.yml +8 -10
- data/CHANGELOG.md +18 -1
- data/Gemfile +4 -2
- data/README.md +3 -1
- data/Rakefile +14 -12
- data/ext/manticore/org/manticore/Manticore.java +13 -4
- data/lib/faraday/adapter/manticore.rb +11 -15
- data/lib/manticore.rb +10 -10
- data/lib/manticore/client.rb +102 -76
- data/lib/manticore/client/proxies.rb +3 -1
- data/lib/manticore/cookie.rb +12 -12
- data/lib/manticore/facade.rb +2 -2
- data/lib/manticore/java_extensions.rb +1 -1
- data/lib/manticore/response.rb +48 -30
- data/lib/manticore/stubbed_response.rb +6 -5
- data/lib/manticore/version.rb +1 -1
- data/lib/manticore_jars.rb +6 -6
- data/lib/org/manticore/manticore-ext.jar +0 -0
- data/manticore.gemspec +4 -2
- data/spec/manticore/client_proxy_spec.rb +5 -4
- data/spec/manticore/client_spec.rb +177 -69
- data/spec/manticore/cookie_spec.rb +9 -10
- data/spec/manticore/facade_spec.rb +6 -6
- data/spec/manticore/response_spec.rb +22 -11
- data/spec/manticore/stubbed_response_spec.rb +5 -5
- data/spec/spec_helper.rb +51 -28
- metadata +28 -14
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Manticore::Cookie do
|
4
4
|
context "created from a Client request" do
|
@@ -9,28 +9,27 @@ describe Manticore::Cookie do
|
|
9
9
|
response.cookies["x"].first
|
10
10
|
}
|
11
11
|
|
12
|
-
its(:name)
|
13
|
-
its(:value)
|
14
|
-
its(:path)
|
12
|
+
its(:name) { is_expected.to eq "x" }
|
13
|
+
its(:value) { is_expected.to eq "2" }
|
14
|
+
its(:path) { is_expected.to eq "/" }
|
15
15
|
its(:domain) { is_expected.to eq "localhost" }
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
let(:opts) {{}}
|
18
|
+
let(:opts) { {} }
|
20
19
|
subject {
|
21
20
|
Manticore::Cookie.new({name: "foo", value: "bar"}.merge(opts))
|
22
21
|
}
|
23
22
|
|
24
|
-
its(:secure?)
|
23
|
+
its(:secure?) { is_expected.to be nil }
|
25
24
|
its(:persistent?) { is_expected.to be nil }
|
26
25
|
|
27
26
|
context "created as secure" do
|
28
|
-
let(:opts) {{
|
27
|
+
let(:opts) { {secure: true} }
|
29
28
|
its(:secure?) { is_expected.to be true }
|
30
29
|
end
|
31
30
|
|
32
31
|
context "created as persistent" do
|
33
|
-
let(:opts) {{
|
32
|
+
let(:opts) { {persistent: true} }
|
34
33
|
its(:persistent?) { is_expected.to be true }
|
35
34
|
end
|
36
|
-
end
|
35
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Manticore::Facade do
|
4
4
|
context "when extended into an arbitrary class" do
|
5
5
|
let(:extended_class) {
|
6
|
-
|
6
|
+
Class.new do
|
7
7
|
include Manticore::Facade
|
8
8
|
include_http_client
|
9
9
|
end
|
10
10
|
}
|
11
11
|
|
12
12
|
let(:extended_shared_class) {
|
13
|
-
|
13
|
+
Class.new do
|
14
14
|
include Manticore::Facade
|
15
15
|
include_http_client shared_pool: true
|
16
16
|
end
|
@@ -23,12 +23,12 @@ describe Manticore::Facade do
|
|
23
23
|
|
24
24
|
it "does not use the shared client by default" do
|
25
25
|
expect(extended_class.send(:__manticore_facade).object_id).to_not eq \
|
26
|
-
|
26
|
+
Manticore.send(:__manticore_facade).object_id
|
27
27
|
end
|
28
28
|
|
29
29
|
it "is able to use the shared client" do
|
30
30
|
expect(extended_shared_class.send(:__manticore_facade).object_id).to eq \
|
31
|
-
|
31
|
+
Manticore.send(:__manticore_facade).object_id
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should work with #http" do
|
@@ -43,4 +43,4 @@ describe Manticore::Facade do
|
|
43
43
|
expect(result["method"]).to eq "GET"
|
44
44
|
end
|
45
45
|
end
|
46
|
-
end
|
46
|
+
end
|
@@ -1,15 +1,27 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Manticore::Response do
|
4
4
|
let(:client) { Manticore::Client.new }
|
5
|
-
subject { client.get(
|
5
|
+
subject { client.get(local_server) }
|
6
6
|
|
7
7
|
its(:headers) { is_expected.to be_a Hash }
|
8
|
-
its(:body)
|
9
|
-
its(:length)
|
8
|
+
its(:body) { is_expected.to be_a String }
|
9
|
+
its(:length) { is_expected.to be_a Fixnum }
|
10
10
|
|
11
11
|
it "provides response header lookup via #[]" do
|
12
|
-
expect(subject["Content-Type"]).to eq "
|
12
|
+
expect(subject["Content-Type"]).to eq "application/json"
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when a response contains repeated headers" do
|
16
|
+
subject { client.get(local_server "/repeated_headers") }
|
17
|
+
|
18
|
+
it "returns an array of values for headers with multiple occurrances" do
|
19
|
+
expect(subject.headers["link"]).to eq ["foo", "bar"]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns only the first value when using response#[]" do
|
23
|
+
expect(subject["Link"]).to eq "foo"
|
24
|
+
end
|
13
25
|
end
|
14
26
|
|
15
27
|
it "reads the body" do
|
@@ -27,14 +39,14 @@ describe Manticore::Response do
|
|
27
39
|
context "when the client is invoked with a block" do
|
28
40
|
it "allows reading the body from a block" do
|
29
41
|
response = client.get(local_server) do |response|
|
30
|
-
expect(response.body).to match
|
42
|
+
expect(response.body).to match "Manticore"
|
31
43
|
end
|
32
44
|
|
33
45
|
expect(response.body).to match "Manticore"
|
34
46
|
end
|
35
47
|
|
36
48
|
it "does not read the body implicitly if called with a block" do
|
37
|
-
response = client.get(local_server) {}
|
49
|
+
response = client.get(local_server) { }
|
38
50
|
expect { response.body }.to raise_exception(Manticore::StreamClosedException)
|
39
51
|
end
|
40
52
|
end
|
@@ -51,9 +63,9 @@ describe Manticore::Response do
|
|
51
63
|
let(:responses) { {} }
|
52
64
|
let(:response) do
|
53
65
|
client.get(url)
|
54
|
-
.on_success {|resp| responses[:success] = true }
|
55
|
-
.on_failure {responses[:failure]
|
56
|
-
.on_complete {responses[:complete]
|
66
|
+
.on_success { |resp| responses[:success] = true }
|
67
|
+
.on_failure { responses[:failure] = true }
|
68
|
+
.on_complete { responses[:complete] = true }
|
57
69
|
end
|
58
70
|
|
59
71
|
context "a succeeded request" do
|
@@ -85,6 +97,5 @@ describe Manticore::Response do
|
|
85
97
|
expect { response.call }.to change { responses[:complete] }.to true
|
86
98
|
end
|
87
99
|
end
|
88
|
-
|
89
100
|
end
|
90
101
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Manticore::StubbedResponse do
|
4
4
|
subject {
|
@@ -7,9 +7,9 @@ describe Manticore::StubbedResponse do
|
|
7
7
|
code: 200,
|
8
8
|
headers: {
|
9
9
|
"Content-Type" => "text/plain",
|
10
|
-
"Set-Cookie" => ["k=v; path=/; domain=localhost", "k=v; path=/sub; domain=sub.localhost", "k2=v2;2 path=/; domain=localhost"]
|
10
|
+
"Set-Cookie" => ["k=v; path=/; domain=localhost", "k=v; path=/sub; domain=sub.localhost", "k2=v2;2 path=/; domain=localhost"],
|
11
11
|
},
|
12
|
-
cookies: {"test" => Manticore::Cookie.new(name: "test", value: "something", path: "/")}
|
12
|
+
cookies: {"test" => Manticore::Cookie.new(name: "test", value: "something", path: "/")},
|
13
13
|
).call
|
14
14
|
}
|
15
15
|
|
@@ -31,7 +31,7 @@ describe Manticore::StubbedResponse do
|
|
31
31
|
|
32
32
|
it "calls on_success handlers" do
|
33
33
|
called = false
|
34
|
-
Manticore::StubbedResponse.stub.on_success {|resp| called = true }.call
|
34
|
+
Manticore::StubbedResponse.stub.on_success { |resp| called = true }.call
|
35
35
|
expect(called).to be true
|
36
36
|
end
|
37
37
|
|
@@ -43,7 +43,7 @@ describe Manticore::StubbedResponse do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it "passes bodies to blocks for streaming reads" do
|
46
|
-
total = ""; subject.body {|chunk| total << chunk }
|
46
|
+
total = ""; subject.body { |chunk| total << chunk }
|
47
47
|
expect(total).to eq("test body")
|
48
48
|
end
|
49
49
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require
|
11
|
-
require
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler/setup"
|
4
|
+
require "simplecov"
|
5
|
+
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter "spec/"
|
8
|
+
end
|
9
|
+
|
10
|
+
require "manticore"
|
11
|
+
require "zlib"
|
12
|
+
require "json"
|
13
|
+
require "rack"
|
14
|
+
require "webrick"
|
15
|
+
require "webrick/https"
|
16
|
+
require "openssl"
|
17
|
+
require "rspec/its"
|
18
|
+
require "logger"
|
12
19
|
|
13
20
|
PORT = 55441
|
14
21
|
|
@@ -16,6 +23,9 @@ def local_server(path = "/", port = PORT)
|
|
16
23
|
URI.join("http://localhost:#{port}", path).to_s
|
17
24
|
end
|
18
25
|
|
26
|
+
Thread.abort_on_exception = true
|
27
|
+
Thread.report_on_exception = false if Thread.respond_to?(:report_on_exception)
|
28
|
+
|
19
29
|
def read_nonblock(socket)
|
20
30
|
buffer = ""
|
21
31
|
loop {
|
@@ -32,8 +42,7 @@ end
|
|
32
42
|
def start_server(port = PORT)
|
33
43
|
@servers ||= {}
|
34
44
|
@servers[port] = Thread.new {
|
35
|
-
Net::HTTP::Server.run(port: port, log:
|
36
|
-
|
45
|
+
Net::HTTP::Server.run(port: port, log: open("/dev/null", "a")) do |request, stream|
|
37
46
|
query = Rack::Utils.parse_query(request[:uri][:query].to_s)
|
38
47
|
if query["sleep"]
|
39
48
|
sleep(query["sleep"].to_f)
|
@@ -43,13 +52,13 @@ def start_server(port = PORT)
|
|
43
52
|
request[:body] = read_nonblock(stream.socket)
|
44
53
|
end
|
45
54
|
|
46
|
-
content_type = request[:headers]["X-Content-Type"] || "
|
55
|
+
content_type = request[:headers]["X-Content-Type"] || "application/json"
|
47
56
|
if request[:uri][:path] == "/auth"
|
48
57
|
if request[:headers]["Authorization"] == "Basic dXNlcjpwYXNz"
|
49
58
|
payload = JSON.dump(request)
|
50
|
-
[200, {
|
59
|
+
[200, {"Content-Type" => content_type, "Content-Length" => payload.length}, [payload]]
|
51
60
|
else
|
52
|
-
[401, {
|
61
|
+
[401, {"WWW-Authenticate" => 'Basic realm="test"'}, [""]]
|
53
62
|
end
|
54
63
|
elsif request[:uri][:path] == "/failearly"
|
55
64
|
# Return an invalid HTTP response
|
@@ -63,26 +72,38 @@ def start_server(port = PORT)
|
|
63
72
|
end
|
64
73
|
elsif request[:uri][:path] == "/proxy"
|
65
74
|
payload = JSON.dump(request.merge(server_port: port))
|
66
|
-
[200, {
|
75
|
+
[200, {"Content-Type" => content_type, "Content-Length" => payload.length}, [payload]]
|
76
|
+
elsif request[:uri][:path] == "/json_utf8"
|
77
|
+
payload = JSON.dump("first_name" => "Mark", "last_name" => "Töger")
|
78
|
+
[200, {"Content-Type" => "application/json", "Content-Length" => payload.length}, [payload]]
|
79
|
+
elsif request[:uri][:path] == "/authproxy"
|
80
|
+
payload = JSON.dump(request.merge(server_port: port))
|
81
|
+
if request[:headers]["Proxy-Authorization"] == "Basic dXNlcjpwYXNz"
|
82
|
+
[200, {"Content-Type" => content_type, "Content-Length" => payload.length}, [payload]]
|
83
|
+
else
|
84
|
+
[407, {"Proxy-Authenticate" => 'Basic realm="localhost'}, [payload]]
|
85
|
+
end
|
67
86
|
elsif request[:uri][:path] == "/keepalive"
|
68
87
|
payload = JSON.dump(request.merge(server_port: port))
|
69
|
-
[200, {
|
88
|
+
[200, {"Content-Type" => content_type, "Content-Length" => payload.length, "Keep-Alive" => "timeout=60"}, [payload]]
|
89
|
+
elsif request[:uri][:path] == "/repeated_headers"
|
90
|
+
payload = JSON.dump(request.merge(server_port: port))
|
91
|
+
[200, {"Link" => ["foo", "bar"]}, [payload]]
|
70
92
|
elsif request[:headers]["X-Redirect"] && request[:uri][:path] != request[:headers]["X-Redirect"]
|
71
|
-
[301, {"Location" => local_server(
|
93
|
+
[301, {"Location" => local_server(request[:headers]["X-Redirect"])}, [""]]
|
72
94
|
else
|
73
95
|
if request[:headers]["Accept-Encoding"] && request[:headers]["Accept-Encoding"].match("gzip")
|
74
|
-
out = StringIO.new(
|
96
|
+
out = StringIO.new("", "w")
|
75
97
|
io = Zlib::GzipWriter.new(out, 2)
|
76
98
|
|
77
99
|
request[:body] = Base64.encode64(request[:body]) if request[:headers]["X-Base64"]
|
78
|
-
|
79
100
|
io.write JSON.dump(request)
|
80
101
|
io.close
|
81
102
|
payload = out.string
|
82
|
-
[200, {
|
103
|
+
[200, {"Content-Type" => content_type, "Content-Encoding" => "gzip", "Content-Length" => payload.length}, [payload]]
|
83
104
|
else
|
84
105
|
payload = JSON.dump(request)
|
85
|
-
[200, {
|
106
|
+
[200, {"Content-Type" => content_type, "Content-Length" => payload.length}, [payload]]
|
86
107
|
end
|
87
108
|
end
|
88
109
|
end
|
@@ -97,9 +118,10 @@ def start_ssl_server(port, options = {})
|
|
97
118
|
cert_name = [
|
98
119
|
%w[CN localhost],
|
99
120
|
]
|
100
|
-
|
121
|
+
cert_file = options[:cert] || File.expand_path("../ssl/host.crt", __FILE__)
|
122
|
+
cert = OpenSSL::X509::Certificate.new File.read(cert_file)
|
101
123
|
cert.version = 0 # HACK: Work around jruby-openssl in jruby-head not setting cert.version
|
102
|
-
pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path(
|
124
|
+
pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path("../ssl/host.key", __FILE__))
|
103
125
|
@servers[port] = Thread.new {
|
104
126
|
server = WEBrick::HTTPServer.new(
|
105
127
|
{
|
@@ -108,7 +130,7 @@ def start_ssl_server(port, options = {})
|
|
108
130
|
:SSLCertificate => cert,
|
109
131
|
:SSLPrivateKey => pkey,
|
110
132
|
:AccessLog => [],
|
111
|
-
:Logger => WEBrick::Log.new("/dev/null")
|
133
|
+
:Logger => WEBrick::Log.new("/dev/null"),
|
112
134
|
}.merge(options)
|
113
135
|
)
|
114
136
|
server.mount_proc "/" do |req, res|
|
@@ -120,7 +142,7 @@ def start_ssl_server(port, options = {})
|
|
120
142
|
end
|
121
143
|
|
122
144
|
RSpec.configure do |c|
|
123
|
-
require
|
145
|
+
require "net/http/server"
|
124
146
|
|
125
147
|
c.before(:suite) {
|
126
148
|
@server = {}
|
@@ -128,9 +150,10 @@ RSpec.configure do |c|
|
|
128
150
|
start_server 55442
|
129
151
|
start_ssl_server 55444
|
130
152
|
start_ssl_server 55445, :SSLVerifyClient => OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, :SSLCACertificateFile => File.expand_path("../ssl/root-ca.crt", __FILE__)
|
153
|
+
start_ssl_server 55446, cert: File.expand_path("../ssl/host-expired.crt", __FILE__)
|
131
154
|
|
132
155
|
Manticore.disable_httpcomponents_logging!
|
133
156
|
}
|
134
157
|
|
135
|
-
c.after(:suite)
|
158
|
+
c.after(:suite) { stop_servers }
|
136
159
|
end
|
metadata
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manticore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Chris Heald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
16
|
+
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '
|
19
|
-
name:
|
18
|
+
version: '0'
|
19
|
+
name: openssl_pkcs8_pure
|
20
|
+
type: :runtime
|
20
21
|
prerelease: false
|
21
|
-
type: :development
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '0'
|
33
|
-
name:
|
34
|
-
prerelease: false
|
33
|
+
name: bundler
|
35
34
|
type: :development
|
35
|
+
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
@@ -44,14 +44,28 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
-
name:
|
48
|
-
prerelease: false
|
47
|
+
name: rake
|
49
48
|
type: :development
|
49
|
+
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.4.1
|
61
|
+
name: jar-dependencies
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.4.1
|
55
69
|
description: Manticore is an HTTP client built on the Apache HttpCore components
|
56
70
|
email:
|
57
71
|
- cheald@mashable.com
|
@@ -60,6 +74,7 @@ extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
76
|
- ".gitignore"
|
77
|
+
- ".gitlab-ci.yml"
|
63
78
|
- ".travis.yml"
|
64
79
|
- APACHE-LICENSE-2.0.txt
|
65
80
|
- CHANGELOG.md
|
@@ -121,8 +136,7 @@ requirements:
|
|
121
136
|
- jar commons-logging:commons-logging, '~> 1.2'
|
122
137
|
- jar commons-codec:commons-codec, '~> 1.9'
|
123
138
|
- jar org.apache.httpcomponents:httpcore, '~> 4.4.4'
|
124
|
-
|
125
|
-
rubygems_version: 2.4.8
|
139
|
+
rubygems_version: 3.0.6
|
126
140
|
signing_key:
|
127
141
|
specification_version: 4
|
128
142
|
summary: Manticore is an HTTP client built on the Apache HttpCore components
|