如何在Perl中模仿wget或curl的行为
How to imitate in Perl the behaviour of wget or curl
我是 Perl 和 ActiveMQ 的新手。
我下载了这个 Perl nagios program 来检查 ActiveMQ 队列。问题是程序存在于主要的 Perl 行中:
my $page = get "http://admin:admin\@$address:$port/admin/xml/queues.jsp" or die "Cannot get XML file: $!\n";;
我将该行替换为其他行以检查 return 代码:
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
my $page = $ua->get("http://admin:admin\@$address:$port/admin/xml/queues.jsp");
if ($page->is_success) {
print $page->decoded_content; # or whatever
}
else {
die $page->status_line;
}
现在,它报告:
401 Unauthorized
但是wget
仍然可以下载页面:
Connecting to 127.0.0.1:8161... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Reusing existing connection to 127.0.0.1:8161.
HTTP request sent, awaiting response... 200 OK
Length: 2430 (2.4K) [text/xml]
Saving to: `queues.jsp'
如何配置 UserAgent
以使 get
调用模仿 wget
行为?
你知道另一个 script/program 来监控 ActiveMQ 队列吗?
有没有办法以纯文本形式获取队列值?然后我会写下我自己的 bash 脚本。
更新 1
正如@mob 所要求的,这是 wget --debug
的输出
DEBUG output created by Wget 1.12 on linux-gnu.
--2017-09-06 19:27:15-- http://admin:*password*@127.0.0.1:8161/admin/xml/queues.jsp
Connecting to 127.0.0.1:8161... connected.
Created socket 3.
Releasing 0x0000000002586c10 (new refcount 0).
Deleting unused 0x0000000002586c10.
---request begin---
GET /admin/xml/queues.jsp HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 127.0.0.1:8161
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 401 Unauthorized
WWW-Authenticate: basic realm="ActiveMQRealm"
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 1293
Connection: keep-alive
Server: Jetty(7.6.9.v20130131)
---response end---
401 Unauthorized
Registered socket 3 for persistent reuse.
Skipping 1293 bytes of body: [<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 401 Unauthorized</title>
</head>
<body>
<h2>HTTP ERROR: 401</h2>
<p>Problem accessing /admin/xml/queues.jsp. Reason:
<pre> Unauthorized</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
] done.
Reusing existing connection to 127.0.0.1:8161.
Reusing fd 3.
---request begin---
GET /admin/xml/queues.jsp HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 127.0.0.1:8161
Connection: Keep-Alive
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=o7kaw1kbzcy91dozx82c8dq2j;Path=/admin
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/xml;charset=ISO-8859-1
Content-Length: 2430
Connection: keep-alive
Server: Jetty(7.6.9.v20130131)
---response end---
200 OK
Stored cookie 127.0.0.1 8161 /admin <session> <insecure> [expiry none] JSESSIONID o7kaw1kbzcy91dozx82c8dq2j
Length: 2430 (2.4K) [text/xml]
Saving to: `queues.jsp'
100%[================================================================================>] 2,430 --.-K/s in 0s
2017-09-06 19:27:15 (395 MB/s) - `queues.jsp' saved [2430/2430]
两次尝试的 ---request begin---
部分的唯一区别是
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
仅在第二次尝试时找到。
LWP::UserAgent 不解析 URL 的 username:password
部分。我怀疑这是为了阻止将 username:password 放在 URL 中的不安全做法,这样它很容易从程序和服务器日志中被盗。
您可以覆盖 get_basic_credentials
以从 URL 中提取用户名和密码。这并不能解决安全问题。
或者您可以在 HTTP::Request
对象上调用 authorization_basic
来为此特定请求设置用户名和密码。
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $url);
$req->authorization_basic($user, $password);
my $res = $ua->request($req);
或者您可以在 UserAgent 上调用 credentials
来为各种 host/port 组合设置密码,而不仅仅是一个请求。这就像将您的密码存储在浏览器中,其中 $ua
是浏览器。
my $ua = LWP::UserAgent->new;
$ua->credentials("$host:$port", $realm, $user, $password);
my $req = $ua->get($url);
或者您可以切换到功能较少但设计更好的 HTTP::Tiny or the slightly more featureful HTTP::Tiny::UA。它将解析并使用 URL.
的 username:password
部分
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $res = $ua->get($url);
我是 Perl 和 ActiveMQ 的新手。
我下载了这个 Perl nagios program 来检查 ActiveMQ 队列。问题是程序存在于主要的 Perl 行中:
my $page = get "http://admin:admin\@$address:$port/admin/xml/queues.jsp" or die "Cannot get XML file: $!\n";;
我将该行替换为其他行以检查 return 代码:
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
my $page = $ua->get("http://admin:admin\@$address:$port/admin/xml/queues.jsp");
if ($page->is_success) {
print $page->decoded_content; # or whatever
}
else {
die $page->status_line;
}
现在,它报告:
401 Unauthorized
但是wget
仍然可以下载页面:
Connecting to 127.0.0.1:8161... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Reusing existing connection to 127.0.0.1:8161.
HTTP request sent, awaiting response... 200 OK
Length: 2430 (2.4K) [text/xml]
Saving to: `queues.jsp'
如何配置 UserAgent
以使 get
调用模仿 wget
行为?
你知道另一个 script/program 来监控 ActiveMQ 队列吗?
有没有办法以纯文本形式获取队列值?然后我会写下我自己的 bash 脚本。
更新 1
正如@mob 所要求的,这是 wget --debug
DEBUG output created by Wget 1.12 on linux-gnu.
--2017-09-06 19:27:15-- http://admin:*password*@127.0.0.1:8161/admin/xml/queues.jsp
Connecting to 127.0.0.1:8161... connected.
Created socket 3.
Releasing 0x0000000002586c10 (new refcount 0).
Deleting unused 0x0000000002586c10.
---request begin---
GET /admin/xml/queues.jsp HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 127.0.0.1:8161
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 401 Unauthorized
WWW-Authenticate: basic realm="ActiveMQRealm"
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 1293
Connection: keep-alive
Server: Jetty(7.6.9.v20130131)
---response end---
401 Unauthorized
Registered socket 3 for persistent reuse.
Skipping 1293 bytes of body: [<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 401 Unauthorized</title>
</head>
<body>
<h2>HTTP ERROR: 401</h2>
<p>Problem accessing /admin/xml/queues.jsp. Reason:
<pre> Unauthorized</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
] done.
Reusing existing connection to 127.0.0.1:8161.
Reusing fd 3.
---request begin---
GET /admin/xml/queues.jsp HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 127.0.0.1:8161
Connection: Keep-Alive
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=o7kaw1kbzcy91dozx82c8dq2j;Path=/admin
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/xml;charset=ISO-8859-1
Content-Length: 2430
Connection: keep-alive
Server: Jetty(7.6.9.v20130131)
---response end---
200 OK
Stored cookie 127.0.0.1 8161 /admin <session> <insecure> [expiry none] JSESSIONID o7kaw1kbzcy91dozx82c8dq2j
Length: 2430 (2.4K) [text/xml]
Saving to: `queues.jsp'
100%[================================================================================>] 2,430 --.-K/s in 0s
2017-09-06 19:27:15 (395 MB/s) - `queues.jsp' saved [2430/2430]
两次尝试的 ---request begin---
部分的唯一区别是
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
仅在第二次尝试时找到。
LWP::UserAgent 不解析 URL 的 username:password
部分。我怀疑这是为了阻止将 username:password 放在 URL 中的不安全做法,这样它很容易从程序和服务器日志中被盗。
您可以覆盖 get_basic_credentials
以从 URL 中提取用户名和密码。这并不能解决安全问题。
或者您可以在 HTTP::Request
对象上调用 authorization_basic
来为此特定请求设置用户名和密码。
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $url);
$req->authorization_basic($user, $password);
my $res = $ua->request($req);
或者您可以在 UserAgent 上调用 credentials
来为各种 host/port 组合设置密码,而不仅仅是一个请求。这就像将您的密码存储在浏览器中,其中 $ua
是浏览器。
my $ua = LWP::UserAgent->new;
$ua->credentials("$host:$port", $realm, $user, $password);
my $req = $ua->get($url);
或者您可以切换到功能较少但设计更好的 HTTP::Tiny or the slightly more featureful HTTP::Tiny::UA。它将解析并使用 URL.
的username:password
部分
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $res = $ua->get($url);