【问题标题】:How to imitate in Perl the behaviour of wget or curl如何在 Perl 中模仿 wget 或 curl 的行为
【发布时间】:2017-09-06 12:32:14
【问题描述】:

我是 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";;

我用其他行替换了该行来检查返回码:

 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 行为?

您知道另一个用于监控 de 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

仅在第二次尝试中发现。

【问题讨论】:

  • \@ 转义也不用单引号展开。
  • @simbabque 我错误地发布了我的代码的第一次尝试。然后我意识到并改为双引号。
  • 使用--debug 标志运行 wget 以查看它如何从最初的 401 响应中恢复。
  • @Schwern,谢谢,我修改了我的帖子。但我这篇文章显示了一个端口号(8161),这不是我的 ActiveMQ 服务器的实际端口号。
  • @Jdamian 甚至不要发布测试密码。它们经常被用作真正的密码。如果没有,他们会深入了解您如何制作密码。例如,这个太短了,太简单了。这些图案说它的手工制作和创造是为了记住。他们告诉我你没有使用密码生成器或密码管理器,或者你没有明智地使用它,所以你的密码会很弱。我建议你养成对所有事情都使用密码管理器的习惯。

标签: perl activemq wget nagios


【解决方案1】:

LWP::UserAgent 不解析 URL 的 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 为各种主机/端口组合设置密码,而不仅仅是一个请求。这就像将您的密码存储在浏览器中,其中$ua 是浏览器。

  my $ua = LWP::UserAgent->new;
  $ua->credentials("$host:$port", $realm, $user, $password);
  my $req = $ua->get($url);

或者您可以切换到功能较少但设计更好的HTTP::Tiny 或功能稍强的HTTP::Tiny::UA。它将解析并使用 URL 的 username:password 部分。

  use HTTP::Tiny;
  my $ua = HTTP::Tiny->new;
  my $res = $ua->get($url);

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 2012-12-10
    • 1970-01-01
    • 2011-04-19
    • 2018-11-14
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多