[PATCH pve-storage v1 19/54] api: status: move up-/download file path parsing code into helper

Max R. Carrara
2026-04-22T11:18:12Z

Create a separate helper for the common file path parsing parts of the
upload / download_url API methods that returns the extension of the
uploaded file. Break up the if-elsif chain along the way.

Keep the inner if-clauses for the 'import' vtype inline for now for
further simplifications later, but don't check whether we have the
'import' vtype before those anymore. This is fine because the 'ova'
file extension is not used for files of any other vtype.

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
src/PVE/API2/Storage/Status.pm | 85 ++++++++++++++++++----------------
1 file changed, 45 insertions(+), 40 deletions(-)

diff --git a/src/PVE/API2/Storage/Status.pm b/src/PVE/API2/Storage/Status.pm
index 742596d4..3a798899 100644
--- a/src/PVE/API2/Storage/Status.pm
+++ b/src/PVE/API2/Storage/Status.pm
@@ -67,6 +67,41 @@ my sub assert_can_transfer_files : prototype($$$) {
return;
}

+my sub parse_transferred_file_path_extension : prototype($$) {
+ my ($path, $vtype) = @_;
+
+ if ($vtype eq 'iso') {
+ if ($path !~ m![^/]+$PVE::Storage::ISO_EXT_RE_0$!) {
+ raise_param_exc({ filename => "wrong file extension" });
+ }
+
+ my $ext = $1;
+ return $ext;
+ }
+
+ if ($vtype eq 'vztmpl') {
+ if ($path !~ m![^/]+$PVE::Storage::VZTMPL_EXT_RE_1$!) {
+ raise_param_exc({ filename => "wrong file extension" });
+ }
+
+ my $ext = $1;
+ return $ext;
+ }
+
+ if ($vtype eq 'import') {
+ if (
+ $path !~ m!${PVE::Storage::SAFE_CHAR_CLASS_RE}+$PVE::Storage::UPLOAD_IMPORT_EXT_RE_1$!
+ ) {
+ raise_param_exc({ filename => "invalid filename or wrong extension" });
+ }
+
+ my $ext = $1;
+ return $ext;
+ }
+
+ die "upload / download: failed to parse '$path' - unhandled content type '$vtype'\n";
+}
+
my sub assert_ova_contents {
my ($file) = @_;

@@ -614,27 +649,12 @@ __PACKAGE__->register_method({
my $is_ova = 0;
my $image_format;

- if ($content eq 'iso') {
- if ($filename !~ m![^/]+$PVE::Storage::ISO_EXT_RE_0$!) {
- raise_param_exc({ filename => "wrong file extension" });
- }
- } elsif ($content eq 'vztmpl') {
- if ($filename !~ m![^/]+$PVE::Storage::VZTMPL_EXT_RE_1$!) {
- raise_param_exc({ filename => "wrong file extension" });
- }
- } elsif ($content eq 'import') {
- if ($filename !~
- m!${PVE::Storage::SAFE_CHAR_CLASS_RE}+$PVE::Storage::UPLOAD_IMPORT_EXT_RE_1$!
- ) {
- raise_param_exc({ filename => "invalid filename or wrong extension" });
- }
- my $format = $1;
+ my $extension = parse_transferred_file_path_extension($filename, $content);

- if ($format eq 'ova') {
- $is_ova = 1;
- } else {
- $image_format = $format;
- }
+ if ($extension eq 'ova') {
+ $is_ova = 1;
+ } else {
+ $image_format = $extension;
}

my $path = plugin_get_vtype_subdir($scfg, $content);
@@ -843,27 +863,12 @@ __PACKAGE__->register_method({
my $is_ova = 0;
my $image_format;

- if ($content eq 'iso') {
- if ($filename !~ m![^/]+$PVE::Storage::ISO_EXT_RE_0$!) {
- raise_param_exc({ filename => "wrong file extension" });
- }
- } elsif ($content eq 'vztmpl') {
- if ($filename !~ m![^/]+$PVE::Storage::VZTMPL_EXT_RE_1$!) {
- raise_param_exc({ filename => "wrong file extension" });
- }
- } elsif ($content eq 'import') {
- if ($filename !~
- m!${PVE::Storage::SAFE_CHAR_CLASS_RE}+$PVE::Storage::UPLOAD_IMPORT_EXT_RE_1$!
- ) {
- raise_param_exc({ filename => "invalid filename or wrong extension" });
- }
- my $format = $1;
+ my $extension = parse_transferred_file_path_extension($filename, $content);

- if ($format eq 'ova') {
- $is_ova = 1;
- } else {
- $image_format = $format;
- }
+ if ($extension eq 'ova') {
+ $is_ova = 1;
+ } else {
+ $image_format = $extension;
}

my $path = plugin_get_vtype_subdir($scfg, $content);
--
2.47.3