我使用包WWW::Curl::Easy進行 API 呼叫,這是我的示例代碼:
use WWW::Curl::Easy;
my $curl = WWW::Curl::Easy->new();
$curl->setopt(CURLOPT_POST, 1);
$curl->setopt(CURLOPT_HEADER, 1);
$curl->setopt(CURLOPT_HTTPHEADER, ['Accept: text/xml; charset=utf-8', 'Content-Type:text/xml; charset=utf-8', 'SOAPAction: "importSheet"']);
$curl->setopt(CURLOPT_POSTFIELDS, $requestMessage);
$curl->setopt(CURLOPT_URL, $tom::{'setup'}{'api'}{'carrier'}{'url'});
my $response;
$curl->setopt(CURLOPT_WRITEDATA, \$response);
main::_log(Dumper(\$curl));
my $ret = $curl->perform();
我可以以某種方式轉儲整個請求$curl嗎?
我試過了,main::_log(Dumper(\$curl));但它沒有給我任何有用的東西。
我想查看整個請求,如真實的頭、方法、請求正文、發布資料等。我知道我可以在代碼中看到這些資訊,因為我將其設定為例如,CURLOPT_HTTPHEADER但我想轉儲“真實”請求(來自curl) 將被發送。
uj5u.com熱心網友回復:
最簡單的方法是CURLOPT_VERBOSE在您的程式中打開。
use WWW::Curl::Easy;
my $curl = WWW::Curl::Easy->new;
$curl->setopt(CURLOPT_HEADER,1);
$curl->setopt(CURLOPT_URL, 'http://example.com');
$curl->setopt(CURLOPT_WRITEDATA,\my $response_body);
# this turns on debugging a la `curl -v http://example.com`
$curl->setopt(CURLOPT_VERBOSE, 1);
my $retcode = $curl->perform;
print("Transfer went ok\n") unless $retcode;
輸出:
* Trying 93.184.216.34:80...
* TCP_NODELAY set
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
Host: example.com
Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Age: 543595
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Thu, 25 Nov 2021 14:20:18 GMT
< Etag: "3147526947 gzip"
< Expires: Thu, 02 Dec 2021 14:20:18 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (nyb/1D0F)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
* Connection #0 to host example.com left intact
Transfer went ok
如果你想要更花哨的東西,你必須自己動手。您可以CURLOPT_VERBOSE通過設定CURLOPT_DEBUGFUNCTION為 Perl 代碼參考來覆寫所做的事情。每一行除錯輸出都會呼叫它。
簽名似乎與 libcurl 檔案中的不同,但可以推斷出正在發生的事情。
$curl->setopt(CURLOPT_VERBOSE, 1);
$curl->setopt(CURLOPT_DEBUGFUNCTION, sub {
use Data::Dumper;
print Dumper \@_;
});
帶有此集合的前幾行輸出如下所示。
[
[0] " Trying 93.184.216.34:80...
",
[1] undef,
[2] 0
]
[
[0] "TCP_NODELAY set
",
[1] undef,
[2] 0
]
[
[0] "Connected to example.com (93.184.216.34) port 80 (#0)
",
[1] undef,
[2] 0
]
[
[0] "GET / HTTP/1.1
Host: example.com
Accept: */*
",
[1] undef,
[2] 2
]
第一個引數似乎是文本。
根據檔案,有幾種型別的除錯資料。
typedef enum { CURLINFO_TEXT = 0, CURLINFO_HEADER_IN, /* 1 */ CURLINFO_HEADER_OUT, /* 2 */ CURLINFO_DATA_IN, /* 3 */ CURLINFO_DATA_OUT, /* 4 */ CURLINFO_SSL_DATA_IN, /* 5 */ CURLINFO_SSL_DATA_OUT, /* 6 */ CURLINFO_END } curl_infotype;
鑒于我的最后一個例子有 a2并且所有其他例子都有 a0作為他們的第三個引數,我們可以假設這一定是型別。
我還沒有弄清楚第二個引數是什么。
這給我們留下了:
$curl->setopt(CURLOPT_DEBUGFUNCTION, sub {
my ($text, undef, $type) = @_;
# ...
});
碰巧的是,這些型別已被 WWW::Curl::Easy 作為常量匯入。所以我們可以做這樣的事情來只獲取傳出的標頭。
$curl->setopt(CURLOPT_DEBUGFUNCTION, sub {
my ($text, undef, $type) = @_;
print $text if $type == CURLINFO_HEADER_OUT;
});
這將輸出:
$ /usr/bin/perl foo.pl
GET / HTTP/1.1
Host: example.com
Accept: */*
Transfer went ok
傳入的標頭似乎一次一個,因此您可以進行過濾。
$curl->setopt(CURLOPT_DEBUGFUNCTION, sub {
my ($text, undef, $type) = @_;
if ($type == CURLINFO_HEADER_IN && $text =~ m/Etag: "(. )"/) {
print "Etag is $1\n";
}
});
一個更復雜的例子是獲取整個除錯輸出并將其轉換為HTTP::Request和HTTP::Response物件。
$curl->setopt(CURLOPT_WRITEDATA,\$response_body);
$curl->setopt(CURLOPT_VERBOSE, 1);
my ($req, $res);
$curl->setopt(CURLOPT_DEBUGFUNCTION, sub {
my ($text, undef, $type) = @_;
require HTTP::Request;
require HTTP::Response;
if ($type == CURLINFO_HEADER_OUT) {
$req = HTTP::Request->parse($text);
} elsif ($type == CURLINFO_DATA_OUT) {
$req->content($text);
} elsif ($type == CURLINFO_HEADER_IN) {
unless ($res) {
$res = HTTP::Response->parse($text);
$res->request($req);
return 0; # this is retcode
}
# this is from HTTP::Message
# (https://metacpan.org/dist/HTTP-Message/source/lib/HTTP/Message.pm#L60)
my @hdr;
while (1) {
if ($text =~ s/^([^\s:] )[ \t]*: ?(.*)\n?//) {
push(@hdr, $1, $2);
$hdr[-1] =~ s/\r\z//;
}
elsif (@hdr && $text =~ s/^([ \t].*)\n?//) {
$hdr[-1] .= "\n$1";
$hdr[-1] =~ s/\r\z//;
}
else {
$text =~ s/^\r?\n//;
last;
}
}
$res->header(@hdr) if @hdr;
} elsif ($type == CURLINFO_DATA_IN) {
$res->content($text);
}
return 0; # this is retcode
});
這將為您提供一個 HTTP::Request 和一個 HTTP::Response 物件,每個物件都包含所有標頭和內容。不確定這是否有用,但它很好地演示了此功能的可能性。
免責宣告:我是 libwww-perl 的維護者。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/366958.html
上一篇:從現有的x、y、z列添加幾何列
下一篇:使用空手道下載檔案
