summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/t/50mruby.t
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 12:08:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 12:08:18 +0000
commit5da14042f70711ea5cf66e034699730335462f66 (patch)
tree0f6354ccac934ed87a2d555f45be4c831cf92f4a /web/server/h2o/libh2o/t/50mruby.t
parentReleasing debian version 1.44.3-2. (diff)
downloadnetdata-5da14042f70711ea5cf66e034699730335462f66.tar.xz
netdata-5da14042f70711ea5cf66e034699730335462f66.zip
Merging upstream version 1.45.3+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/t/50mruby.t')
-rw-r--r--web/server/h2o/libh2o/t/50mruby.t541
1 files changed, 0 insertions, 541 deletions
diff --git a/web/server/h2o/libh2o/t/50mruby.t b/web/server/h2o/libh2o/t/50mruby.t
deleted file mode 100644
index d93f17e04..000000000
--- a/web/server/h2o/libh2o/t/50mruby.t
+++ /dev/null
@@ -1,541 +0,0 @@
-use strict;
-use warnings;
-use Digest::MD5 qw(md5_hex);
-use File::Temp qw(tempdir);
-use Test::More;
-use t::Util;
-
-plan skip_all => 'mruby support is off'
- unless server_features()->{mruby};
-
-plan skip_all => 'curl not found'
- unless prog_exists('curl');
-
-subtest "handler-file" => sub {
- my $server = spawn_h2o(<< 'EOT');
-hosts:
- default:
- paths:
- /:
- mruby.handler-file: t/50mruby/hello.rb
-EOT
- my ($headers, $body) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- is $body, "hello from h2o_mruby\n";
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}s;
- like $headers, qr{^content-type: text/plain; charset=utf-8\r$}im;
-};
-
-subtest "basic" => sub {
- my $server = spawn_h2o(<< 'EOT');
-hosts:
- default:
- paths:
- /inline:
- mruby.handler: |
- Proc.new do |env|
- [200, {}, ["hello from h2o_mruby\n"]]
- end
- /return-404:
- mruby.handler: |
- Proc.new do |env|
- [404, {}, ["not found"]]
- end
- file.dir: examples/doc_root
- /fallthru:
- mruby.handler: |
- Proc.new do |env|
- [399, {}, []]
- end
- file.dir: t/50mruby/
- /echo:
- mruby.handler: |
- Proc.new do |env|
- [200, {}, [JSON.generate(env)]]
- end
- /headers:
- mruby.handler: |
- Proc.new do |env|
- [200, {"foo" => "123\n456", "bar" => "baz"}, []]
- end
- /headers-each:
- mruby.handler: |
- Proc.new do |env|
- [200, [["content-type", "text/plain"], ["hello", "world"]], []]
- end
-EOT
- my $fetch = sub {
- my $path = shift;
- run_prog("curl --silent -A h2o_mruby_test --dump-header /dev/stderr http://127.0.0.1:$server->{port}$path");
- };
- my ($headers, $body) = $fetch->("/inline/");
- is $body, "hello from h2o_mruby\n", "inline";
- subtest "return-404" => sub {
- ($headers, $body) = $fetch->("/return-404/");
- like $headers, qr{^HTTP/1\.1 404 }is;
- is $body, "not found";
- };
- subtest "fallthru" => sub {
- ($headers, $body) = $fetch->("/fallthru/");
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}is;
- is md5_hex($body), md5_file("t/50mruby/index.html");
- };
- subtest "echo" => sub {
- ($headers, $body) = $fetch->("/echo/abc?def");
- like $body, qr{"REQUEST_METHOD":"GET"}, "REQUEST_METHOD";
- like $body, qr{"SCRIPT_NAME":"/echo"}, "SCRIPT_NAME";
- like $body, qr{"PATH_INFO":"/abc"}, "PATH_INFO";
- like $body, qr{"QUERY_STRING":"def"}, "QUERY_STRING";
- like $body, qr{"SERVER_NAME":"default"}, "SERVER_NAME";
- like $body, qr{"SERVER_ADDR":"127.0.0.1"}, "SERVER_ADDR";
- like $body, qr{"SERVER_PORT":"$server->{port}"}, "SERVER_PORT";
- like $body, qr{"HTTP_HOST":"127.0.0.1:$server->{port}"}, "HTTP_HOST";
- like $body, qr{"SERVER_ADDR":"127.0.0.1"}, "REMOTE_ADDR";
- like $body, qr{"SERVER_PORT":"[0-9]+"}, "REMOTE_PORT";
- like $body, qr{"HTTP_USER_AGENT":"h2o_mruby_test"}, "HTTP_USER_AGENT";
- like $body, qr{"rack.url_scheme":"http"}, "url_scheme";
- like $body, qr{"SERVER_SOFTWARE":"h2o/[0-9]+\.[0-9]+\.[0-9]+}, "SERVER_SOFTWARE";
- };
- subtest "protocol" => sub {
- run_with_curl($server, sub {
- my ($proto, $port, $curl) = @_;
- my $content = `$curl --silent --show-error $proto://127.0.0.1:$port/echo`;
- if ($curl =~ /http2/) {
- like $content, qr{"SERVER_PROTOCOL":"HTTP/2"}, "SERVER_PROTOCOL";
- } else {
- like $content, qr{"SERVER_PROTOCOL":"HTTP/1\.1"}, "SERVER_PROTOCOL";
- }
- });
- };
- subtest "headers" => sub {
- ($headers, $body) = $fetch->("/headers/");
- like $headers, qr{^foo: 123\r$}mi;
- like $headers, qr{^foo: 456\r$}mi;
- like $headers, qr{^bar: baz\r$}mi;
- };
- subtest "headers-each" => sub {
- ($headers, $body) = $fetch->("/headers-each/");
- like $headers, qr{^content-type: text/plain\r$}mi;
- like $headers, qr{^hello: world\r$}mi;
- };
-};
-
-subtest "reprocess_request" => sub {
- my $server = spawn_h2o(<< "EOT");
-hosts:
- default:
- reproxy: ON
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- [200, {"x-reproxy-url" => "http://default/dest#{env["PATH_INFO"]}"}, ["should never see this"]]
- end
- /307:
- mruby.handler: |
- Proc.new do |env|
- [307, {"x-reproxy-url" => "http://default/dest#{env["PATH_INFO"]}"}, ["should never see this"]]
- end
- /dest:
- mruby.handler: |
- Proc.new do |env|
- [200, {}, ["#{env["SCRIPT_NAME"]}#{env["PATH_INFO"]};#{env["CONTENT_LENGTH"]}"]]
- end
-EOT
- my ($stderr, $stdout) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- is $stdout, "/dest/;";
- ($stderr, $stdout) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/hoge");
- is $stdout, "/dest/hoge;";
- subtest "preserve-method" => sub {
- ($stderr, $stdout) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/307/");
- is $stdout, "/dest/;";
- ($stderr, $stdout) = run_prog("curl --data hello --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/307/");
- is $stdout, "/dest/;5";
- ($stderr, $stdout) = run_prog("curl --data hello --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- is $stdout, "/dest/;";
- };
-};
-
-subtest "server-push" => sub {
- plan skip_all => 'nghttp not found'
- unless prog_exists('nghttp');
- my $server = spawn_h2o(<< "EOT");
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- push_paths = []
- if env["PATH_INFO"] == "/index.txt"
- push_paths << "/index.js"
- end
- [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload"}.join()}, []]
- end
- file.dir: t/assets/doc_root
-EOT
- my $resp = `nghttp -n --stat https://127.0.0.1:$server->{tls_port}/index.txt`;
- like $resp, qr{\nid\s*responseEnd\s.*\s/index\.js\n.*\s/index\.txt}is, "receives index.js then /index.txt";
-};
-
-subtest "server-push / nopush" => sub {
- plan skip_all => 'nghttp not found'
- unless prog_exists('nghttp');
- my $server = spawn_h2o(<< "EOT");
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- push_paths = []
- if env["PATH_INFO"] == "/index.txt"
- push_paths << "/index.js"
- end
- [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload; nopush"}.join()}, []]
- end
- file.dir: t/assets/doc_root
-EOT
- my $resp = `nghttp -n --stat https://127.0.0.1:$server->{tls_port}/index.txt`;
- unlike $resp, qr{/index\.js}is, "receives only /index.txt";
- like $resp, qr{/index\.txt}is, "receives only /index.txt";
-};
-
-subtest "infinite-reprocess" => sub {
- my $server = spawn_h2o(sub {
- my ($port, $tls_port) = @_;
- return << "EOT";
-hosts:
- "127.0.0.1:$port":
- paths:
- /:
- reproxy: ON
- mruby.handler: |
- Proc.new do |env|
- [200,{"x-reproxy-url" => "http://127.0.0.1:$port/"},[]]
- end
-EOT
- });
- my ($stderr, $stdout) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $stderr, qr{^HTTP\/1.1 502 }s, "502 response";
- like $stdout, qr{too many internal delegations}, "reason";
-};
-
-subtest "send-file" => sub {
- my $server = spawn_h2o(<< "EOT");
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- [200,{}, File::open("t/50mruby/index.html")]
- end
-EOT
- my ($headers, $body) = run_prog("curl --silent -A h2o_mruby_test --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}is;
- is md5_hex($body), md5_file("t/50mruby/index.html");
-};
-
-subtest "exception" => sub {
- my $server = spawn_h2o(<< 'EOT');
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- cnt = 0
- Proc.new do |env|
- cnt += 1
- if cnt % 2 != 0
- [200, {}, ["hello\n"]]
- else
- raise "error from rack"
- end
- end
-EOT
- my $fetch = sub {
- run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}");
- };
- for (1..3) {
- my ($headers, $body) = $fetch->();
- like $headers, qr{^HTTP/1\.1 200 }is;
- is $body, "hello\n";
- ($headers, $body) = $fetch->();
- like $headers, qr{^HTTP/1\.1 500 }is;
- }
-};
-
-subtest "post" => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- body = []
- 3.times do
- env["rack.input"].rewind
- body << env["rack.input"].read
- body << "\\n"
- end
- [200, {}, body]
- end
-EOT
- my ($headers, $body) = run_prog("curl --silent --data 'hello' --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}is;
- is $body, "hello\n" x 3;
-};
-
-subtest "InputStream#read-after-close" => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- prev_input = nil
- Proc.new do |env|
- if !prev_input
- prev_input = env["rack.input"]
- resp = "not cached"
- else
- begin
- prev_input.read
- resp = "must not seed this"
- rescue IOError => e
- resp = "got IOError"
- end
- end
- [200, {}, [resp]]
- end
-EOT
- my ($headers, $body) = run_prog("curl --silent --data 'hello' --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}is;
- is $body, "not cached";
- ($headers, $body) = run_prog("curl --silent --data 'hello' --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 OK\r\n}is;
- is $body, "got IOError";
-};
-
-subtest "header-concat" => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- [200, {}, [env["HTTP_COOKIE"]]]
- end
-EOT
- run_with_curl($server, sub {
- my ($proto, $port, $curl) = @_;
- my ($headers, $body) = run_prog("$curl --silent -H 'cookie: a=b' -H 'cookie: c=d' --dump-header /dev/stderr $proto://127.0.0.1:$port/");
- like $headers, qr{^HTTP/\S+ 200}is;
- like $body, qr{^a=b;\s*c=d$}is;
- });
-};
-
-subtest "close-called" => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- is_open = false
- lambda do |env|
- if is_open
- return [500, {}, ["close not called"]]
- end
- is_open = true
- return [
- 200,
- {},
- Class.new do
- def each
- yield "hello"
- end
- define_method(:close) do
- is_open = false
- end
- end.new,
- ]
- end
-EOT
- my ($headers, $body) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 }is;
- is $body, "hello";
- ($headers, $body) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 }is;
- is $body, "hello";
-};
-
-subtest "close-called-on-exception" => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- is_open = false
- lambda do |env|
- if is_open
- return [500, {}, ["close not called"]]
- end
- is_open = true
- return [
- 200,
- {},
- Class.new do
- def each
- yield "hello"
- raise "yeah!"
- end
- define_method(:close) do
- is_open = false
- end
- end.new,
- ]
- end
-EOT
- my ($headers, $body) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 }is;
- is $body, "hello";
- ($headers, $body) = run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 200 }is;
- is $body, "hello";
-};
-
-subtest "log lineno" => sub {
- my $tester = sub {
- my ($name, $conf, $expected) = @_;
-
- subtest $name => sub {
- my $tempdir = tempdir(CLEANUP => 1);
- unlink "$tempdir/error_log";
- my $server = spawn_h2o(<< "EOT");
-$conf
-error-log: $tempdir/error_log
-EOT
- run_prog("curl --silent --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- my @log = do {
- open my $fh, "<", "$tempdir/error_log"
- or die "failed to open error_log:$!";
- map { my $l = $_; chomp $l; $l } <$fh>;
- };
- @log = grep { $_ =~ /^\[h2o_mruby\]/ } @log;
- like $log[$#log], qr{\[h2o_mruby\] in request:/:mruby raised: @{[$server->{conf_file}]}:$expected:\s*hoge \(RuntimeError\)};
- };
- };
- $tester->("flow style", <<"EOT", 5);
-hosts:
- default:
- paths:
- /:
- mruby.handler: Proc.new do |env| raise "hoge" end
-EOT
- $tester->("block style", <<"EOT", 7);
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- Proc.new do |env|
- raise "hoge"
- end
-EOT
-};
-
-subtest 'response with specific statuses should not contain content-length header' => sub {
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- proc {|env|
- [204, {}, []]
- }
-EOT
- my ($headers, $body) = run_prog("curl --silent --data 'hello' --dump-header /dev/stderr http://127.0.0.1:$server->{port}/");
- like $headers, qr{^HTTP/1\.1 204 OK\r\n}is;
- unlike $headers, qr{^content-length:}im;
-};
-
-subtest 'PATH_INFO and SCRIPT_NAME' => sub {
- plan skip_all => "nc not found"
- unless prog_exists("nc");
-
- my $server = spawn_h2o(<< "EOT");
-num-threads: 1
-hosts:
- default:
- paths:
- /:
- mruby.handler: |
- proc {|env|
- [200, {}, ['handler1, ' + env['SCRIPT_NAME'] + ', ' + env['PATH_INFO']]]
- }
- /abc:
- mruby.handler: |
- proc {|env|
- [200, {}, ['handler2, ' + env['SCRIPT_NAME'] + ', ' + env['PATH_INFO']]]
- }
- "/foo bar":
- mruby.handler: |
- proc {|env|
- [200, {}, ['handler3, ' + env['SCRIPT_NAME'] + ', ' + env['PATH_INFO']]]
- }
-EOT
- my $nc = sub {
- my $path = shift;
- my $cmd = "echo 'GET $path HTTP/1.1\\r\\nHost: 127.0.0.1\\r\\n\\r' | nc 127.0.0.1 $server->{port}";
- (undef, my $r) = run_prog($cmd);
- split(/\r\n\r\n/, $r, 2);
- };
-
- my $body;
- (undef, $body) = $nc->('/abc/def%20ghi');
- is $body, 'handler2, /abc, /def%20ghi', 'should be kept undecoded';
-
- (undef, $body) = $nc->('/abc/def/../ghi/../jhk');
- is $body, 'handler2, /abc, /def/../ghi/../jhk', 'https://github.com/h2o/h2o/pull/1480#issuecomment-339614160';
-
- (undef, $body) = $nc->('/123/../abc/def/../ghi');
- is $body, 'handler2, /abc, /def/../ghi', 'https://github.com/h2o/h2o/pull/1480#issuecomment-339658134';
-
- (undef, $body) = $nc->('/foo%20bar/baz');
- is $body, 'handler3, /foo bar, /baz', 'paths should be decoded';
-
- (undef, $body) = $nc->('/xxx/../hoge');
- is $body, 'handler1, , /xxx/../hoge', 'string size is too big issue 1';
-
- (undef, $body) = $nc->('/../abc');
- is $body, 'handler2, /abc, ', 'string size is too big issue 2';
-
- (undef, $body) = $nc->('abc');
- is $body, 'handler2, /abc, ', 'no leading slash 1';
-
- (undef, $body) = $nc->('abc/def');
- is $body, 'handler2, /abc, /def', 'no leading slash 2';
-
- (undef, $body) = $nc->('123/../abc/def/../ghi');
- is $body, 'handler2, /abc, /def/../ghi', 'no leading slash 3';
-
- (undef, $body) = $nc->('xyz');
- is $body, 'handler1, , xyz', 'no leading slash 4';
-
- (undef, $body) = $nc->('');
- is $body, 'handler1, , ', 'empty path';
-};
-
-done_testing();