varnishtest "normalize-uri tests" #REQUIRE_VERSION=2.4 # This reg-test tests the http-request normalize-uri action. feature ignore_unknown_macro server s1 { rxreq txresp -hdr "connection: close" } -repeat 70 -start haproxy h1 -conf { global # WT: limit false-positives causing "HTTP header incomplete" due to # idle server connections being randomly used and randomly expiring # under us. tune.idle-pool.shared off expose-experimental-directives defaults mode http timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" timeout client "${HAPROXY_TEST_TIMEOUT-5s}" timeout server "${HAPROXY_TEST_TIMEOUT-5s}" frontend fe_path_merge_slashes bind "fd@${fe_path_merge_slashes}" http-request set-var(txn.before) url http-request normalize-uri path-merge-slashes http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_path_strip_dotdot bind "fd@${fe_path_strip_dotdot}" http-request set-var(txn.before) url http-request normalize-uri path-strip-dotdot http-request set-var(txn.after) url http-request set-uri %[var(txn.before)] http-request normalize-uri path-strip-dotdot full http-request set-var(txn.after_full) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] http-response add-header after-full %[var(txn.after_full)] default_backend be frontend fe_sort_query_by_name bind "fd@${fe_sort_query_by_name}" http-request set-var(txn.before) url http-request normalize-uri query-sort-by-name http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_percent_to_uppercase bind "fd@${fe_percent_to_uppercase}" http-request set-var(txn.before) url http-request normalize-uri percent-to-uppercase http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_percent_to_uppercase_strict bind "fd@${fe_percent_to_uppercase_strict}" http-request set-var(txn.before) url http-request normalize-uri percent-to-uppercase strict http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_dot bind "fd@${fe_dot}" http-request set-var(txn.before) url http-request normalize-uri path-strip-dot http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_percent_decode_unreserved bind "fd@${fe_percent_decode_unreserved}" http-request set-var(txn.before) url http-request normalize-uri percent-decode-unreserved http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_percent_decode_unreserved_strict bind "fd@${fe_percent_decode_unreserved_strict}" http-request set-var(txn.before) url http-request normalize-uri percent-decode-unreserved strict http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_fragment_strip bind "fd@${fe_fragment_strip}" option accept-invalid-http-request http-request set-var(txn.before) url http-request normalize-uri fragment-strip http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_fragment_encode bind "fd@${fe_fragment_encode}" option accept-invalid-http-request http-request set-var(txn.before) url http-request normalize-uri fragment-encode http-request set-var(txn.after) url http-response add-header before %[var(txn.before)] http-response add-header after %[var(txn.after)] default_backend be frontend fe_fragment_block bind "fd@${fe_fragment_block}" http-request normalize-uri fragment-strip default_backend be backend be server s1 ${s1_addr}:${s1_port} } -start client c1 -connect ${h1_fe_path_merge_slashes_sock} { txreq -url "/foo/bar" rxresp expect resp.http.before == "/foo/bar" expect resp.http.after == "/foo/bar" txreq -url "/foo//bar" rxresp expect resp.http.before == "/foo//bar" expect resp.http.after == "/foo/bar" txreq -url "/foo///bar" rxresp expect resp.http.before == "/foo///bar" expect resp.http.after == "/foo/bar" txreq -url "///foo///bar" rxresp expect resp.http.before == "///foo///bar" expect resp.http.after == "/foo/bar" txreq -url "///foo/bar" rxresp expect resp.http.before == "///foo/bar" expect resp.http.after == "/foo/bar" txreq -url "///foo///bar///" rxresp expect resp.http.before == "///foo///bar///" expect resp.http.after == "/foo/bar/" txreq -url "///" rxresp expect resp.http.before == "///" expect resp.http.after == "/" txreq -url "/foo?bar=///" rxresp expect resp.http.before == "/foo?bar=///" expect resp.http.after == "/foo?bar=///" txreq -url "//foo?bar=///" rxresp expect resp.http.before == "//foo?bar=///" expect resp.http.after == "/foo?bar=///" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c2 -connect ${h1_fe_path_strip_dotdot_sock} { txreq -url "/foo/bar" rxresp expect resp.http.before == "/foo/bar" expect resp.http.after == "/foo/bar" expect resp.http.after-full == "/foo/bar" txreq -url "/foo/.." rxresp expect resp.http.before == "/foo/.." expect resp.http.after == "/" expect resp.http.after-full == "/" txreq -url "/foo/../" rxresp expect resp.http.before == "/foo/../" expect resp.http.after == "/" expect resp.http.after-full == "/" txreq -url "/foo/bar/../" rxresp expect resp.http.before == "/foo/bar/../" expect resp.http.after == "/foo/" expect resp.http.after-full == "/foo/" txreq -url "/foo/../bar" rxresp expect resp.http.before == "/foo/../bar" expect resp.http.after == "/bar" expect resp.http.after-full == "/bar" txreq -url "/foo/../bar/" rxresp expect resp.http.before == "/foo/../bar/" expect resp.http.after == "/bar/" expect resp.http.after-full == "/bar/" txreq -url "/foo/../../bar/" rxresp expect resp.http.before == "/foo/../../bar/" expect resp.http.after == "/../bar/" expect resp.http.after-full == "/bar/" txreq -url "/foo//../../bar/" rxresp expect resp.http.before == "/foo//../../bar/" expect resp.http.after == "/bar/" expect resp.http.after-full == "/bar/" txreq -url "/foo/?bar=/foo/../" rxresp expect resp.http.before == "/foo/?bar=/foo/../" expect resp.http.after == "/foo/?bar=/foo/../" expect resp.http.after-full == "/foo/?bar=/foo/../" txreq -url "/foo/../?bar=/foo/../" rxresp expect resp.http.before == "/foo/../?bar=/foo/../" expect resp.http.after == "/?bar=/foo/../" expect resp.http.after-full == "/?bar=/foo/../" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" expect resp.http.after-full == "*" } -run client c3 -connect ${h1_fe_sort_query_by_name_sock} { txreq -url "/?a=a" rxresp expect resp.http.before == "/?a=a" expect resp.http.after == "/?a=a" txreq -url "/?a=a&z=z" rxresp expect resp.http.before == "/?a=a&z=z" expect resp.http.after == "/?a=a&z=z" txreq -url "/?z=z&a=a" rxresp expect resp.http.before == "/?z=z&a=a" expect resp.http.after == "/?a=a&z=z" txreq -url "/?a=z&z=a" rxresp expect resp.http.before == "/?a=z&z=a" expect resp.http.after == "/?a=z&z=a" txreq -url "/?z=a&a=z" rxresp expect resp.http.before == "/?z=a&a=z" expect resp.http.after == "/?a=z&z=a" txreq -url "/?c&b&a&z&x&y" rxresp expect resp.http.before == "/?c&b&a&z&x&y" expect resp.http.after == "/?a&b&c&x&y&z" txreq -url "/?a=&aa=&aaa=&aaaa=" rxresp expect resp.http.before == "/?a=&aa=&aaa=&aaaa=" expect resp.http.after == "/?a=&aa=&aaa=&aaaa=" txreq -url "/?aaaa=&a=&aa=&aaa=" rxresp expect resp.http.before == "/?aaaa=&a=&aa=&aaa=" expect resp.http.after == "/?a=&aa=&aaa=&aaaa=" txreq -url "/?a=5&a=3&a=1&a=2&a=4" rxresp expect resp.http.before == "/?a=5&a=3&a=1&a=2&a=4" expect resp.http.after == "/?a=5&a=3&a=1&a=2&a=4" txreq -url "/?a=5&b=3&a=1&a=2&b=4" rxresp expect resp.http.before == "/?a=5&b=3&a=1&a=2&b=4" expect resp.http.after == "/?a=5&a=1&a=2&b=3&b=4" txreq -url "/" rxresp expect resp.http.before == "/" expect resp.http.after == "/" txreq -url "/?" rxresp expect resp.http.before == "/?" expect resp.http.after == "/?" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c4 -connect ${h1_fe_percent_to_uppercase_sock} { txreq -url "/a?a=a" rxresp expect resp.http.before == "/a?a=a" expect resp.http.after == "/a?a=a" txreq -url "/%aa?a=%aa" rxresp expect resp.http.before == "/%aa?a=%aa" expect resp.http.after == "/%AA?a=%AA" txreq -url "/%zz?a=%zz" rxresp expect resp.status == 200 expect resp.http.before == "/%zz?a=%zz" expect resp.http.after == "/%zz?a=%zz" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c5 -connect ${h1_fe_percent_to_uppercase_strict_sock} { txreq -url "/a?a=a" rxresp expect resp.http.before == "/a?a=a" expect resp.http.after == "/a?a=a" txreq -url "/%aa?a=%aa" rxresp expect resp.http.before == "/%aa?a=%aa" expect resp.http.after == "/%AA?a=%AA" txreq -url "/%zz?a=%zz" rxresp expect resp.status == 400 } -run client c6 -connect ${h1_fe_dot_sock} { txreq -url "/" rxresp expect resp.http.before == "/" expect resp.http.after == "/" txreq -url "/a/b" rxresp expect resp.http.before == "/a/b" expect resp.http.after == "/a/b" txreq -url "/." rxresp expect resp.http.before == "/." expect resp.http.after == "/" txreq -url "/./" rxresp expect resp.http.before == "/./" expect resp.http.after == "/" txreq -url "/a/." rxresp expect resp.http.before == "/a/." expect resp.http.after == "/a/" txreq -url "/a." rxresp expect resp.http.before == "/a." expect resp.http.after == "/a." txreq -url "/.a" rxresp expect resp.http.before == "/.a" expect resp.http.after == "/.a" txreq -url "/a/." rxresp expect resp.http.before == "/a/." expect resp.http.after == "/a/" txreq -url "/a/./" rxresp expect resp.http.before == "/a/./" expect resp.http.after == "/a/" txreq -url "/a/./a" rxresp expect resp.http.before == "/a/./a" expect resp.http.after == "/a/a" txreq -url "/a/../" rxresp expect resp.http.before == "/a/../" expect resp.http.after == "/a/../" txreq -url "/a/../a" rxresp expect resp.http.before == "/a/../a" expect resp.http.after == "/a/../a" txreq -url "/?a=/./" rxresp expect resp.http.before == "/?a=/./" expect resp.http.after == "/?a=/./" } -run client c7 -connect ${h1_fe_percent_decode_unreserved_sock} { txreq -url "/a?a=a" rxresp expect resp.http.before == "/a?a=a" expect resp.http.after == "/a?a=a" txreq -url "/%61?%61=%61" rxresp expect resp.http.before == "/%61?%61=%61" expect resp.http.after == "/a?a=a" txreq -url "/%3F?foo=bar" rxresp expect resp.http.before == "/%3F?foo=bar" expect resp.http.after == "/%3F?foo=bar" txreq -url "/%%36%36" rxresp expect resp.status == 200 expect resp.http.before == "/%%36%36" expect resp.http.after == "/%66" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c8 -connect ${h1_fe_percent_decode_unreserved_strict_sock} { txreq -url "/a?a=a" rxresp expect resp.http.before == "/a?a=a" expect resp.http.after == "/a?a=a" txreq -url "/%61?%61=%61" rxresp expect resp.http.before == "/%61?%61=%61" expect resp.http.after == "/a?a=a" txreq -url "/%3F?foo=bar" rxresp expect resp.http.before == "/%3F?foo=bar" expect resp.http.after == "/%3F?foo=bar" txreq -url "/%%36%36" rxresp expect resp.status == 400 } -run client c9 -connect ${h1_fe_fragment_strip_sock} { txreq -url "/#foo" rxresp expect resp.http.before == "/#foo" expect resp.http.after == "/" txreq -url "/%23foo" rxresp expect resp.http.before == "/%23foo" expect resp.http.after == "/%23foo" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c10 -connect ${h1_fe_fragment_encode_sock} { txreq -url "/#foo" rxresp expect resp.http.before == "/#foo" expect resp.http.after == "/%23foo" txreq -url "/#foo/#foo" rxresp expect resp.http.before == "/#foo/#foo" expect resp.http.after == "/%23foo/%23foo" txreq -url "/%23foo" rxresp expect resp.http.before == "/%23foo" expect resp.http.after == "/%23foo" txreq -req OPTIONS -url "*" rxresp expect resp.http.before == "*" expect resp.http.after == "*" } -run client c11 -connect ${h1_fe_fragment_block_sock} { txreq -url "/#foo" rxresp expect resp.status == 400 } -run