2016-05-13 76 views
0

我正試圖重新創建一個工作CURL命令與Perl中的LWP和我得到LWP 401未經授權的錯誤。該命令將JSON發佈到特定的URL,如下面的代碼所示。服務器FQDN,IP,端口和路徑在curl和Perl之間是正確和相同的,證書和領域也是如此。任何幫助將不勝感激 - 謝謝!Perl LWP未經授權雖然捲曲Ok

下面是捲曲和調試器輸出的工作語法:

#curl -v -k -u "USERNAME:PASSWORD" -X POST <SERVER_URL> -d '<JSON CONTENT>'; 

* About to connect() to <SERVER_URL> port 443 (#0) 
* Trying <SERVER_IP>... connected 
* Connected to <SERVER_URL> (<SERVER_IP>) port 443 (#0) 
* Initializing NSS with certpath: sql:/etc/pki/nssdb 
* warning: ignoring value of ssl.verifyhost 
* skipping SSL peer certificate verification 
* SSL connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
* Server certificate: 
*  subject: [REDACTED] 
*  start date: Apr 21 00:00:00 2016 GMT 
*  expire date: Apr 21 23:59:59 2019 GMT 
*  common name: <SERVER_URL> 
*  issuer: [REDACTED] 
* Server auth using Basic with user '<USERNAME>' 
> POST <SERVER_PATH> HTTP/1.1 
> Authorization: Basic <BASE64-ENCODED USERNAME:PASSWORD> 
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 
> Host: <SERVER_URL> 
> Accept: */* 
> Content-Length: 144 
> Content-Type: application/x-www-form-urlencoded 
> 
< HTTP/1.1 200 OK 
< Date: Fri, 13 May 2016 13:48:42 GMT 
< Server: Apache 
< Content-Type: application/json 
< Content-Length: 256 
< 
* Connection #0 to host <SERVER_URL> left intact 
* Closing connection #0 

更新Perl代碼和輸出每斯特芬的建議。我校正的初始引用錯誤,並且還添加了Accept首部到LWP po​​st命令:

use strict; 
use warnings; 
use LWP::UserAgent; 
use Data::Dumper; 

my $server_root_with_port = "<FQDN>:443"; 
my $url = "<SERVER_URL>"; 
my $realm = "<SERVER_REALM>"; 
my $json = "<JSON CONTENT>"; 
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); 
$ua->credentials($server_root_with_port,$realm,$username=>$password); 
$response = $ua->post($url, 'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => '*/*', 'Content' => $json); 
print Dumper $response; 

exit; 

$VAR1 = bless({ 
     '_protocol' => 'HTTP/1.1', 
     '_content' => '', 
     '_rc' => '400', 
     '_headers' => bless({ 
        'connection' => 'close', 
        'client-response-num' => 1, 
        'date' => 'Mon, 16 May 2016 14:18:59 GMT', 
        'client-ssl-cert-issuer' => '[REDACTED]', 
        'client-ssl-cipher' => 'AES128-SHA256', 
        'client-peer' => '<SERVER_IP>:443', 
        'content-length' => '0', 
        '::std_case' => { 
           'client-date' => 'Client-Date', 
           'client-response-num' => 'Client-Response-Num', 
           'client-ssl-cert-subject' => 'Client-SSL-Cert-Subject', 
           'client-ssl-cert-issuer' => 'Client-SSL-Cert-Issuer', 
           'client-ssl-cipher' => 'Client-SSL-Cipher', 
           'client-peer' => 'Client-Peer', 
           'client-ssl-socket-class' => 'Client-SSL-Socket-Class' 
          }, 
        'client-date' => 'Mon, 16 May 2016 14:18:59 GMT', 
        'client-ssl-cert-subject' => '[REDACTED]', 
        'server' => 'Apache', 
        'client-ssl-socket-class' => 'IO::Socket::SSL' 
         }, 'HTTP::Headers'), 
     '_previous' => bless({ 
        '_protocol' => 'HTTP/1.1', 
        '_content' => '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
          <html><head> 
          <title>401 Unauthorized</title> 
          </head><body> 
          <h1>Unauthorized</h1> 
          <p>This server could not verify that you 
          are authorized to access the document 
          requested. Either you supplied the wrong 
          credentials (e.g., bad password), or your 
          browser doesn\'t understand how to supply 
          the credentials required.</p> 
          </body></html> 
          ', 
        '_rc' => '401', 
        '_headers' => bless({ 
           'connection' => 'close', 
           'client-response-num' => 1, 
           'date' => 'Mon, 16 May 2016 14:18:59 GMT', 
           'client-ssl-cert-issuer' => '[REDACTED]', 
           'client-ssl-cipher' => 'AES128-SHA256', 
           'client-peer' => '<SERVER_IP>:443', 
           'content-length' => '381', 
           '::std_case' => { 
              'client-date' => 'Client-Date', 
              'client-response-num' => 'Client-Response-Num', 
              'client-ssl-cert-subject' => 'Client-SSL-Cert-Subject', 
              'title' => 'Title', 
              'client-ssl-cert-issuer' => 'Client-SSL-Cert-Issuer', 
              'client-ssl-cipher' => 'Client-SSL-Cipher', 
              'client-peer' => 'Client-Peer', 
              'client-ssl-socket-class' => 'Client-SSL-Socket-Class' 
             }, 
           'client-date' => 'Mon, 16 May 2016 14:18:59 GMT', 
           'content-type' => 'text/html; charset=iso-8859-1', 
           'client-ssl-cert-subject' => '[REDACTED]', 
           'www-authenticate' => 'Basic realm="<SERVER_REALM>"', 
           'title' => '401 Unauthorized', 
           'server' => 'Apache', 
           'client-ssl-socket-class' => 'IO::Socket::SSL' 
            }, 'HTTP::Headers'), 
        '_msg' => 'Unauthorized', 
        '_request' => bless({ 
           '_content' => '<JSON_CONTENT>', 
           '_uri' => bless(do{\(my $o = '<SERVER_URL>')}, 'URI::https'), 
           '_headers' => bless({ 
               'user-agent' => 'libwww-perl/6.15', 
               'content-type' => 'application/x-www-form-urlencoded', 
               'accept' => '*/*', 
               'content-length' => 144, 
               '::std_case' => { 
                'if-ssl-cert-subject' => 'If-SSL-Cert-Subject' 
                 } 
              }, 'HTTP::Headers'), 
           '_method' => 'POST', 
           '_uri_canonical' => $VAR1->{'_previous'}{'_request'}{'_uri'} 
            }, 'HTTP::Request') 
         }, 'HTTP::Response'), 
     '_msg' => 'Bad Request', 
     '_request' => bless({ 
        '_protocol' => undef, 
        '_content' => '<JSON_CONTENT>', 
        '_uri' => bless(do{\(my $o = '<SERVER_URL>')}, 'URI::https'), 
        '_headers' => bless({ 
            'user-agent' => 'libwww-perl/6.15', 
            'content-type' => 'application/x-www-form-urlencoded', 
            'accept' => '*/*', 
            'content-length' => 144, 
            'authorization' => '<BASE64-ENCODED USERNAME:PASSWORD>', 
            '::std_case' => { 
             'if-ssl-cert-subject' => 'If-SSL-Cert-Subject' 
              } 
           }, 'HTTP::Headers'), 
        '_method' => 'POST', 
        '_uri_canonical' => $VAR1->{'_request'}{'_uri'} 
         }, 'HTTP::Request') 
      }, 'HTTP::Response'); 

Perl的修訂#1:

use strict; 
use warnings; 
use LWP::UserAgent; 
use HTTP::Request::Common; 
use Data::Dumper; 

my $fqdn_port = "<FQDN>:443"; 
my $url  = "<URL>"; 
my $realm  = "<REALM>"; 
my $username = "<USERNAME>"; 
my $password = "<PASSWORD>"; 
my $json  = "<JSON_CONTENT>"; 

my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); 

#$ua->credentials($fqdn_port,$realm,$username=>$password); 
#my $response = $ua->post($url, 'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => '*/*', Content => $json); 

my $request = HTTP::Request->new('POST',$url); 
$request->header('Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => '*/*'); 
$request->authorization_basic($username,$password); 
$request->content($json); 

my $response = $ua->request($request); 

print Dumper $response; 

exit; 


$VAR1 = bless({ 
     '_protocol' => 'HTTP/1.1', 
     '_content' => '', 
     '_rc' => '400', 
     '_headers' => bless({ 
        'connection' => 'close', 
        'client-response-num' => 1, 
        'date' => 'Mon, 16 May 2016 15:41:10 GMT', 
        'client-ssl-cert-issuer' => '[REDACTED]', 
        'client-ssl-cipher' => 'AES128-SHA256', 
        'client-peer' => '<SERVER_IP>:443', 
        'content-length' => '0', 
        '::std_case' => { 
           'client-date' => 'Client-Date', 
           'client-response-num' => 'Client-Response-Num', 
           'client-ssl-cert-subject' => 'Client-SSL-Cert-Subject', 
           'client-ssl-cert-issuer' => 'Client-SSL-Cert-Issuer', 
           'client-ssl-cipher' => 'Client-SSL-Cipher', 
           'client-peer' => 'Client-Peer', 
           'client-ssl-socket-class' => 'Client-SSL-Socket-Class' 
          }, 
        'client-date' => 'Mon, 16 May 2016 15:41:10 GMT', 
        'client-ssl-cert-subject' => '[REDACTED]', 
        'server' => 'Apache', 
        'client-ssl-socket-class' => 'IO::Socket::SSL' 
         }, 'HTTP::Headers'), 
     '_msg' => 'Bad Request', 
     '_request' => bless({ 
        '_content' => '<JSON_CONTENT>', 
        '_uri' => bless(do{\(my $o = '<URL>')}, 'URI::https'), 
        '_headers' => bless({ 
            'user-agent' => 'libwww-perl/6.15', 
            'content-type' => 'application/x-www-form-urlencoded', 
            'accept' => '*/*', 
            '::std_case' => { 
             'if-ssl-cert-subject' => 'If-SSL-Cert-Subject' 
              }, 
            'authorization' => 'Basic <BASE64-ENCODED USERNAME:PASSWORD>' 
           }, 'HTTP::Headers'), 
        '_method' => 'POST', 
        '_uri_canonical' => $VAR1->{'_request'}{'_uri'} 
         }, 'HTTP::Request') 
      }, 'HTTP::Response'); 
