2

Amazon AWS SQS WSDL(位于https://sqs.us-east-1.amazonaws.com/doc/2009-02-01/QueueService.wsdl)列出了具有不同“地址”的多个“端口”(靠近底部文件),它指定服务的 HTTP 和 HTTPS 地址。

使用 PHP SOAP 对象:

$aws_ns = 'http://security.amazonaws.com/doc/2007-01-01/';
$sc = new SoapClient('https://sqs.us-east-1.amazonaws.com/doc/2009-02-01/QueueService.wsdl');
$sc->__setSoapHeaders(new SoapHeader($aws_ns, 'AWSAccessKeyId', 'MyAccessKey'));
$action = "ListQueues";
$ts = date('c');
$hash = base64_encode(hash_hmac('sha1', $action.$ts, 'MyPrivateKey', true));
try {
  $rs = $sc->__soapCall($action, array(), NULL, array(
    new SoapHeader($aws_ns, 'Signature', $hash),
    new SoapHeader($aws_ns, 'Timestamp', $ts)
  ));
} catch (SoapFault $f) {
  echo "ERROR: ".$f->faultcode."-".$f->faultstring."\n";
}

运行该代码会给出“错误:后向兼容的 SOAP 身份验证所需的 aws:Client.RequiresSSL-SSL 连接。”;它使用第一个“端口”(HTTP 端口)联系 AWS 服务,这种身份验证不允许这样做。

如果我在 之前添加一个$sc->__setLocation('https://queue.amazonaws.com');(从 WSDL 文件复制和粘贴的 URL)行__soapCall,它可以正常工作,但是我如何告诉 SoapClient 对象使用 WSDL 中的另一个端口,而不是将其作为静态字符串提供,在万一他们改变了HTTPS URL呢?

4

1 回答 1

1

据我所知,没有简单的方法可以告诉 SoapClient 使用另一个。如果只需要http进行https更改,并且所有其他条件都相同,则可以使用自己的类覆盖某些方法:

class HttpsPortSoapClient extends Soapclient {
  function __doRequest($request,$location,$action,$version,$one_way = 0 ){
    $locationparts = parse_url($location);
    if(isset($locationparts['scheme']) && $locationparts['scheme'] == 'http'){
      if(function_exists('http_build_url')){
        $location = http_build_url($locationparts,array('scheme'=>'https'));
      } else {
        //the long way around:
        $location = 'https://';
        if(isset($locationparts['user'])){
          $location .= $locationparts['user'];
          if(isset($locationparts['pass']))$location .= ':'.$locationparts['pass'];
          $location .= '@';
        }
        if(isset($locationparts['host']))  $location .= $locationparts['host'];
        if(isset($locationparts['port']))  $location .= ':'.$locationparts['port'];
        if(isset($locationparts['path']))  $location .= $locationparts['path'];
        if(isset($locationparts['query'])) $location .= '?'.$locationparts['query'];
      }
    }
    return parent::__doRequest($request,$location,$action,$version,$one_way);
  }
}

如果方法确实不同,您可能想要覆盖该__construct方法,加载 XML,并清理或删除对“http”端口而不是“https”端口的任何引用。不过,它看起来越来越像编写自己的soapclient :)

于 2010-07-25T17:10:06.907 回答