mirror of
				https://github.com/openresty/openresty.git
				synced 2024-10-13 00:29:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			204 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env perl
 | 
						|
 | 
						|
# Copyright (C) Yichun Zhang (agentzh)
 | 
						|
 | 
						|
# TODO: port this script into the nginx core for greater flexibility
 | 
						|
# and better performance.
 | 
						|
 | 
						|
use strict;
 | 
						|
use warnings;
 | 
						|
 | 
						|
use File::Spec ();
 | 
						|
use FindBin ();
 | 
						|
use Getopt::Std qw( getopts );
 | 
						|
use File::Temp qw( tempdir );
 | 
						|
use POSIX qw( WNOHANG );
 | 
						|
 | 
						|
my %opts;
 | 
						|
getopts("he:c:V", \%opts)
 | 
						|
    or usage(1);
 | 
						|
 | 
						|
if ($opts{h}) {
 | 
						|
    usage(0);
 | 
						|
}
 | 
						|
 | 
						|
my $nginx_path = File::Spec->catfile($FindBin::Bin, "..", "nginx", "sbin", "nginx");
 | 
						|
#warn $nginx_path;
 | 
						|
if (!-f $nginx_path) {
 | 
						|
    $nginx_path = "nginx";  # find in PATH
 | 
						|
}
 | 
						|
 | 
						|
if ($opts{V}) {
 | 
						|
    exec "$nginx_path -V";
 | 
						|
}
 | 
						|
 | 
						|
my $luafile;
 | 
						|
if (!defined $opts{e}) {
 | 
						|
    $luafile = shift
 | 
						|
        or die qq{No Lua input file nor -e "" option specified.\n};
 | 
						|
}
 | 
						|
 | 
						|
if (@ARGV) {
 | 
						|
    die "unknown arguments: @ARGV\n";
 | 
						|
}
 | 
						|
 | 
						|
my $conns = $opts{c} || 64;
 | 
						|
 | 
						|
my $prefix_dir = tempdir(CLEANUP => 1);
 | 
						|
#warn "prefix dir: $prefix_dir\n";
 | 
						|
 | 
						|
my $logs_dir = File::Spec->catfile($prefix_dir, "logs");
 | 
						|
mkdir $logs_dir or die "failed to mkdir $logs_dir: $!";
 | 
						|
 | 
						|
my $conf_dir = File::Spec->catfile($prefix_dir, "conf");
 | 
						|
mkdir $conf_dir or die "failed to mkdir $conf_dir: $!";
 | 
						|
 | 
						|
my $chunk_name;
 | 
						|
if (defined $opts{e}) {
 | 
						|
    $luafile = File::Spec->catfile($conf_dir, "a.lua");
 | 
						|
    open my $out, ">$luafile"
 | 
						|
        or die "Cannot open $luafile for writing: $!\n";
 | 
						|
    print $out $opts{e};
 | 
						|
    close $out;
 | 
						|
    $chunk_name = "=(command line -e)";
 | 
						|
 | 
						|
} else {
 | 
						|
    $chunk_name = "\@$luafile";
 | 
						|
}
 | 
						|
 | 
						|
my $loader = <<_EOC_;
 | 
						|
            local gen
 | 
						|
            do
 | 
						|
                local fname = "$luafile"
 | 
						|
                local f = assert(io.open(fname, "r"))
 | 
						|
                local chunk = f:read("*a")
 | 
						|
                gen = assert(loadstring(chunk, "$chunk_name"))
 | 
						|
            end
 | 
						|
_EOC_
 | 
						|
 | 
						|
my $conf_file = File::Spec->catfile($conf_dir, "nginx.conf");
 | 
						|
open my $out, ">$conf_file"
 | 
						|
    or die "Cannot open $conf_file for writing: $!\n";
 | 
						|
 | 
						|
print $out <<_EOC_;
 | 
						|
daemon off;
 | 
						|
master_process off;
 | 
						|
worker_processes 1;
 | 
						|
 | 
						|
env LD_LIBRARY_PATH;
 | 
						|
env LD_PRELOAD;
 | 
						|
env PATH;
 | 
						|
env LUA_PATH;
 | 
						|
env LUA_CPATH;
 | 
						|
 | 
						|
