2016-05-13 45 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

问题的更新应该作为问题的更新,而不是作为答案**。 –

相关问题