+0

verify_hostname => 1應該是=> 0,表示將匹配捲曲-k – gfunk

回答

2

TL; TR:總是use strict !!

$response = $ua->post($url, Content-Type => 'application/json', Content => $json); 

你已經錯過了報價周圍會被use strict檢測Content-Type。這這個結果是一個奇怪的頭0您在調試輸出中看到:

'content-type' => 'application/x-www-form-urlencoded', 
'0' => 'application/json', 
'content-length' => 144, 

而這也意味着,內容類型的設置是錯誤的。在服務器這共同作用的結果不接受你的要求:

'_rc' => '400', 
    ... 
    '_msg' => 'Bad Request', 

要了解這裏發生了什麼看什麼的Perl在這樣的代碼實際看到:

$ perl -MO=Deparse -e 'my %x = (Content-Type => 1, Foo => 2)' 
my(%x) = ('Content' - 'Type', 1, 'Foo', 2); 

這表明它會解釋未加引號Content-Type'Content' - 'Type'。由於沒有爲字符串定義減法,它們將被轉換爲整數,即0。這意味着結果是00-0)。

當使用嚴格的你,而不是:

perl -Mstrict -e 'my %x = (Content-Type => 1, Foo => 2)'                                 
Bareword "Content" not allowed while "strict subs" in use at -e line 1.                                   
Execution of -e aborted due to compilation errors. 
+0

