通过代理服务器进行SSL连接

时间:2014-04-18 15:06:24

标签: php curl ssl proxy

我正在尝试连接到Twitter api服务器以进行“仅限应用程序的身份验证”。 我不关心任何其他方式连接到Twitter。我需要这种特定的方法。

我需要从localhost通过我公司的代理转到需要ssl的api.twitter.com

按照此Twitter开发者页面https://dev.twitter.com/docs/auth/application-only-auth的说明,我尝试了:

卷曲:

try {
    $ch = curl_init();    
    curl_setopt($ch, CURLOPT_URL, $url);
    if ($this->proxy != '') {
        curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
        curl_setopt($ch, CURLOPT_PROXYPORT, $this->port);
        curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->userpwd);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSLVERSION, 3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("
         POST /oauth2/token HTTP/1.1
         Host: api.twitter.com
         User-Agent: My Twitter App v1.0.23
         Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
         Content-Length: 29
         Accept-Encoding: gzip
         grant_type=client_credentials
    "));
    $response = curl_exec($ch);
    if (FALSE === $response) throw new Exception(curl_error($ch), curl_errno($ch));
        curl_close($ch);
        var_dump(json_decode($response));
} 
catch(Exception $e) {
    trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}

哪个给了我

  

致命错误:卷曲失败,错误#35:与api.twitter.com相关的未知SSL协议错误

的file_get_contents:

$context = stream_context_create(array(
    "http" => array(
    "method"=>"CONNECT",
    "proxy" => $this->proxy.":".$this->port,
    "request_fulluri" => true,
    "header" => "
        POST /oauth2/token HTTP/1.1
        Host: api.twitter.com
        User-Agent: My Twitter App v1.0.23
        Proxy-Authorization: Basic ".base64_encode(urlencode($this->userpwd))."
        Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
        Content-Type: application/x-www-form-urlencoded;charset=UTF-8
        Content-Length: 29
        Accept-Encoding: gzip
        grant_type=client_credentials
        ",
    ),
));
$response = file_get_contents($url, False, $context);
var_dump(json_decode($response));

哪个给了我

  

警告:file_get_contents(https://api.twitter.com/oauth2/token)[function.file-get-contents]:无法打开流:无法通过代理连接到HTTPS服务器

的fsockopen:

$fp = fsockopen($this->proxy, $this->port);
fputs($fp, "
    POST /oauth2/token HTTP/1.1
    Host: api.twitter.com
    User-Agent: My Twitter App v1.0.23
    Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
    Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    Content-Length: 29
    Accept-Encoding: gzip
    grant_type=client_credentials
");
$data="";
while (!feof($fp)) $data .= fgets($fp,1024);
fclose($fp);
var_dump($data);

哪个给了我

HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 727

我确信443端口是打开的,这不是localhost的问题(我在在线服务器上尝试了同样的错误)。

我甚至尝试使用CONNECT方法而不是POST。 我尝试了隧道代理,但我不确定我是不是也不是那个问题。

我的想法很少......

2 个答案:

答案 0 :(得分:1)

尝试删除此内容:

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

这个数组中只有一个值,这是错误的。

curl_setopt($ch, CURLOPT_HTTPHEADER, array("
         POST /oauth2/token HTTP/1.1
         Host: api.twitter.com
         User-Agent: My Twitter App v1.0.23
         Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
         Content-Length: 29
         Accept-Encoding: gzip
         grant_type=client_credentials
    "));

为此改变上述内容:

$consumer_key = base64_encode(urlencode($consumer_key);
$consumer_secret = urlencode($consumer_secret);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
         "Host: api.twitter.com",
         "User-Agent: My Twitter App v1.0.23",
         "Authorization: Basic $consumer_key:$consumer_secret",
         "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
         "Accept-Encoding: gzip",
         "grant_type=client_credentials"
         ));

如果要包含Content-Length: xx,则需要使用strlen()来获取帖子的字符串长度,ex;

$length = strlen($post_content);

然后将其添加到CURLOPT_HTTPHEADER数组:

"Content-Length: $length"

答案 1 :(得分:0)

发现问题。没有必要(可能只在这种情况下,我不确定)base64编码凭证。它们将由服务器编码。

我不知道不同错误响应的原因,但实际上是双重编码的问题,因为服务器无法验证我的凭据。