2019-06-11 22:24:35 +00:00
|
|
|
require "helper"
|
|
|
|
require "inspec/resource"
|
|
|
|
require "inspec/resources/http"
|
2019-05-03 22:01:06 +00:00
|
|
|
require "faraday_middleware/response/follow_redirects"
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "Inspec::Resources::Http" do
|
|
|
|
describe "InSpec::Resources::Http::Worker::Local" do
|
|
|
|
let(:domain) { "www.example.com" }
|
|
|
|
let(:http_method) { "GET" }
|
2017-10-04 20:44:09 +00:00
|
|
|
let(:opts) { {} }
|
|
|
|
let(:worker) { Inspec::Resources::Http::Worker::Local.new(http_method, "http://#{domain}", opts) }
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "simple HTTP request with no options" do
|
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:get, domain).to_return(status: 200, body: "pong")
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "pong"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "request with basic auth" do
|
|
|
|
let(:opts) { { auth: { user: "user", pass: "pass" } } }
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:get, domain).with(basic_auth: %w{user pass}).to_return(status: 200, body: "auth ok")
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "auth ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "request with redirect enabled" do
|
2018-10-13 06:14:17 +00:00
|
|
|
let(:opts) { { max_redirects: 1 } }
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "follows the redirect" do
|
|
|
|
stub_request(:get, domain).to_return(status: 302, headers: { location: "http://example.com" } )
|
|
|
|
stub_request(:get, "example.com").to_return(status: 200, body: "redirect ok")
|
2018-10-13 06:14:17 +00:00
|
|
|
|
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "redirect ok"
|
2018-10-13 06:14:17 +00:00
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "does not exceed max_redirects" do
|
|
|
|
stub_request(:get, domain).to_return(status: 302, headers: { location: "http://redirect1.com" } )
|
|
|
|
stub_request(:get, "redirect1.com").to_return(status: 302, headers: { location: "http://redirect2.com" } )
|
|
|
|
stub_request(:get, "redirect2.com").to_return(status: 200, body: "should not get here")
|
2018-10-13 06:14:17 +00:00
|
|
|
|
2019-09-30 22:31:55 +00:00
|
|
|
_(proc { worker.status }).must_raise FaradayMiddleware::RedirectLimitReached
|
2018-10-13 06:14:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "POST request with data" do
|
|
|
|
let(:http_method) { "POST" }
|
|
|
|
let(:opts) { { data: { a: "1", b: "five" } } }
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:post, domain).with(body: { a: "1", b: "five" }).to_return(status: 200, body: "post ok")
|
2017-10-04 20:44:09 +00:00
|
|
|
|
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "post ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "with request headers" do
|
|
|
|
let(:opts) { { headers: { "accept" => "application/json" } } }
|
2017-10-04 20:44:09 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:get, domain).with(headers: { "accept" => "application/json" }).to_return(status: 200, body: "headers ok", headers: { "mock" => "ok" })
|
2017-10-04 20:44:09 +00:00
|
|
|
|
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "headers ok"
|
|
|
|
_(worker.response_headers["mock"]).must_equal "ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "with params" do
|
|
|
|
let(:opts) { { params: { a: "b" } } }
|
2017-01-05 19:29:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:get, domain).with(query: { a: "b" }).to_return(status: 200, body: "params ok")
|
2017-10-04 20:44:09 +00:00
|
|
|
|
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "params ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
2018-02-27 17:59:53 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "an OPTIONS request" do
|
|
|
|
let(:http_method) { "OPTIONS" }
|
|
|
|
let(:opts) do
|
|
|
|
{ headers: { "Access-Control-Request-Method" => "GET",
|
|
|
|
"Access-Control-Request-Headers" => "origin, x-requested-with",
|
2019-07-09 00:20:30 +00:00
|
|
|
"Origin" => "http://www.example.com" } }
|
|
|
|
end
|
2018-02-27 17:59:53 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
|
|
|
stub_request(:options, "http://www.example.com/")
|
|
|
|
.with(headers: { "Access-Control-Request-Headers" => "origin, x-requested-with", "Access-Control-Request-Method" => "GET", "Origin" => "http://www.example.com" })
|
|
|
|
.to_return(status: 200, body: "", headers: { "mock" => "ok", "Access-Control-Allow-Origin" => "http://www.example.com", "Access-Control-Allow-Methods" => "POST, GET, OPTIONS, DELETE", "Access-Control-Max-Age" => "86400" })
|
2018-02-27 17:59:53 +00:00
|
|
|
|
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.response_headers["mock"]).must_equal "ok"
|
|
|
|
_(worker.response_headers["access-control-allow-origin"]).must_equal "http://www.example.com"
|
|
|
|
_(worker.response_headers["access-control-allow-methods"]).must_equal "POST, GET, OPTIONS, DELETE"
|
|
|
|
_(worker.response_headers["access-control-max-age"]).must_equal "86400"
|
2018-02-27 17:59:53 +00:00
|
|
|
end
|
|
|
|
end
|
2017-01-05 19:29:11 +00:00
|
|
|
end
|
2017-05-19 15:23:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "Inspec::Resource::Http::Worker::Remote" do
|
2017-10-04 20:44:09 +00:00
|
|
|
let(:backend) { MockLoader.new.backend }
|
2019-06-11 22:24:35 +00:00
|
|
|
let(:http_method) { "GET" }
|
|
|
|
let(:url) { "http://www.example.com" }
|
2017-10-04 20:44:09 +00:00
|
|
|
let(:opts) { {} }
|
2019-06-11 22:24:35 +00:00
|
|
|
let(:worker) { Inspec::Resources::Http::Worker::Remote.new(backend, http_method, url, opts) }
|
2017-10-04 20:44:09 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "simple HTTP request with no options" do
|
|
|
|
it "returns correct data" do
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "no options"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "request with basic auth" do
|
|
|
|
let(:opts) { { auth: { user: "user", pass: "pass" } } }
|
2017-10-04 20:44:09 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "auth ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "request with redirect enabled" do
|
2018-10-13 06:14:17 +00:00
|
|
|
let(:opts) { { max_redirects: 1 } }
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "follows the redirect" do
|
2018-10-13 06:14:17 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "followed redirect"
|
2018-10-13 06:14:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "POST request with data" do
|
|
|
|
let(:http_method) { "POST" }
|
|
|
|
let(:opts) { { data: { a: "1", b: "five" } } }
|
2017-10-04 20:44:09 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "post ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "with request headers" do
|
|
|
|
let(:opts) { { headers: { "accept" => "application/json", "foo" => "bar" } } }
|
2017-05-19 15:23:11 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2017-10-04 20:44:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "headers ok"
|
|
|
|
_(worker.response_headers["mock"]).must_equal "ok"
|
2017-10-04 20:44:09 +00:00
|
|
|
end
|
|
|
|
end
|
2017-11-16 17:16:23 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "with params" do
|
|
|
|
let(:opts) { { params: { a: "b", c: "d" } } }
|
2017-11-16 17:16:23 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2017-11-16 17:16:23 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.body).must_equal "params ok"
|
2017-11-16 17:16:23 +00:00
|
|
|
end
|
|
|
|
end
|
2017-11-27 17:17:39 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "a HEAD request" do
|
|
|
|
let(:http_method) { "HEAD" }
|
2017-11-27 17:17:39 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2017-11-27 17:17:39 +00:00
|
|
|
_(worker.status).must_equal 301
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.response_headers["Location"]).must_equal "http://www.google.com/"
|
2017-11-27 17:17:39 +00:00
|
|
|
end
|
|
|
|
end
|
2018-02-27 17:59:53 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "an OPTIONS request" do
|
|
|
|
let(:http_method) { "OPTIONS" }
|
|
|
|
let(:opts) do
|
|
|
|
{ headers: { "Access-Control-Request-Method" => "GET",
|
|
|
|
"Access-Control-Request-Headers" => "origin, x-requested-with",
|
2019-07-09 00:20:30 +00:00
|
|
|
"Origin" => "http://www.example.com" } }
|
|
|
|
end
|
2018-02-27 17:59:53 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns correct data" do
|
2018-02-27 17:59:53 +00:00
|
|
|
_(worker.status).must_equal 200
|
2019-06-11 22:24:35 +00:00
|
|
|
_(worker.response_headers["Access-Control-Allow-Origin"]).must_equal "http://www.example.com"
|
|
|
|
_(worker.response_headers["Access-Control-Allow-Methods"]).must_equal "POST, GET, OPTIONS, DELETE"
|
|
|
|
_(worker.response_headers["Access-Control-Max-Age"]).must_equal "86400"
|
2018-02-27 17:59:53 +00:00
|
|
|
end
|
|
|
|
end
|
2018-03-08 04:04:26 +00:00
|
|
|
|
2020-07-19 21:54:16 +00:00
|
|
|
describe "run_http request" do
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns nil when nil is returned" do
|
2018-03-08 04:04:26 +00:00
|
|
|
Inspec::Resources::Cmd.any_instance
|
2019-07-09 00:20:30 +00:00
|
|
|
.stubs(:stdout)
|
|
|
|
.returns(nil)
|
2020-07-19 21:54:16 +00:00
|
|
|
_(worker.send(:run_http)).must_be_nil
|
2018-03-08 04:04:26 +00:00
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns nil when failure is returned" do
|
2018-03-08 04:04:26 +00:00
|
|
|
Inspec::Resources::Cmd.any_instance
|
2019-07-09 00:20:30 +00:00
|
|
|
.stubs(:exit_status)
|
|
|
|
.returns(1)
|
2020-07-19 21:54:16 +00:00
|
|
|
_(worker.send(:run_http)).must_be_nil
|
2018-03-08 04:04:26 +00:00
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns html when html is returned" do
|
2018-03-08 04:04:26 +00:00
|
|
|
Inspec::Resources::Cmd.any_instance
|
2019-07-09 00:20:30 +00:00
|
|
|
.stubs(:stdout)
|
|
|
|
.returns("HTTP/1.1 200 OK\nDate: Tue, 03 Oct 2017 20:30:08 GMT\nExpires: -1\nCache-Control: private")
|
2018-03-08 04:04:26 +00:00
|
|
|
assert = ["Date: Tue, 03 Oct 2017 20:30:08 GMT", "Expires: -1", "Cache-Control: private"]
|
2020-07-19 21:54:16 +00:00
|
|
|
_(worker.send(:run_http)).must_equal assert
|
2018-03-08 04:04:26 +00:00
|
|
|
end
|
|
|
|
end
|
2017-05-19 15:23:11 +00:00
|
|
|
end
|
2018-01-16 22:30:35 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
describe "Inspec::Resource::Http::Headers" do
|
|
|
|
let(:headers) { Inspec::Resources::Http::Headers.create(a: 1, B: 2, "c" => 3, "D" => 4) }
|
2018-01-16 22:30:35 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns the correct data via hash syntax ensuring case-insensitive keys" do
|
2019-09-30 22:31:55 +00:00
|
|
|
_(headers["a"]).must_equal(1)
|
|
|
|
_(headers["A"]).must_equal(1)
|
|
|
|
_(headers["b"]).must_equal(2)
|
|
|
|
_(headers["B"]).must_equal(2)
|
|
|
|
_(headers["c"]).must_equal(3)
|
|
|
|
_(headers["C"]).must_equal(3)
|
|
|
|
_(headers["d"]).must_equal(4)
|
|
|
|
_(headers["D"]).must_equal(4)
|
2018-01-16 22:30:35 +00:00
|
|
|
end
|
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
it "returns the correct data via method syntax ensuring case-insensitive keys" do
|
2019-09-30 22:31:55 +00:00
|
|
|
_(headers.a).must_equal(1)
|
|
|
|
_(headers.A).must_equal(1)
|
|
|
|
_(headers.b).must_equal(2)
|
|
|
|
_(headers.B).must_equal(2)
|
|
|
|
_(headers.c).must_equal(3)
|
|
|
|
_(headers.C).must_equal(3)
|
|
|
|
_(headers.d).must_equal(4)
|
|
|
|
_(headers.D).must_equal(4)
|
2018-01-16 22:30:35 +00:00
|
|
|
end
|
|
|
|
end
|
2020-10-16 18:01:38 +00:00
|
|
|
|
2021-03-10 05:42:50 +00:00
|
|
|
describe "Windows-Simple" do
|
2021-03-08 07:58:50 +00:00
|
|
|
let(:backend) { MockLoader.new(:windows).backend }
|
2020-10-19 05:24:09 +00:00
|
|
|
let(:http_method) { "GET" }
|
2021-03-08 07:58:50 +00:00
|
|
|
let(:url) { "https://www.example.com" }
|
2020-10-19 05:24:09 +00:00
|
|
|
let(:opts) { {} }
|
|
|
|
let(:worker) { Inspec::Resources::Http::Worker::Remote.new(backend, http_method, url, opts) }
|
|
|
|
|
|
|
|
describe "simple HTTP request with no options" do
|
|
|
|
it "returns correct data" do
|
2021-03-08 07:58:50 +00:00
|
|
|
Inspec::Resources::Cmd.any_instance
|
|
|
|
.stubs(:exist?)
|
|
|
|
.returns(true)
|
2020-10-19 05:24:09 +00:00
|
|
|
_(worker.status).must_equal 200
|
2021-03-08 15:02:11 +00:00
|
|
|
_(worker.response_headers["Content-Type"]).must_equal "text/html; charset=UTF-8"
|
2020-10-19 05:24:09 +00:00
|
|
|
end
|
2020-10-16 18:01:38 +00:00
|
|
|
end
|
|
|
|
end
|
2021-03-10 05:42:50 +00:00
|
|
|
|
|
|
|
describe "Windows-Head" do
|
|
|
|
let(:backend) { MockLoader.new(:windows).backend }
|
|
|
|
let(:http_method) { "HEAD" }
|
|
|
|
let(:url) { "https://www.example.com" }
|
|
|
|
let(:opts) { {} }
|
|
|
|
let(:worker) { Inspec::Resources::Http::Worker::Remote.new(backend, http_method, url, opts) }
|
|
|
|
|
|
|
|
describe "simple Head request" do
|
|
|
|
it "returns correct data" do
|
|
|
|
Inspec::Resources::Cmd.any_instance
|
|
|
|
.stubs(:exist?)
|
|
|
|
.returns(true)
|
|
|
|
_(worker.status).must_equal 200
|
|
|
|
_(worker.response_headers["Content-Type"]).must_equal "text/html; charset=UTF-8"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-10-13 12:56:38 +00:00
|
|
|
|
|
|
|
describe "POST request with data" do
|
|
|
|
let(:backend) { MockLoader.new(:windows).backend }
|
|
|
|
let(:http_method) { "POST" }
|
|
|
|
let(:url) { "https://www.example.com" }
|
|
|
|
let(:opts) { { data: '{ "a" : "1", "b" : "five" }' } }
|
|
|
|
let(:worker) { Inspec::Resources::Http::Worker::Remote.new(backend, http_method, url, opts) }
|
|
|
|
|
|
|
|
it "returns correct data" do
|
|
|
|
Inspec::Resources::Cmd.any_instance
|
2021-10-13 13:57:29 +00:00
|
|
|
.stubs(:exist?)
|
|
|
|
.returns(true)
|
2021-10-13 12:56:38 +00:00
|
|
|
_(worker.status).must_equal 200
|
|
|
|
_(worker.body).must_equal "post ok"
|
|
|
|
_(worker.response_headers["Content-Type"]).must_equal "text/html; charset=UTF-8"
|
|
|
|
end
|
|
|
|
end
|
2017-01-05 19:29:11 +00:00
|
|
|
end
|