worker_processes  1;
events {
    worker_connections  200;
}

daemon off;
master_process off;
error_log logs/error.log info;

http {
    include       mime.types;

    # test for init master process
    mruby_init_code 'p "[#{Process.pid}] init master process"';

    # test for init worker process
    #mruby_init_worker build/nginx/html/init_worker.rb;

    # test for init worker process using inline code
    mruby_init_worker_code 'p "[#{Process.pid}] init worker process from inline code"';

    # test for exit worker process
    #mruby_exit_worker build/nginx/html/exit_worker.rb;

    # test for init worker process using inline code
    mruby_exit_worker_code 'p "[#{Process.pid}] exit worker process from inline code"';

    server {
        listen       58082 ssl;
        server_name  _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate     __NGXDOCROOT__/dummy.crt;
        ssl_certificate_key __NGXDOCROOT__/dummy.key;

        mruby_ssl_handshake_handler_code '
          ssl = Nginx::SSL.new
          ssl.certificate = "__NGXDOCROOT__/#{ssl.servername}.crt"
          ssl.certificate_key = "__NGXDOCROOT__/#{ssl.servername}.key"
        ';

        location / {
            mruby_content_handler_code "Nginx.rputs 'ssl test ok'";
        }
    }

    server {
        listen       58083 ssl;
        server_name  _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate     __NGXDOCROOT__/dummy.crt;
        ssl_certificate_key __NGXDOCROOT__/dummy.key;

        mruby_ssl_handshake_handler_code '
          ssl = Nginx::SSL.new
          ssl.certificate_data = File.read "__NGXDOCROOT__/#{ssl.servername}.crt"
          ssl.certificate_key_data = File.read "__NGXDOCROOT__/#{ssl.servername}.key"
        ';

        location / {
            mruby_content_handler_code "Nginx.rputs 'ssl test ok'";
        }
    }

    server {
        listen       58085 ssl;
        server_name  _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate     __NGXDOCROOT__/dummy.crt;
        ssl_certificate_key __NGXDOCROOT__/dummy.key;

        mruby_ssl_handshake_handler build/nginx/html/set_ssl_cert_and_key.rb;

        location / {
            mruby_content_handler_code "Nginx.rputs 'ssl test ok'";
        }
    }

    server {
        listen       58086 ssl;
        server_name  _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate     __NGXDOCROOT__/dummy.crt;
        ssl_certificate_key __NGXDOCROOT__/dummy.key;

        mruby_ssl_handshake_handler build/nginx/html/set_ssl_cert_and_key.rb cache;

        location / {
            mruby_content_handler_code "Nginx.rputs 'ssl test ok'";
        }
    }

    server {
        listen       58087 ssl;
        server_name  _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate     __NGXDOCROOT__/dummy.crt;
        ssl_certificate_key __NGXDOCROOT__/dummy.key;

        mruby_ssl_handshake_handler_code '
          ssl = Nginx::SSL.new
          Nginx::SSL.errlogger Nginx::LOG_NOTICE, "Servername is #{ssl.servername}"
        ';

        location / {
            mruby_content_handler_code "Nginx.rputs 'ssl test ok'";
        }
    }

    server {
        listen       58081;
        server_name  localhost;

        location /keepalive {
            # If using keepalive, return true
            mruby_content_handler_code '
              Nginx.rputs Nginx::Request.new.headers_in["Connection"].nil?.to_s
              Nginx.errlogger Nginx::LOG_NOTICE, "upstream: remote_port: #{Nginx::Connection.new.remote_port}"
              Nginx.errlogger Nginx::LOG_NOTICE, "upstream: request_header:: #{Nginx::Headers_in.new.all}"
            ';
        }
        location / {
            mruby_content_handler_code "Nginx.rputs 'proxy test ok'";
        }
    }

    server {
        listen       58080;
        server_name  localhost;
        root __NGXDOCROOT__;

        # test for hello world and cache option
        location /mruby {
            mruby_content_handler build/nginx/html/unified_hello.rb cache;
        }

        # test for creating all instance
        location /all_instance {
          mruby_content_handler_code '
            if server_name == "NGINX"
              Server = Nginx
            elsif server_name == "Apache"
              Server = Apache
            end

            r = Server::Request.new
            s = Server::Server.new
            c = Server::Connection.new
            v = Server::Var.new

            Server.echo "hostname: " + r.hostname
            Server.echo "path: " + s.path
            Server.echo "hello world"
            Server.echo "documento_root: #{s.document_root}"
            Server.echo "path: #{s.path}"
            Server.echo "remote ip: #{c.remote_ip}"
            Server.echo "remote port: #{c.remote_port}"
            Server.echo "user_agent: #{r.headers_in.user_agent}"
            Server.echo "local ip: #{c.local_ip}"
            Server.echo "local port: #{c.local_port}"
            Server.echo "scheme: #{v.scheme}"

            r.headers_in.all.keys.each do |k|
              Server.echo "#{k}: #{r.headers_in[k]}"
            end
            # if do not raise error, set "OK" into response header
            r.headers_out["X-INST-TEST"] = "OK"
          ';
        }

        # test for proxy on rewrite phase
        location /proxy {
          mruby_set_code $backend '
            backends = [
              "127.0.0.1:58081",
              #"test2.example.com",
              #"test3.example.com",
            ]
            backends[rand(backends.length)]
          ';
          proxy_pass  http://$backend;
        }

        # test for request/response header test
        location /header {
            mruby_content_handler_code '
                r = Nginx::Request.new
                unless r.headers_in["X-REQUEST-HEADER"].nil?
                  r.headers_out["X-RESPONSE-HEADER"] = r.headers_in["X-REQUEST-HEADER"]
                  Nginx.rputs "X-REQUEST-HEADER found"
                else
                  r.headers_out["X-RESPONSE-HEADER"] = "nothing"
                  Nginx.rputs "X-REQUEST-HEADER not found"
                end
                Nginx.return Nginx::HTTP_OK
            ';
        }

        # test for setting new headers_in header
        location /header/internal {
          mruby_access_handler_code '
            r = Nginx::Request.new
            r.headers_in["X-INTERNAL-HEADER"] = "hoge"
          ';
          mruby_content_handler_code '
            r = Nginx::Request.new
            r.headers_out["X-INTERNAL-HEADER"] = r.headers_in["X-INTERNAL-HEADER"]
            Nginx.return Nginx::HTTP_OK
          ';
        }

        # test for deleting headers_out header
        location /headers_out_delete {
          mruby_access_handler_code '
            r = Nginx::Request.new
            (1..53).each do |i|
                r.headers_out["EXT-HEADER#{i}"] = "foo"
            end
          ';
          mruby_content_handler_code '
            r = Nginx::Request.new
            %w(2 1 22 21 25 42 41 43 47 40 51 53 52).each do |n|
              r.headers_out.delete("EXT-HEADER#{n}")
            end
            Nginx.return Nginx::HTTP_OK
          ';
        }

        # test for deleting internal header
        location /headers_in_delete {
          mruby_access_handler_code '
            r = Nginx::Request.new
            r.headers_in["X-INTERNAL-HEADER"] = "hoge"
            r.headers_in.delete("X-REQUEST-HEADER")
          ';
          mruby_content_handler_code '
            r = Nginx::Request.new
            r.headers_out["X-INTERNAL-HEADER"] = r.headers_in["X-INTERNAL-HEADER"]
            Nginx.rputs "X-REQUEST-HEADER is #{r.headers_in["X-REQUEST-HEADER"].inspect}"
            Nginx.return Nginx::HTTP_OK
          ';
        }

        # test for nginx variables
        location /vars {
            set $foo "mruby";
            mruby_content_handler_code '
                r = Nginx::Request.new
                r.content_type = "text/html"
                Nginx.rputs "host => #{r.var.host} "
                Nginx.rputs "foo => #{r.var.foo}"
            ';
        }

        # test for redirect
        # http://localhost/redirect?url=http://www.google.com
        location /redirect {
            mruby_rewrite_handler_code '
                r = Nginx::Request.new
                if r.var.arg_url
                    Nginx.redirect r.var.arg_url
                else
                    Nginx.redirect "http://ngx.mruby.org", 301
                end
            ';
        }

        # test for internal redirect
        # http://localhost/redirect/internal?version=xxx
        location /redirect/internal {
            mruby_rewrite_handler_code '
                Nginx.redirect "/vars"
            ';
        }

        # test for output filter by dynamic arg
        location /filter_dynamic_arg {
          mruby_output_body_filter_code '
            r = Nginx::Request.new
            f = Nginx::Filter.new
            args = r.var.args
            if args.nil?
              f.body = "output filter: static"
            else
              f.body = "output filter: #{args}"
            end
          ';
          mruby_output_header_filter_code '
            r = Nginx::Request.new
            args = r.var.args
            unless args.nil?
              r.headers_out["X-New-Header"] = args.to_s
            end
          ';
        }

        # test for output filter by dynamic arg using ruby file
        location /filter_dynamic_arg_file {
          mruby_output_body_filter build/nginx/html/filter_dynamic_arg.rb cache;
          mruby_output_header_filter_code '
            r = Nginx::Request.new
            args = r.var.args
            unless args.nil?
              r.headers_out["X-New-Header"] = args.to_s
            end
          ';
        }

        # test for control nginx internal variable between mruby and nginx
        location /inter_var_file {
            set $fuga "200";
            mruby_set $hoge "build/nginx/html/set.rb" cache;
            mruby_content_handler "build/nginx/html/set2.rb";
        }

        # test for nginx internal variables in inline code
        location /inter_var_inline {
            set $fuga "100";
            mruby_set_code $hoge 'Nginx::Var.new.fuga.to_i * 2';
            mruby_content_handler_code '
              r = Nginx::Request.new
              Nginx.rputs "fuga => #{r.var.fuga} "
              Nginx.rputs "hoge => #{r.var.hoge} "
              r.var.set "hoge", r.var.hoge.to_i * 2
              Nginx.rputs "hoge => #{r.var.hoge}"
            ';
        }

        # test for server ip address and port
        location /server_ip_port {
            mruby_content_handler_code '
              c = Nginx::Connection.new
              Nginx.rputs "#{c.local_ip}:#{c.local_port}"
            ';
        }

        # test for client ip address
        location /client_ip {
            mruby_content_handler_code '
              c = Nginx::Connection.new
              Nginx.rputs "#{c.remote_ip}"
            ';
        }

        # test for request method like GET
        location /request_method {
            mruby_content_handler_code '
              r = Nginx::Request.new
              if r.method == "HEAD"
                r.headers_out["x-method"] = "head"
              else
                Nginx.rputs "#{r.method}"
              end
            ';
        }

        # test for add_handler
        location ~ \.rb$ {
            mruby_add_handler on;
        }

        # test for Kernel.server_name
        location /kernel_servername {
            mruby_content_handler_code '
              Nginx.rputs server_name
            ';
        }

        # test for Nginx::Var
        # http://localhost/nginx_var?name=http_host
        location /nginx_var {
            mruby_content_handler_code '
              r = Nginx::Request.new
              Nginx.rputs r.var.send r.var.arg_name.to_sym
            ';
        }

        # test for status code
        location /service_unavailable {
            mruby_content_handler_code '
              Nginx.return Nginx::HTTP_SERVICE_UNAVAILABLE
            ';
        }

        # test for return with reponse body
        location /return_and_body {
            mruby_content_handler_code '
              Nginx.rputs "body"
              Nginx.return Nginx::HTTP_OK
            ';
        }

        # test for return with no reponse body
        location /return_and_error {
            mruby_content_handler_code '
              Nginx.return Nginx::HTTP_OK
            ';
        }

        # test for raise error with no reponse body
        location /raise_and_no_response {
            mruby_content_handler_code '
              Nginx.echooo "echooo is invalid method"
            ';
        }

        # test for request_body
        location /request_body_manual {
            mruby_rewrite_handler_code '
              r = Nginx::Request.new
              r.read_body
              Nginx.rputs r.get_body
            ';
        }

        # test for request_body
        location /request_body {
            mruby_rewrite_handler_code '
              r = Nginx::Request.new
              Nginx.rputs r.body
            ';
        }

        # test for get_server_class
        location /server_class {
            mruby_rewrite_handler_code '
              Nginx.rputs get_server_class.to_s
            ';
        }

        # test for header at output_filter
        location /output_filter_header {
            mruby_output_header_filter build/nginx/html/header_filter.rb cache;
        }

        # test for header at output_filter
        location /output_header_filter {
            mruby_output_header_filter_code '
              Nginx::Request.new.headers_out["x-add-new-header"] = "new_header"
            ';
        }

        # test for builtin header at output_filter
        location /output_filter_builtin_header {
            mruby_output_header_filter_code '
              Nginx::Request.new.headers_out["Server"] = "ngx_mruby"
            ';
        }
        # test for rewrite built-in Server header
        mruby_server_rewrite_handler_code 'Nginx::Request.new.headers_out["Server"] = "global_ngx_mruby"; Nginx.return Nginx::DECLINED';

        # test for upstream keepalive
        location /upstream-keepalive {
          mruby_rewrite_handler_code '
            u = Nginx::Upstream.new "mruby_upstream"
            u.server = "127.0.0.1:58081"
            Nginx.errlogger Nginx::LOG_NOTICE, "front: keepalive_cache: #{u.keepalive_cache}"
            Nginx.errlogger Nginx::LOG_NOTICE, "front: u.hostname: #{u.server}"
          ';
          proxy_pass http://mruby_upstream/keepalive;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_send_timeout 2s;
          proxy_read_timeout 2s;
          proxy_connect_timeout 2s;
        }
        location /nginx-version {
          mruby_content_handler_code 'Nginx.rputs Nginx.nginx_version';
        }
        location /sub_request_check {
          mruby_content_handler_code 'Nginx.rputs Nginx::Request.new.sub_request?.to_s';
        }
        location /authority {
          mruby_content_handler_code 'Nginx.rputs Nginx::Request.new.authority.to_s';
        }
        location /hostname {
          mruby_content_handler_code 'Nginx.rputs Nginx::Request.new.hostname.to_s';
        }
        location /var_exist {
          mruby_content_handler_code 'Nginx.rputs Nginx::Request.new.var.exist?("arg_foo").to_s';
        }
        location /rack_base {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, {"x-hoge" => "foo"}, ["rack body"]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base1 {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, {"x-hoge" => "foo", "x-foo" => "hoge"}, ["rack", " body"]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base2 {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, [["x-hoge", "foo"], ["x-foo", "hoge"]], ["rack", " body"]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base3 {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [404, [], []]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base4 {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, [{"x-foo" => "foo"}], ["You never see this response"]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base_env {
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, [], [JSON.generate(env)]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base_2phase {
          mruby_access_handler_code '
            class AccessCheck
              def call(env)
                if env["HTTP_AUTH_TOKEN"] == "aaabbbccc"
                  [Nginx::DECLINED, {"x-client-ip" => env["REMOTE_ADDR"]}, []]
                else
                  [403, {}, []]
                end
              end
            end
            run AccessCheck.new
          ';
          mruby_content_handler_code '
            class RackTest
              def call(env)
                [200, [], ["OK"]]
              end
            end
            run RackTest.new
          ';
        }
        location /rack_base_push {
          mruby_content_handler_code '
            p = Proc.new do |env|
              push_paths = []
              if env["PATH_INFO"] == "/rack_base_push/index.txt"
                push_paths << "/index.js"
              end
              [200, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload"}.join()}, ["push"]]
            end
            run p
          ';
        }
        location /rack_base_logger {
          mruby_content_handler_code '
            p = Proc.new do |env|
              logger = env["rack.logger"]
              logger.fatal "Ignore me. This is for logger test"
              logger.error "Ignore me. This is for logger test"
              logger.warn "Ignore me. This is for logger test"
              logger.info "Ignore me. This is for logger test"
              logger.debug "Ignore me. This is for logger test"
              logger.emerg "Ignore me. This is for logger test"
              logger.alert "Ignore me. This is for logger test"
              logger.crit "Ignore me. This is for logger test"
              logger.notice "Ignore me. This is for logger test"

              logger.fatal {"Ignore me." + " This is for logger with block test"}
              logger.error {"Ignore me." + " This is for logger with block test"}
              logger.warn {"Ignore me." + " This is for logger with block test"}
              logger.info {"Ignore me." + " This is for logger with block test"}
              logger.debug {"Ignore me." + " This is for logger with block test"}
              logger.emerg {"Ignore me." + " This is for logger with block test"}
              logger.alert {"Ignore me." + " This is for logger with block test"}
              logger.crit {"Ignore me." + " This is for logger with block test"}
              logger.notice {"Ignore me." + " This is for logger with block test"}
              [200, {}, ["OK"]]
            end
            run p
          ';
        } 
        location /rack_base_input {
          mruby_content_handler_code '
            p = Proc.new do |env|
              msg = "#{env["REQUEST_METHOD"]}:#{env["rack.input"].gets}"
              [200, {}, [msg]]
            end
            run p
          ';
        }
        location /rack_base_errorpage {
          error_page 401 @rack_base_errorpage;
          mruby_access_handler_code 'Nginx.return Nginx::HTTP_UNAUTHORIZED';
        }
        location @rack_base_errorpage {
          mruby_content_handler_code '
            p = Proc.new do |env|
              [nil, {}, ["THIS IS AN ERROR MESSAGE FOR 401"]]
            end
            run p
          ';
        }
        location /multi_headers_out {
          mruby_content_handler_code '
            r = Nginx::Request.new
            r.headers_out["hoge"] = "dummy"
            r.headers_out["hoge"] = %w(foo fuga)
            Nginx.rputs r.headers_out["hoge"]
            Nginx.return 200
          ';
        }
        location /multi_headers_in {
          mruby_content_handler_code '
            r = Nginx::Request.new
            r.headers_in["hoge"] = [r.headers_in["hoge"], "fuga"]
            Nginx.rputs r.headers_in["hoge"]
            Nginx.return 200
          ';
        }
        location /fix-bug-issue-155 {
          mruby_rewrite_handler_code '
            headers = %w(abc=123 foo=bar)
            Nginx::Request.new.headers_out["Set-Cookies"] = headers
            Nginx.rputs headers
            Nginx::return 200
          ';
        }
        location /get_uri_args {
          mruby_content_handler_code '
            args = Nginx::Request.new.uri_args
            Nginx.echo args.map{|k, v| "#{k}:#{v}" }.join(\n)
          ';
        }
        location /set_uri_args {
          mruby_content_handler_code '
            args = {"pass" => "ngx_mruby"}
            r = Nginx::Request.new
            r.uri_args = args

            Nginx.echo(r.args)
          ';
        }
        location /get_post_args {
          mruby_content_handler_code '
            r = Nginx::Request.new
            args = r.post_args

            Nginx.echo args.map{|k, v| "#{k}:#{v}" }.join("\n")
          ';
        }
        location /issue_172 {
          mruby_output_body_filter_code '
             f = Nginx::Filter.new
             response = f.body
             f.body = (response + " world").upcase
          ';
        }
        location /issue_172_2 {
          root   html;
          index  index.html index.htm;
          mruby_output_body_filter_code '
             Nginx::Request.new.headers_out["hoge"] = "fuga"
             f = Nginx::Filter.new
             response = f.body
             f.body = (response + " world").upcase
          ';
        }
        location /nginx_false_true {
          mruby_content_handler_code 'Nginx.rputs (Nginx::FALSE + Nginx::TRUE)';
        }

        mruby_post_read_handler_code 'Nginx::Request.new.headers_out["hoge"] = "fuga"';
        location /issue_210 {
          mruby_content_handler_code 'Nginx.rputs "hello"';
        }
        location /issue_210_2 {
          mruby_content_handler_code 'Nginx.rputs "hello2"';
        }
    }

    server {
        listen       58084;
        server_name  localhost;

        mruby_access_handler_code 'Nginx.return Nginx::HTTP_FORBIDDEN';
        location /access_handler_in_server_scope {
          mruby_content_handler_code '
            Nginx.rputs "OK" # See https://github.com/matsumoto-r/ngx_mruby/issues/200
            Nginx::return 200
          ';
        }

        location /override_access_handler_in_server_scope {
          mruby_access_handler_code 'Nginx.return Nginx::OK';
          mruby_content_handler_code '
            Nginx.rputs "OK" # See https://github.com/matsumoto-r/ngx_mruby/issues/200
            Nginx::return 200
          ';
        }

    }

    upstream mruby_upstream {
      server 127.0.0.1:80;
      mruby_upstream_keepalive 16;
    }
}

# vim: set ft=nginx :
