manticore 0.6.0-java → 0.7.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|