error_log /dev/stderr warn;
 | 
						|
#error_log /dev/stderr debug;
 | 
						|
 | 
						|
events {
 | 
						|
    worker_connections $conns;
 | 
						|
}
 | 
						|
 | 
						|
http {
 | 
						|
    access_log off;
 | 
						|
    lua_socket_log_errors off;
 | 
						|
 | 
						|
    init_by_lua '
 | 
						|
        local stdout = io.stdout
 | 
						|
        print = function (...) stdout:write(...) end
 | 
						|
        ngx.print = print
 | 
						|
        ngx.say = function (...) print(...) print("\\\\n") end
 | 
						|
    ';
 | 
						|
 | 
						|
    init_worker_by_lua '
 | 
						|
        local exit = os.exit
 | 
						|
        local stderr = io.stderr
 | 
						|
 | 
						|
        local function handle_err(err)
 | 
						|
            if err then
 | 
						|
                err = string.gsub(err, "^init_worker_by_lua:%d+: ", "")
 | 
						|
                stderr:write(err)
 | 
						|
            end
 | 
						|
            return exit(1)
 | 
						|
        end
 | 
						|
 | 
						|
        local ok, err = pcall(function ()
 | 
						|
$loader
 | 
						|
            -- print("calling timer.at...")
 | 
						|
            local ok, err = ngx.timer.at(0, function ()
 | 
						|
                -- io.stderr:write("timer firing")
 | 
						|
                local ok, err = pcall(gen)
 | 
						|
                if not ok then
 | 
						|
                    return handle_err(err)
 | 
						|
                end
 | 
						|
                local rc = err
 | 
						|
                if rc and type(rc) ~= "number" then
 | 
						|
                    return handle_err("bad return value of type " .. type(rc))
 | 
						|
                end
 | 
						|
                return exit(rc)
 | 
						|
            end)
 | 
						|
            if not ok then
 | 
						|
                return handle_err(err)
 | 
						|
            end
 | 
						|
            -- print("timer created")
 | 
						|
        end)
 | 
						|
 | 
						|
        if not ok then
 | 
						|
            return handle_err(err)
 | 
						|
        end
 | 
						|
    ';
 | 
						|
}
 | 
						|
_EOC_
 | 
						|
 | 
						|
close $out;
 | 
						|
 | 
						|
my $cmd = "$nginx_path -p $prefix_dir/";
 | 
						|
 | 
						|
my $child_pid;
 | 
						|
 | 
						|
sub sigint {
 | 
						|
    $SIG{INT} = \&sigint;
 | 
						|
    if ($child_pid) {
 | 
						|
        kill INT => $child_pid;
 | 
						|
    }
 | 
						|
}
 | 
						|
$SIG{INT} = \&sigint;
 | 
						|
 | 
						|
my $pid = fork();
 | 
						|
 | 
						|
if (!defined $pid) {
 | 
						|
    die "fork() failed: $!\n";
 | 
						|
}
 | 
						|
 | 
						|
if ($pid == 0) {  # child process
 | 
						|
    #warn "exec $cmd...";
 | 
						|
    exec $cmd;
 | 
						|
 | 
						|
} else {
 | 
						|
    $child_pid = $pid;
 | 
						|
    waitpid($child_pid, 0);
 | 
						|
    exit($? || 0);
 | 
						|
}
 | 
						|
 | 
						|
sub usage {
 | 
						|
    my $rc = shift;
 | 
						|
    my $msg = <<_EOC_;
 | 
						|
resty [-h] [-c num] [-e prog] [-V] [lua-file]
 | 
						|
 | 
						|
Options:
 | 
						|
    -c num      set maximal connection count (default: 64).
 | 
						|
    -e prog     run the inlined Lua code in "prog".
 | 
						|
    -h          print this help.
 | 
						|
    -V          print the underlying nginx version and configurations.
 | 
						|
 | 
						|
For bug reporting instructions, please see:
 | 
						|
<http://openresty.org/#Community>
 | 
						|
_EOC_
 | 
						|
    if ($rc == 0) {
 | 
						|
        print $msg;
 | 
						|
        exit(0);
 | 
						|
    }
 | 
						|
 | 
						|
    warn $msg;
 | 
						|
    exit($rc);
 | 
						|
}
 |