summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/t/00unit.mruby
diff options
context:
space:
mode:
Diffstat (limited to 'web/server/h2o/libh2o/t/00unit.mruby')
-rw-r--r--web/server/h2o/libh2o/t/00unit.mruby/acl.rb179
-rw-r--r--web/server/h2o/libh2o/t/00unit.mruby/trie_addr.rb64
2 files changed, 243 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/t/00unit.mruby/acl.rb b/web/server/h2o/libh2o/t/00unit.mruby/acl.rb
new file mode 100644
index 00000000..771047da
--- /dev/null
+++ b/web/server/h2o/libh2o/t/00unit.mruby/acl.rb
@@ -0,0 +1,179 @@
+$LOAD_PATH << 'share/h2o/mruby'
+require 'misc/mruby-mtest/mrblib/mtest_unit.rb'
+require 'acl.rb'
+
+class ACLTest < MTest::Unit::TestCase
+ include H2O::ACL
+ def setup
+ H2O::ConfigurationContext.reset
+ end
+
+ def test_use
+ act = acl {
+ use proc {|env| [200, {}, ["hello test_use"]]}
+ }.call({})
+ assert_equal([200, {}, ["hello test_use"]], act)
+ end
+
+ def test_respond
+ act = acl {
+ respond(409, {"custom" => "header"}, ["Conflict"])
+ }.call({})
+ assert_equal([409, {"custom" => "header"}, ["Conflict"]], act)
+ end
+
+ def test_deny
+ act = acl {
+ deny
+ }.call({})
+ assert_equal([403, {}, ["Forbidden"]], act)
+ end
+
+ def test_allow
+ act = acl {
+ allow
+ }.call({})
+ assert_equal([399, {}, []], act)
+ end
+
+ def test_redirect
+ act = acl {
+ redirect("https://h2o.examp1e.net/", 301)
+ }.call({})
+ assert_equal([301, {"Location" => "https://h2o.examp1e.net/"}, []], act)
+ end
+
+ ##### tests for condition block
+
+ def test_conditional_true
+ act = acl {
+ respond(200) { true }
+ }.call({})
+ assert_equal([200, {}, []], act)
+ end
+
+ def test_conditional_false
+ act = acl {
+ respond(200) { false }
+ }.call({})
+ assert_equal([399, {}, []], act)
+ end
+
+ ##### tests for acl block
+
+ def test_empty
+ act = acl {
+ }.call({})[0]
+ assert_equal(399, act)
+ end
+
+ def test_multiple1
+ act = acl {
+ respond(201) { true }
+ respond(202) { true }
+ }.call({})[0]
+ assert_equal(201, act)
+ end
+
+ def test_multiple2
+ act = acl {
+ respond(201) { false }
+ respond(202) { true }
+ }.call({})[0]
+ assert_equal(202, act)
+ end
+
+ def test_multiple3
+ act = acl {
+ respond(201) { false }
+ respond(202) { false }
+ }.call({})[0]
+ assert_equal(399, act)
+ end
+
+ def test_acl_restriction1
+ acl { respond(200) }
+ assert_raise(RuntimeError, "must raise exception if acl method is called more than once") {
+ acl { respond(200) }
+ }
+ end
+
+ ##### tests for matcher
+
+ def test_addr
+ handler = acl {
+ respond(200) { addr.match(/^192\.168\./) }
+ respond(403) { addr.match(/^200\./) }
+ respond(503) { addr.match(/^201\./) }
+ }
+ assert_equal(200, handler.call({ "REMOTE_ADDR" => "192.168.0.1"})[0])
+ assert_equal(403, handler.call({ "REMOTE_ADDR" => "200.0.0.1"})[0])
+ assert_equal(503, handler.call({ "REMOTE_ADDR" => "201.0.0.1"})[0])
+ assert_equal(399, handler.call({ "REMOTE_ADDR" => "127.0.0.1"})[0])
+ assert_equal(200, handler.call({ "HTTP_X_FORWARDED_FOR" => "192.168.0.1"})[0])
+ end
+
+ def test_addr_not_forwarded
+ handler = acl {
+ respond(200) { addr(false).match(/^192\.168\./) }
+ respond(403)
+ }
+ assert_equal(200, handler.call({ "REMOTE_ADDR" => "192.168.0.1"})[0])
+ assert_equal(403, handler.call({ "HTTP_X_FORWARDED_FOR" => "192.168.0.1"})[0])
+ end
+
+ def test_path
+ handler = acl {
+ respond(200) { path == "/foo" }
+ respond(404)
+ }
+ assert_equal(200, handler.call({ "PATH_INFO" => "/foo"})[0])
+ assert_equal(404, handler.call({ "PATH_INFO" => "/bar"})[0])
+ end
+
+ def test_method
+ handler = acl {
+ allow { method.match(/^(GET|HEAD)$/) }
+ respond(405)
+ }
+ assert_equal(399, handler.call({ "REQUEST_METHOD" => "GET"})[0])
+ assert_equal(405, handler.call({ "REQUEST_METHOD" => "POST"})[0])
+ end
+
+ def test_method
+ handler = acl {
+ allow { method.match(/^(GET|HEAD)$/) }
+ respond(405)
+ }
+ assert_equal(399, handler.call({ "REQUEST_METHOD" => "GET"})[0])
+ assert_equal(405, handler.call({ "REQUEST_METHOD" => "POST"})[0])
+ end
+
+ def test_header
+ handler = acl {
+ respond(400, {}, ["authorization header missing"]) { header("Authorization").empty? }
+ }
+ assert_equal(400, handler.call({})[0])
+ assert_equal(399, handler.call({ "HTTP_AUTHORIZATION" => "Bearer xyz"})[0])
+ end
+
+ def test_user_agent
+ handler = acl {
+ respond(200, {}, ["hello googlebot!"]) { user_agent.match(/Googlebot/i) }
+ }
+ assert_equal(200, handler.call({ "HTTP_USER_AGENT" => "i'm Googlebot"})[0])
+ assert_equal(399, handler.call({})[0])
+ end
+
+ def test_multiple_matchers
+ handler = acl {
+ respond(403, {}, []) { ! addr.start_with?("192.168.") && user_agent.match(/curl/i) }
+ }
+ assert_equal(399, handler.call({ "REMOTE_ADDR" => "192.168.100.100", "HTTP_USER_AGENT" => "i'm firefox"})[0])
+ assert_equal(399, handler.call({ "REMOTE_ADDR" => "192.168.100.100", "HTTP_USER_AGENT" => "i'm curl"})[0])
+ assert_equal(399, handler.call({ "REMOTE_ADDR" => "222.222.222.222", "HTTP_USER_AGENT" => "i'm firefox"})[0])
+ assert_equal(403, handler.call({ "REMOTE_ADDR" => "222.222.222.222", "HTTP_USER_AGENT" => "i'm curl"})[0])
+ end
+end
+
+MTest::Unit.new.run
diff --git a/web/server/h2o/libh2o/t/00unit.mruby/trie_addr.rb b/web/server/h2o/libh2o/t/00unit.mruby/trie_addr.rb
new file mode 100644
index 00000000..9b6936d3
--- /dev/null
+++ b/web/server/h2o/libh2o/t/00unit.mruby/trie_addr.rb
@@ -0,0 +1,64 @@
+$LOAD_PATH << 'share/h2o/mruby'
+require 'misc/mruby-mtest/mrblib/mtest_unit.rb'
+require 'trie_addr.rb'
+
+class TrieAddrTest < MTest::Unit::TestCase
+ def test_basic
+ addr = TrieAddr.new
+ addr.add("10.0.0.0/12")
+ addr.add("10.255.0.0/12")
+
+ assert_true(addr.match?("10.10.0.0"))
+ assert_false(addr.match?("10.128.0.0"))
+ assert_true(addr.match?("10.250.0.0"))
+
+ addr.add("10.255.0.0/8")
+ assert_true(addr.match?("10.128.0.0"))
+
+ end
+
+ def test_missing_prefix_length
+ addr = TrieAddr.new
+ addr.add("12.34.56.78")
+
+ assert_false(addr.match?("12.34.56.77"))
+ assert_true(addr.match?("12.34.56.78"))
+ assert_false(addr.match?("12.34.56.79"))
+ end
+
+ def test_ipv6_addr
+ addr = TrieAddr.new
+ assert_raise(ArgumentError, "ipv6 is currently not supported") { addr.add("::1") }
+ assert_false(addr.match?("::1"), "always returns false")
+ end
+
+ def test_invalid_addr
+ addr = TrieAddr.new
+ addr.add("0.0.0.0/8")
+ assert_false(addr.match?("hogehoge"))
+ end
+
+ # taken from https://github.com/hirose31/p5-net-ip-match?-trie/blob/master/t/10_match?_ip_PP.t
+ def test_nimt_cases
+ addr = TrieAddr.new
+ addr.add(["10.0.0.0/24", "10.0.1.0/24", "11.0.0.0/16", "10.1.0.0/28", "10.0.0.0/8", "10.2.0.0/24"])
+
+ cases = [
+ { :name => "match 1", :input => "10.0.0.100", :expected => true },
+ { :name => "match 2", :input => "10.1.0.8", :expected => true },
+ { :name => "match 3", :input => "10.2.0.1", :expected => true },
+ { :name => "not match", :input => "192.168.1.2", :expected => false },
+ { :name => "match min", :input => "10.0.0.0", :expected => true },
+ { :name => "match max", :input => "10.0.0.255", :expected => true },
+ { :name => "invalid IP", :input => "11.0.999.1", :expected => false },
+ { :name => "0.0.0.0", :input => "0.0.0.0", :expected => false },
+ { :name => "255.255.255.255", :input => "255.255.255.255", :expected => false },
+ { :name => "big", :input => "10.255.255.255", :expected => true },
+ ]
+ cases.each {|c|
+ assert_equal(c[:expected], addr.match?(c[:input]), c[:name])
+ }
+ end
+end
+
+MTest::Unit.new.run