Я бы изменил только несколько вещей.
Сначала замените блок кода после первого блока комментария следующим образом:
my $query = new CGI;
my $file = $query->params('img');
Ваш код для получения расширения файла не работает для меня. Это делает:
my ($ext) = $file =~ m/\.([^\.]+)$/;
Я не понимаю использования "my $ image = do {...". Это просто не кажется необходимым.
Поскольку вы уже используете модуль CGI, используйте его для создания своих заголовков:
print $query->header(
-type => 'image/' . $ext,
-Content_length => $length,
);
То, как вы читаете файл и выписываете его обратно, выглядит функционально идеально.
У меня есть несколько дополнительных комментариев и предложений. Во-первых, ваш код крайне небезопасен. Приятно, что вы думаете о режиме taint, но ничего не делаете с именем файла, переданным вашим клиентом. Что, если они передали "/ etc / passwd", например? Во-вторых, вы также можете открыть свой файл изображения (после дополнительных проверок безопасности) до отправки заголовков HTTP. Это позволит вам отправить разумную ошибку обратно клиенту (404?), А не просто умереть. Используйте метод "заголовка" CGI, чтобы сделать это легко. Вы все еще можете написать что-нибудь в STDERR, если хотите.
Это все, что я могу думать только сейчас. Надеюсь, этого достаточно, чтобы вы пошли.