Skip to content

Commit

Permalink
unify remote.cgi and proxy.cgi
Browse files Browse the repository at this point in the history
  • Loading branch information
sni committed Sep 12, 2024
1 parent 2e3c27e commit 6366ff9
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 30 deletions.
3 changes: 2 additions & 1 deletion lib/Thruk.pm
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ sub startup {
$app = Plack::Middleware::Static->wrap($app,
path => sub {
my $p = Thruk::Context::translate_request_path($_, config());
return if $p =~ m%^/thruk/cgi\-bin/proxy\.cgi%mx;
return if $p =~ m%^/thruk/cgi\-bin/(remote|proxy)\.cgi%mx;
$p =~ /\.(css|png|js|gif|jpg|ico|html|wav|mp3|ogg|ttf|svg|woff|woff2|eot|map)$/mx;
},
root => './root/',
Expand Down Expand Up @@ -190,6 +190,7 @@ sub _build_app {
[ '^/thruk/r/v1.*' ,'Thruk::Controller::rest_v1::index' ],
[ '^/thruk/r/.*' ,'Thruk::Controller::rest_v1::index' ],
[ '^/thruk/cgi-bin/proxy.cgi/.*' ,'Thruk::Controller::proxy::index' ],
[ '^/thruk/cgi-bin/remote.cgi/.*' ,'Thruk::Controller::remote::index' ],
];

Thruk::Utils::Status::add_view({'group' => 'Main',
Expand Down
7 changes: 6 additions & 1 deletion lib/Thruk/Backend/Peer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ sub cmd {
my $req = HTTP::Request->new('POST', $url.'cgi-bin/remote.cgi', $header, $postdata);

require Thruk::Controller::proxy;
my $res = Thruk::Controller::proxy::proxy_request($c, $self->{'key'}, $url.'cgi-bin/remote.cgi', $req);
my $res = Thruk::Controller::proxy::proxy_request($c, $self->{'key'}, $url.'cgi-bin/remote.cgi', $req);
my $result;
eval {
$result = Cpanel::JSON::XS::decode_json($res->content());
Expand All @@ -368,6 +368,11 @@ sub cmd {
if($err) {
die(Thruk::Utils::http_response_error($res));
}
if(ref $result->{'output'} ne 'ARRAY') {
$out = $result->{'output'};
$rc = -1;
return($rc, $out);
}
($rc, $out) = @{$result->{'output'}};
if($background_options) {
($out) = @{$result->{'output'}};
Expand Down
16 changes: 14 additions & 2 deletions lib/Thruk/Controller/proxy.pm
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,21 @@ sub proxy_request {
my $request_url = Thruk::Utils::absolute_url($peer->{'addr'}, $url, 1);

# federated peers forward to the next hop
my $passthrough;
my($passthrough, $add_key);
if($peer->{'federation'} && scalar @{$peer->{'fed_info'}->{'type'}} >= 2 && $peer->{'fed_info'}->{'type'}->[1] eq 'http') {
$request_url = $peer->{'addr'};
$request_url =~ s|/cgi\-bin/remote\.cgi$||gmx;
$request_url =~ s|/thruk/?$||gmx;
$request_url = $request_url.'/thruk/cgi-bin/proxy.cgi/'.$peer->{'key'};
$request_url = $request_url.'/thruk/cgi-bin/remote.cgi/'.$peer->{'key'};
$passthrough = '/thruk/cgi-bin/proxy.cgi/'.$peer->{'key'}.$url;
} else {
# TODO: only if normal http request fails or so...
$request_url = $peer->{'addr'};
$request_url =~ s|/cgi\-bin/remote\.cgi$||gmx;
$request_url =~ s|/thruk/?$||gmx;
$request_url = $request_url.'/thruk/cgi-bin/remote.cgi';
$passthrough = $url;
$add_key = 1;
}

if($base_req->{'env'}->{'QUERY_STRING'}) {
Expand All @@ -107,6 +115,10 @@ sub proxy_request {
if($passthrough) {
$req->header('X-Thruk-Passthrough', $passthrough);
}
if($add_key) {
$req->header('X-Thruk-Auth-Key', $peer->{'class'}->{'auth'});
$req->header('X-Thruk-Auth-User', $c->user->{'username'}) if $c->user_exists;
}
my $ua = Thruk::UserAgent->new({}, $c->config);
$ua->max_redirect(0);
Thruk::UserAgent::disable_verify_hostname_by_url($ua, $request_url);
Expand Down
26 changes: 25 additions & 1 deletion lib/Thruk/Controller/remote.pm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,31 @@ Thruk Controller.

##########################################################
sub index {
my($c) = @_;
my($c, $path_info) = @_;

# proxy request
if($c->req->header('X-Thruk-Passthrough')) {
if(!$c->user_exists) {
$c->authenticate(skip_db_access => 1);
}
if(!$c->user_exists) {
$c->res->code(401);
return $c->render("text" => 'not authorized');
}
$c->user->set_dynamic_attributes($c);
#select(STDERR); $| = 1; select(STDOUT); $| = 1; use Data::Dumper; print STDERR Dumper($c->user);
require Thruk::Context;
require Thruk::Utils::CLI;
my $url = Thruk::Context::translate_request_path($c->req->header('X-Thruk-Passthrough'), $c->config);
my @res = Thruk::Utils::CLI::request_url($c, $url, undef, $c->req->method, $c->req->parameters);
if($res[1] && $res[1]->{'headers'}) {
$c->res->headers($res[1]->{'headers'}->clone());
}
$c->res->body($res[1]->{'result'} // $res[2]);
$c->res->code($res[0]);
$c->{'rendered'} = 1;
return;
}

Thruk::Utils::check_pid_file($c);

Expand Down
56 changes: 36 additions & 20 deletions lib/Thruk/Utils.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ sub proxifiy_me {
get_remote_thruk_url($c, $peer_key, [$full])
return url for remote thruk installation
return last http address in chain
=cut
sub get_remote_thruk_url {
Expand All @@ -1327,29 +1327,26 @@ sub get_remote_thruk_url {
confess("got no peer for id: ".$id) unless $peer;
my $url = "";
if($peer->{'fed_info'} && $peer->{'fed_info'}->{'addr'}) {
# use last address which starts with http
for my $u (reverse @{$peer->{'fed_info'}->{'addr'}}) {
if($u =~ m|^https?:|mx) {
if($u =~ m%^https?:%mx) {
$url = $u;
last;
}
}
}
if($peer->{'type'} eq 'http' && (!$url || $url !~ /^https?:/mx)) {
$url = $peer->{'addr'};
if(!$url || $url !~ m/^https?:\/\//mx) {
return("");
}
return($url || "") if $full;
if($url) {
if($url !~ m/^https?:\/\//mx) {
return("");
}
$url =~ s|^https?://[^/]*/?|/|gmx;
$url =~ s|cgi-bin\/remote\.cgi$||gmx;
$url =~ s|thruk/?$||gmx;
$url =~ s|/$||gmx;
$url = $url.'/thruk/';
}
return($url || "");

return($url) if $full;

$url =~ s|^https?://[^/]*/?|/|gmx;
$url =~ s|cgi-bin\/remote\.cgi$||gmx;
$url =~ s|thruk/?$||gmx;
$url =~ s|/$||gmx;
$url = $url.'/thruk/';

return($url);
}

########################################
Expand All @@ -1358,17 +1355,36 @@ sub get_remote_thruk_url {
get_remote_thruk_url_full($c, $peer_key)
returns ($proto, $hostname, $site)
returns ($proto, $hostname, $site, $addr) of last none-local address
=cut
sub get_remote_thruk_url_full {
my($c, $id) = @_;
my $url = get_remote_thruk_url($c, $id, 1);

my $peer = $c->db->get_peer_by_key($id);
confess("got no peer for id: ".$id) unless $peer;

my $url = "";
if($peer->{'fed_info'} && $peer->{'fed_info'}->{'addr'}) {
for my $u (reverse @{$peer->{'fed_info'}->{'addr'}}) {
next if $u =~ m%(127\.0\.0\.|localhost|::1|^/)%mx;
if($u =~ m%^(https?:|.*:\d+)%mx) {
$url = $u;
last;
}
}
}

return unless $url;

if($url =~ m|^(https?)://([^/]+)/([^/]+)/|gmx) {
return($1, $2, $3);
return($1, $2, $3, $url);
}

if($url =~ m|^(.*):(\d+)|gmx) {
return("", $1, undef, $url);
}

return;
}

Expand Down
16 changes: 16 additions & 0 deletions lib/Thruk/Utils/CLI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,22 @@ sub _internal_request {
delete $Thruk::thruk->{'TRANSFER_USER'} if $app->{'thruk'};
$Thruk::thruk->{'TRANSFER_USER'} = $user if defined $user;

# serve static files internally
if($url =~ m%/thruk/(vendor|javascript|themes)/%mx) {
my $file = Thruk->config->{home}.'/root'.$url;
if(-f $file) {
require Plack::MIME;
my $content_type = Plack::MIME->mime_type($file) || 'text/plain';
return(undef, undef,
HTTP::Response->new(
200, "OK",
HTTP::Headers->new( Content_Type => $content_type ),
Thruk::Utils::IO::read($file),
),
);
}
}

my $request = HTTP::Request->new($method, $url);
$request->method(uc($method));
if($postdata) {
Expand Down
11 changes: 7 additions & 4 deletions lib/Thruk/Utils/Filter.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2078,12 +2078,10 @@ sub peer_address_list {
my $peer = $c->db->get_peer_by_key($id);
confess("got no peer for id: ".$id) unless $peer;

my $mainAddr = $peer->{'addr'};
my($proto, $host, $site) = Thruk::Utils::get_remote_thruk_url_full($c, $id);
my($proto, $host, $site, $mainAddr) = Thruk::Utils::get_remote_thruk_url_full($c, $id);
my $http = "";
if($host) {
if($proto && $host) {
$http = CORE::sprintf('%s://%s/%s', $proto, $host, $site);
$mainAddr = $http;
}
my $full = [];
if($peer->{'fed_info'}) {
Expand All @@ -2094,6 +2092,11 @@ sub peer_address_list {
}
}

$mainAddr = $peer->{'addr'} unless $mainAddr;

$mainAddr =~ s|cgi-bin\/remote\.cgi$||gmx;
$mainAddr =~ s|thruk/?$||gmx;

return([$mainAddr, $http, $full]);
}

Expand Down
2 changes: 1 addition & 1 deletion templates/_header.tt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
</div>
<button class="noprint big primary round" title="reload page" id="refresh_button" onClick="refresh_button()"><i class="uil uil-sync"></i></button>
[%- IF c.user_exists || c.errored -%]
<button class="noprint big primary round" title="user preferences" onClick="toggleElementRemote('pref_pane', '_header_prefs', true); return false;"><i class="uil uil-cog"></i></button>
<button class="noprint big primary round" title="user preferences" onClick="toggleElementRemote('pref_pane', '_header_prefs', true); return false;"[% IF !c.user_exists %] disabled[% END %]><i class="uil uil-cog"></i></button>
[%- IF (cookie_auth && show_logout_button) || c.errored -%]
<form action="[% IF c.config.logout_link; c.config.logout_link; ELSE %][% url_prefix %]cgi-bin/login.cgi?logout[% END %]" method='POST' target='_top' style="display: initial;">
<button class="noprint big primary round" title="sign out"><i class="uil uil-signout"></i></button>
Expand Down

0 comments on commit 6366ff9

Please sign in to comment.