斯特芬 - 我更新了我的代碼,如你所說,封閉的Content-Type單引號,所以造成語法寫着「內容類型'=>'application/json'並嚴格使用我沒有收到錯誤,但是我仍然收到401未經授權的錯誤。 – dthumb

+0

@dthumb:請更新代碼並調試問題中的輸出以反映當前狀態。 –

+0

根據建議更新了原始問題編輯 - 不再看到格式錯誤的標題,但仍然從服務器獲得401未授權返回。謝謝。 – dthumb

0

找到了解決辦法 - 也許不是最優雅,但它的伎倆。最後使用HTTP :: Request :: Common解決授權問題,並將JSON變量的引用反轉,以減輕400錯誤請求和成功 - 從服務器獲得正確的返回結果!感謝@steffen_ullrich的幫助。

use strict; 
use warnings; 
use LWP::UserAgent; 
use HTTP::Request::Common; 
use Data::Dumper; 

my $fqdn_port = "<FQDN>:443"; 
my $url  = "<URL>"; 
my $realm  = "<REALM>"; 
my $username = "<USERNAME>"; 
my $password = "<PASSWORD>"; 
my $json  = '<JSON_CONTENT>'; 

my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); 
my $request = HTTP::Request->new('POST',$url); 
$request->header('Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => '*/*'); 
$request->authorization_basic($username,$password); 
$request->content($json); 

my $response = $ua->request($request); 
print Dumper $response; 
exit; 


$VAR1 = bless({ 
     '_protocol' => 'HTTP/1.1', 
     '_content' => '<RETURN JSON FROM SERVER>', 
     '_rc' => '200', 
     '_headers' => bless({ 
        'connection' => 'close', 
        'client-response-num' => 1, 
        'date' => 'Mon, 16 May 2016 16:07:07 GMT', 
        'client-ssl-cert-issuer' => '[REDACTED]', 
        'client-ssl-cipher' => 'AES128-SHA256', 
        'client-peer' => '<SERVER_IP>:443', 
        'content-length' => '233', 
        '::std_case' => { 
           'client-date' => 'Client-Date', 
           'client-response-num' => 'Client-Response-Num', 
           'client-ssl-cert-subject' => 'Client-SSL-Cert-Subject', 
           'client-ssl-cert-issuer' => 'Client-SSL-Cert-Issuer', 
           'client-ssl-cipher' => 'Client-SSL-Cipher', 
           'client-peer' => 'Client-Peer', 
           'client-ssl-socket-class' => 'Client-SSL-Socket-Class' 
          }, 
        'client-date' => 'Mon, 16 May 2016 16:07:07 GMT', 
        'content-type' => 'application/json', 
        'client-ssl-cert-subject' => '[REDACTED]', 
        'server' => 'Apache', 
        'client-ssl-socket-class' => 'IO::Socket::SSL' 
         }, 'HTTP::Headers'), 
     '_msg' => 'OK', 
     '_request' => bless({ 
        '_content' => '<JSON_CONTENT>', 
        '_uri' => bless(do{\(my $o = '<URL>')}, 'URI::https'), 
        '_headers' => bless({ 
            'user-agent' => 'libwww-perl/6.15', 
            'content-type' => 'application/x-www-form-urlencoded', 
            'accept' => '*/*', 
            '::std_case' => { 
             'if-ssl-cert-subject' => 'If-SSL-Cert-Subject' 
              }, 
            'authorization' => 'Basic <BASE64-ENCODED USERNAME:PASSWORD>' 
           }, 'HTTP::Headers'), 
        '_method' => 'POST', 
        '_uri_canonical' => $VAR1->{'_request'}{'_uri'} 
         }, 'HTTP::Request') 
      }, 'HTTP::Response'); 
+0

問題的更新應該作爲問題的更新,而不是作爲答案**。 –

相關問題