【发布时间】:2014-03-25 11:44:18
【问题描述】:
我正在与似乎已损坏的 HTTP 守护程序交谈,我需要发出一个 GET 请求,该请求在 URL 中包含一个管道 | 字符。
LWP::UserAgent 在发送请求之前转义管道字符。
例如,传入的 URL 为:
https://hostname/url/doSomethingScript?ss=1234&activities=Lec1|01
被传递给 HTTP 守护进程
https://hostname/url/doSomethingScript?ss=1234&activities=Lec1%7C01
这是正确的,但不适用于这个损坏的服务器。
如何覆盖或绕过 LWP 及其朋友正在执行的编码?
注意
我在 StackOverflow 上看到并尝试了其他解决类似问题的答案。这里的区别似乎是这些答案正在处理POST 请求,其中URL 的formfield 部分可以作为键/值对数组或'Content' => $content 参数传递。这些方法不适用于我的 LWP 请求。
我还尝试构建一个HTTP::Request 对象并将其传递给LWP,并将完整的URL 直接传递给LWP->get()。两种方法都没有骰子。
应 Borodin 的要求,这是我正在使用的代码的净化版本
#!/usr/local/bin/perl -w
use HTTP::Cookies;
use LWP;
my $debug = 1;
# make a 'browser' object
my $browser = LWP::UserAgent->new();
# cookie handling...
$browser->cookie_jar(HTTP::Cookies->new(
'file' => '.cookie_jar.txt',
'autosave' => 1,
'ignore_discard' => 1,
));
# proxy, so we can watch...
if ($debug == 1) {
$browser->proxy(['http', 'ftp', 'https'], 'http://localhost:8080/');
}
# user agent string (pretend to be Firefox)
$agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.7.12) Gecko/20050919 Firefox/1.0.7';
# set the user agent
$browser->agent($agent);
# do some things here to log in to the web site, accept session cookies, etc.
# These are basic POSTs of filled forms. Works fine.
# [...]
my $baseURL = 'https://hostname/url/doSomethingScript?ss=1234&activities=VALUEA|VALUEB';
@values = ['Lec1', '01', 'Lec1', '02'];
while (1) {
if (scalar(@values) < 2) { last; }
my $vala = shift(@values);
my $valb = shift(@values);
my $url = $basEURL;
$url =~ s/VALUEA/$vala/g;
$url =~ s/VALUEB/$valb/g;
# simplified. Would usually check request for '200' response, etc...
$content = $browser->get($url)->content();
# do something here with the content
# [...]
# fails because the '|' character in the url is escaped after it's handed
# to LWP
}
# end
【问题讨论】:
-
作为一个兴趣点,我发现了 LWP::Curl 模块及其 auto_encode() 方法。我已经能够证明,如果这样创建一个对象:
$lwpcurl = LWP::Curl->new();并设置$lwpcurl->auto_encode(0);,带有我在问题中描述的形式的 URL 的后续请求将传递给 HTTP 守护程序,而无需进一步处理。对我来说,使用 LWP::UserAgent 仍然比 LWP::Curl 更可取(我必须重新编写很多代码),所以我会让我的问题继续存在,希望有人能够帮助。 -
LWP 库设计得非常好,几乎每个点都有钩子。请出示您的代码。你在打一个简单的
$ua->get电话吗?您是否尝试过构建HTTP::Request对象并在其上调用$ua->request? -
由 HTTP::Request 使用的 URI 类完成
-
作为 stackoverflow 新手,我无法回答自己的问题。所以,一个评论:我已经找到了一种方法来完成这项工作,在 Joe Schaefer 的帖子 (#13) 中的 perlmonks 线程 computer-programming-forum.com/53-perl/11cfc4991e0b3d0a.htm 中。本质上,创建一个
HTTP::Request对象,传入“损坏的”url:my $url = 'hostname/url/…';我的 $request = HTTP:Request->new(GET => $url);HTTP::Request修改 URL: print $request->as_string;证明了这一点。 ... -
付出了这么多努力为未来的读者留下了一个解释,你很可能仅仅通过这个问题就产生了足够的代表。欢迎来到 SO。