簡體   English   中英

使用TeamCity REST API進行Perl HTTP請求POST失敗

[英]Perl HTTP Request POST fails with TeamCity REST API

我有一個Perl腳本,通過REST API備份我們的TeamCity服務器,如下所示:

use strict;
use LWP::UserAgent;
use HTTP::Request::Common qw{ POST GET }

# ... code ommitted for brevity ... #

my $url = 'http://teamcity:8080/httpAuth/app/rest/server/backup';
my $req = POST( $url . '?includeConfigs=true&includeDatabase=true&includeBuildLogs=true&fileName=' . $filename);   
$req->authorization_basic($username, $password);
my $resp = $ua->request($req);    

我嘗試根據HTTP:Request的文檔發布內容,但由於某種原因它失敗,並抱怨我沒有指定文件名:

# This fails
my $req= POST( $url, [ 'includeConfigs'   => 'true',
                            'includeDatabase'  => 'true',
                            'includeBuildLogs' => 'true',
                            'fileName'         => $filename, 
                          ] ); 

但是,當我查看TeamCity的后端REST日志時,完整的請求似乎使它完整無缺,並且與上面傳遞的請求相同。

成功命令的日志:

[2012-12-13 15:02:38,574]  DEBUG [www-perl/5.805 ] - rver.server.rest.APIController - REST API request received: POST '/httpAuth/app/rest/server/backup?includeConfigs=true&includeDatabase=true&includeBuildLogs=true&fileName=foo', from client 10.126.31.219, authenticated as jsmith 

失敗命令的日志:

[2012-12-13 14:57:00,649]  DEBUG [www-perl/5.805 ] - rver.server.rest.APIController - REST API request received: POST '/httpAuth/app/rest/server/backup?includeConfigs=true&includeDatabase=true&includeBuildLogs=true&fileName=foo', from client 10.126.31.219, authenticated as jsmith

發出POST請求的兩種方法之間是否存在其他可能導致失敗的隱藏差異?

更新:這是通過Data :: Dumper打印時每個請求的結果

成功的POST:

$VAR1 = bless( {
             '_content' => '',
             '_uri' => bless( do{\(my $o = 'http://teamcity:8080/httpAuth/app/rest/server/backup?includeConfigs=true&includeDatabase=true&includeBuildLogs=true&fileName=foo')}, 'URI::http' ),
             '_headers' => bless( {
                                    'content-type' => 'application/x-www-form-urlencoded',
                                    'content-length' => 0,
                                    'authorization' => 'Basic c3lzQnVpbGRTeXN0ZW1JOnBhaWQuZmFpdGg='
                                  }, 'HTTP::Headers' ),
             '_method' => 'POST'
           }, 'HTTP::Request' );

POST不成功:

$VAR1 = bless( {
             '_content' => 'includeConfigs=true&includeDatabase=true&includeBuildLogs=true&fileName=foo',
             '_uri' => bless( do{\(my $o = 'http://teamcity:8080/httpAuth/app/rest/server/backup')}, 'URI::http' ),
             '_headers' => bless( {
                                    'content-type' => 'application/x-www-form-urlencoded',
                                    'content-length' => 75,
                                    'authorization' => 'Basic c3lzQnVpbGRTeXN0ZW1JOnBhaWQuZmFpdGg='
                                  }, 'HTTP::Headers' ),
             '_method' => 'POST'
           }, 'HTTP::Request' );

我認為您的服務器端腳本只能處理URL中編碼的GET參數,而不能處理通過標准輸入傳輸的POST數據。 請注意,HTTP描述了幾種不同的方法,分別是GETPOSTHEADDELETE等。然后,有兩種方法可以將數據傳遞到服務器上的應用程序。 最常見的一種方式也稱為GET parameters ,另一種方式稱為POST data因為GET parameters通常與HTTP GET方法一起使用,而POST data通常用於HTTP POST方法。 但是,他們不必這樣做。 而且我認為您在成功情況下將HTTP POST方法與GET parameters混合在一起,在失敗情況下與POST data混合在一起。

GET parameters是通過URL傳遞的,通常是通過附加?來傳遞的? 網址,后跟實際的鍵/值pais。 這些可以通過某些環境變量在服務器上運行的腳本中使用。 由腳本來拆分&處的變量,在=上拆分鍵/值對並撤消轉義。

對於POST data ,環境變量CONTENT_LENGTH告訴腳本從其標准輸入讀取多少字節。 實際的鍵/值對通過不同的編碼(通常作為多部分編碼的內容)傳輸。 是的, POST HTTP請求(主要來自HTML <form> )也可以像GET parameters一樣通過URL編碼發送,但是HTTP標准對包括所有參數的URL施加了長度限制。 因此,通過標准輸入而不是通過URL傳輸數據的方法。

現在看來,您的服務器端腳本可以評估URL編碼的參數(也稱為GET parameters )參數,但不能評估通過標准輸入發布到該參數的數據。 即使您使用POST HTTP方法/動詞,在成功的情況下,實際上也不會通過標准輸入將值作為POST data傳輸。 在這種情況下,您可以簡單地將POST(...)換成GET(...) ,它仍然可以正常工作。

在不成功的情況下,請使用POST HTTP方法和POST data傳輸值的方式。

在某些情況下,我在這里的說法可能是錯誤的,但基本原理仍然可以。

my $url= my $url = 'http://teamcity:8080/httpAuth/app/rest/server/backup';
my $req= POST( $url, { 'includeConfigs'   => 'true',
                            'includeDatabase'  => 'true',
                            'includeBuildLogs' => 'true',
                            'fileName'         => $filename, 
                          } ); 

注意“ {}”(哈希引用,而不是數組引用)。 同樣,不將查詢字符串(GET)語法與POST語法混合使用也很有助於弄清問題。

干杯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM