【问题标题】:How can I detect the file type of image at a URL?如何检测 URL 中图像的文件类型?
【发布时间】:2009-07-14 12:20:12
【问题描述】:

如何在 Perl 表单网站 URL 中查找图片文件类型?

例如,

$image_name = "logo";
$image_path = "http://stackoverflow.com/content/img/so/".$image_name 

从这些信息中如何找到 .这里应该显示的示例

"png"

http://stackoverflow.com/content/img/so/logo.png . 

假设它有更多文件,如 SO web site 。它应该显示所有文件类型

【问题讨论】:

  • 请根据文件的内容或网络服务器告诉客户端的任何谎言来判断您是否想知道类型。
  • 仅供参考:我已在答案中添加了代码以根据内容检测类型。

标签: perl image url file


【解决方案1】:

如果您使用 LWP 来获取图像,您可以查看 HTTP 服务器返回的 content-type 标头。

WWW::MechanizeLWP::UserAgent 都会为任何 GET 请求提供一个 HTTP::Response 对象。所以你可以这样做:

use strict;
use warnings;

use WWW::Mechanize;

my $mech = WWW::Mechanize->new;
$mech->get( "http://stackoverflow.com/content/img/so/logo.png" );
my $type = $mech->response->headers->header( 'Content-Type' );

【讨论】:

  • 使用这个方法我可以达到我的要求
【解决方案2】:

你不能轻易说出来。 URL 不一定反映图像的类型。

要获取图像类型,您必须通过 HTTP(GET,或更有效的 HEAD)发出请求,并检查 HTTP 响应中的 Content-type 标头。

【讨论】:

  • 它只是应用程序,不像网络
  • 以上正是您标记为实现您的要求的两个问题的情况:-)
【解决方案3】:

嗯,https://stackoverflow.com/content/img/so/logo 是 404。如果不是,那么您可以使用

#!/usr/bin/perl

use strict;
use warnings;

use LWP::Simple;

my ($content_type) = head "https://stackoverflow.com/content/img/so/logo.png";

print "$content_type\n" if defined $content_type;

__END__

作为Kent Fredric points out,网络服务器告诉您的内容类型不必与网络服务器发送的实际内容相匹配。请记住,File::MMagic 也可能被欺骗。

#!/usr/bin/perl
use strict;
use warnings;

use File::MMagic;
use LWP::UserAgent;

my $mm = File::MMagic->new;

my $ua = LWP::UserAgent->new(
    max_size => 1_000 * 1_024,
);

my $res = $ua->get('https://stackoverflow.com/content/img/so/logo.png');

if ( $res->code eq '200' ) {
    print $mm->checktype_contents( $res->content );
}
else {
    print $res->status_line, "\n";
}
__END__

【讨论】:

  • 这种方式我也可以,但我必须找到网络服务所有不同的内容类型
  • 使用这个方法我可以实现我的要求
【解决方案4】:

您确实无法根据 URL 甚至内容类型标头对内容做出假设。

它们只是发送内容的指南

混淆使用后缀匹配来识别文件类型的东西的一个方便的技巧是这样做:

  http://example.com/someurl?q=foo#fakeheheh.png

如果您任意允许将该图像添加到页面中,则在某些情况下,如果浏览器跟随它,它可能会成为某种攻击的入口。 (例如,http://really_awful_bank.example.com/transfer?amt=1000000;from=123;to=123

基于内容类型的伪造并不是那么有害,但是如果控制名称的人知道您如何识别事物并为 HEAD 请求发送与 GET 请求不同的内容类型,那么您可能会做一些令人讨厌的事情。

它可以告诉 HEAD 请求它是一个图像,然后告诉 GET 请求它是一个application/javascript,天知道这会导致什么。

确定知道它是什么的唯一方法是下载文件,然后进行基于 MAGIC 的识别,或者更多(即尝试解码图像)。然后,您只需要担心太大的图像,以及可能触发尚未针对该漏洞修补的计算机中的漏洞的特制图像。

尽管以上所有这些都是极端偏执狂,但如果你知道罕见的可能性,你可以确保它们不会发生:)

【讨论】:

  • +1 用于指出不实际下载文件并检查它的缺陷。
  • 在我的答案中添加了代码以处理您提出的一些问题。
【解决方案5】:

据我了解,您并不担心您已经知道名称+扩展名的图像的内容类型,而是希望找到您知道基本名称的图像的扩展名。

为了做到这一点,您必须单独测试您想要的所有图片扩展,并存储哪些已解决,哪些未解决。例如https://stackoverflow.com/content/img/so/logo.pnghttps://stackoverflow.com/content/img/so/logo.gif 都可能存在。他们不在这种确切的情况下,但是在某些任意服务器上,您可以拥有多个具有相同基本名称但扩展名不同的图像。不幸的是,没有办法通过提供其基本名称来获取远程 Web 目录中文件的可用扩展名列表,而无需遍历所有可能性。

【讨论】:

  • 这是字面上的问题,但从后来的 cmets 看来,这显然不是真正想要的:)
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 2015-12-04
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2021-06-17
相关资源
最近更新 更多