rework formatter registration

Do the whole thing inside PVE/APIServer/Formatter.pm
This commit is contained in:
Dietmar Maurer 2017-01-14 10:25:10 +01:00
parent 63307bebd9
commit c715437597
3 changed files with 47 additions and 32 deletions

View File

@ -657,7 +657,7 @@ sub handle_api2_request {
my ($rel_uri, $format) = &$split_abs_uri($path, $self->{base_uri}); my ($rel_uri, $format) = &$split_abs_uri($path, $self->{base_uri});
my $formatter = PVE::APIServer::Formatter::get_formatter($format); my $formatter = PVE::APIServer::Formatter::get_formatter($format, $method, $rel_uri);
if (!defined($formatter)) { if (!defined($formatter)) {
$self->error($reqstate, HTTP_NOT_IMPLEMENTED, "no such uri $rel_uri, $format"); $self->error($reqstate, HTTP_NOT_IMPLEMENTED, "no such uri $rel_uri, $format");
@ -738,12 +738,6 @@ sub handle_api2_request {
$delay = 0 if $delay < 0; $delay = 0 if $delay < 0;
} }
if ($res->{info} && $res->{info}->{formatter}) {
if (defined(my $func = $res->{info}->{formatter}->{$format})) {
$formatter = $func;
}
}
my ($raw, $ct, $nocomp) = &$formatter($res, $res->{data}, $params, $path, $auth); my ($raw, $ct, $nocomp) = &$formatter($res, $res->{data}, $params, $path, $auth);
my $resp; my $resp;

View File

@ -3,53 +3,74 @@ package PVE::APIServer::Formatter;
use strict; use strict;
use warnings; use warnings;
use URI::Escape;
# generic formatter support # generic formatter support
# PVE::APIServer::Formatter::* classes should register themselves here # PVE::APIServer::Formatter::* classes should register themselves here
my $formatter_hash = {}; my $formatter_hash = {};
my $page_formatter_hash = {};
sub register_formatter { sub register_formatter {
my ($format, $func) = @_; my ($format, $code) = @_;
die "formatter '$format' already defined" if $formatter_hash->{$format}; die "formatter '$format' already defined"
if defined($formatter_hash->{$format});
$formatter_hash->{$format} = { $formatter_hash->{$format} = $code;
func => $func, }
};
sub register_page_formatter {
my (%config) = @_;
my $format = $config{format} ||
die "missing format";
my $path = $config{path} ||
die "missing path";
my $method = $config{method} ||
die "missing method";
my $code = $config{code} ||
die "missing formatter code";
die "duplicate page formatter for '$method: $path'"
if defined($page_formatter_hash->{$format}->{$method}->{$path});
$page_formatter_hash->{$format}->{$method}->{$path} = $code;
} }
sub get_formatter { sub get_formatter {
my ($format) = @_; my ($format, $method, $path) = @_;
return undef if !$format; return undef if !defined($format);
my $info = $formatter_hash->{$format}; if (defined($method) && defined($path)) {
return undef if !$info; my $code = $page_formatter_hash->{$format}->{$method}->{$path};
return $code if defined($code);
}
return $info->{func}; return $formatter_hash->{$format};
} }
my $login_formatter_hash = {}; my $login_formatter_hash = {};
sub register_login_formatter { sub register_login_formatter {
my ($format, $func) = @_; my ($format, $code) = @_;
die "login formatter '$format' already defined" if $login_formatter_hash->{$format}; die "login formatter '$format' already defined"
if defined($login_formatter_hash->{$format});
$login_formatter_hash->{$format} = { $login_formatter_hash->{$format} = $code;
func => $func,
};
} }
sub get_login_formatter { sub get_login_formatter {
my ($format) = @_; my ($format) = @_;
return undef if !$format; return undef if !defined($format);
my $info = $login_formatter_hash->{$format}; return $login_formatter_hash->{$format};
return undef if !$info;
return $info->{func};
} }
# some helper functions # some helper functions

View File

@ -170,11 +170,11 @@ PVE::APIServer::Formatter::register_formatter($portal_format, sub {
my ($res, $data, $param, $path, $auth) = @_; my ($res, $data, $param, $path, $auth) = @_;
# fixme: clumsy! # fixme: clumsy!
PVE::API2::Formatter::Standard::prepare_response_data($portal_format, $res); PVE::APIServer::Formatter::Standard::prepare_response_data($portal_format, $res);
$data = $res->{data}; $data = $res->{data};
my $html = ''; my $html = '';
my $doc = PVE::API2::Formatter::Bootstrap->new($res, $path); my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path);
if (!HTTP::Status::is_success($res->{status})) { if (!HTTP::Status::is_success($res->{status})) {
$html .= $doc->alert(text => "Error $res->{status}: $res->{message}"); $html .= $doc->alert(text => "Error $res->{status}: $res->{message}");
@ -243,14 +243,14 @@ PVE::APIServer::Formatter::register_formatter($portal_format, sub {
return ($raw, $portal_ct); return ($raw, $portal_ct);
}); });
PVE::RESTHandler->register_page_formatter( PVE::APIServer::Formatter::register_page_formatter(
'format' => $portal_format, 'format' => $portal_format,
method => 'GET', method => 'GET',
path => "/access/ticket", path => "/access/ticket",
code => sub { code => sub {
my ($res, $data, $param, $path, $auth) = @_; my ($res, $data, $param, $path, $auth) = @_;
my $doc = PVE::API2::Formatter::Bootstrap->new($res, $path); my $doc = PVE::APIServer::Formatter::Bootstrap->new($res, $path);
my $html = &$login_form($doc); my $html = &$login_form($doc);
@ -258,7 +258,7 @@ PVE::RESTHandler->register_page_formatter(
return ($raw, $portal_ct); return ($raw, $portal_ct);
}); });
PVE::RESTHandler->register_page_formatter( PVE::APIServer::Formatter::register_page_formatter(
'format' => $portal_format, 'format' => $portal_format,
method => 'POST', method => 'POST',
path => "/access/ticket", path => "/access/ticket",