X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=blobdiff_plain;f=PVE%2FRPCEnvironment.pm;h=a0c0c3328f2313ce0f73d1e453808ea6b4f968ee;hp=0905b65ef040930c6cc662ed96d4dc6936f99193;hb=dcfaabd7ca0afb4e157634c4179cebb1482681a1;hpb=8d6e045f21177cef610f717a940e5717e5998c3c diff --git a/PVE/RPCEnvironment.pm b/PVE/RPCEnvironment.pm index 0905b65..a0c0c33 100644 --- a/PVE/RPCEnvironment.pm +++ b/PVE/RPCEnvironment.pm @@ -3,7 +3,9 @@ package PVE::RPCEnvironment; use strict; use warnings; use POSIX qw(:sys_wait_h EINTR); +use IO::Handle; use IO::File; +use IO::Select; use Fcntl qw(:flock); use PVE::SafeSyslog; use PVE::Tools; @@ -11,6 +13,7 @@ use PVE::INotify; use PVE::Cluster; use PVE::ProcFSTools; use PVE::AccessControl; +use CGI; # we use this singleton class to pass RPC related environment values @@ -222,6 +225,51 @@ sub get { return $pve_env; } +sub parse_params { + my ($self, $enable_upload) = @_; + + if ($self->{request_rec}) { + my $cgi; + if ($enable_upload) { + $cgi = CGI->new($self->{request_rec}); + } else { + # disable upload using empty upload_hook + $cgi = CGI->new($self->{request_rec}, sub {}, undef, 0); + } + $self->{cgi} = $cgi; + my $params = $cgi->Vars(); + return $params; + } elsif ($self->{params}) { + return $self->{params}; + } else { + die "no parameters registered"; + } +} + +sub get_upload_info { + my ($self, $param) = @_; + + my $cgi = $self->{cgi}; + die "CGI not initialized" if !$cgi; + + my $pd = $cgi->param($param); + die "unable to get cgi parameter info\n" if !$pd; + my $info = $cgi->uploadInfo($pd); + die "unable to get cgi upload info\n" if !$info; + + my $res = { %$info }; + + my $tmpfilename = $cgi->tmpFileName($pd); + die "unable to get cgi upload file name\n" if !$tmpfilename; + $res->{tmpfilename} = $tmpfilename; + + #my $hndl = $cgi->upload($param); + #die "unable to get cgi upload handle\n" if !$hndl; + #$res->{handle} = $hndl->handle; + + return $res; +} + # init_request - must be called before each RPC request sub init_request { my ($self, %params) = @_; @@ -232,6 +280,11 @@ sub init_request { foreach my $p (keys %params) { if ($p eq 'userconfig') { $userconfig = $params{$p}; + } elsif ($p eq 'request_rec') { + # pass Apache2::RequestRec + $self->{request_rec} = $params{$p}; + } elsif ($p eq 'params') { + $self->{params} = $params{$p}; } else { die "unknown parameter '$p'"; } @@ -531,13 +584,17 @@ sub fork_worker { # same algorythm as used inside SA # STDIN = /dev/null my $fd = fileno (STDIN); - close STDIN; - POSIX::close(0) if $fd != 0; - die "unable to redirect STDIN - $!" - if !open(STDIN, "new_from_fd($psync[0], 'r'); + $select->add($fh); + + while ($select->count) { + my @handles = $select->can_read(1); + if (scalar(@handles)) { + my $count = sysread ($handles[0], $readbuf, 4096); + if (!defined ($count)) { + my $err = $!; + die "sync pipe read error: $err\n"; } - if ($outfh) { - print $outfh $line; - $outfh->flush(); + last if $count == 0; # eof + + $outbuf .= $readbuf; + while ($outbuf =~ s/^(([^\010\r\n]*)(\r|\n|(\010)+|\r\n))//s) { + my $line = $1; + my $data = $2; + if ($data =~ m/^TASK OK$/) { + # skip + } elsif ($data =~ m/^TASK ERROR: (.+)$/) { + print STDERR "$1\n"; + } else { + print $line; + } + if ($outfh) { + print $outfh $line; + $outfh->flush(); + } } + } else { + # some commands daemonize without closing stdout + last if !PVE::ProcFSTools::check_process_running($cpid); } } };