package OpenResty::Handler::CompiledAction; use strict; use warnings; use OpenResty::Util qw(Q QI); use OpenResty::QuasiQuote::SQL; use JSON::XS (); use LWP::UserAgent; use Data::Dumper qw(Dumper); use base 'OpenResty::Handler::Base'; __PACKAGE__->register('action'); sub requires_acl { undef } sub level2name { qw< action_list action action_param action_exec > [$_[-1]] } our $Dispatcher; BEGIN { my $root_path = "$FindBin::Bin/.."; my $filename = 'compiled.actions'; my $path = "$root_path/etc/$filename"; unless (-f $path) { $path = "/etc/openresty/$filename"; } if (!-f $path) { die "Can't find $filename under $root_path/etc/ nor /etc/openresty/.\n"; } unless ($Dispatcher = do $path) { die "Couldn't parse $path: $@\n" if $@; die "Couldn't read $path: $!\n" unless defined $Dispatcher; die "Couldn't run $path\n" unless $Dispatcher; } } my $ua = LWP::UserAgent->new; $ua->timeout(2); sub GET_action_exec { my ($self, $openresty, $bits) = @_; my $action = $bits->[1]; my $user = $openresty->builtin_param('_user') or die "No _user secified fro the CompiledAction handler.\n"; my $key; if ($user =~ /^\w+/) { $user = $&; $key = "$user|$action"; } else { die "Invalid _user param.\n"; } my $res = $Dispatcher->{$key} or die "Can't find the compiled form for action \"$action\""; # warn "result: $res"; my ($required_params, $hdl) = @$res; # warn "handle: $hdl\n"; #$hdl = eval $hdl; #if ($@) { die "Failed to eval the handler: $@\n" } my $user_test = $openresty->builtin_param("_user"); #warn "_user: $user_test \n"; while (my ($key, $val) = each %$required_params) { next if !$key; my $user_val = substr($key, 0, 1) eq '_' ? $openresty->builtin_param($key) : $openresty->url_param($key); if (!defined $user_val || $user_val ne $val) { die "Required params do not meet for action \"$action\": $key\n"; } } my ($fix_var, $fix_var_value) = ($bits->[2], $bits->[3]); my %vars; for my $var ($openresty->url_param) { $vars{$var} = $openresty->url_param($var) unless $var =~ /^_/; } if ($fix_var ne '~' and $fix_var_value ne '~') { $vars{$fix_var} = $fix_var_value; } $res = $hdl->(\%vars); # warn $res; my $req = do_http_request('GET', $res); my @outs; push @outs, $req; return \@outs; #warn "!!!!! $sql"; #$openresty->set_user($user); #return $openresty->select($sql, { use_hash => 1, read_only => 1 }); } sub do_http_request { my ($meth, $url, $rcontent) = @_; #no strict 'subs'; #### $meth #### $url my $req = HTTP::Request->new($meth); $req->header('Content-Type' => 'text/plain'); $req->header('Accept', '*/*'); $req->url($url); my $res = $ua->request($req); # judge result and next action based on $response_code if ($res->is_success) { my $content = $res->content; my $type = $res->header('Content-Type'); if ($type !~ /^text\//) { return { success => 0, error => 'Text response expected.', }; } my $data; eval { $data = $OpenResty::JsonXs->decode($content); }; if ($@) { return $content; } else { return $data; } } else { return { success => 0, error => $res->status_line, }; } } 1; __END__