web-dev-qa-db-ja.com

cURLを使用してHTTPSサイトに接続できません。代わりに長さ0のコンテンツを返します。私に何ができる?

CURL(最新バージョン)を使用して支払い用の安全なゲートウェイに接続するサイトがあります。

問題は、cURLが常に長さ0のコンテンツを返すことです。ヘッダーのみを取得します。そして、ヘッダーを返すようにcURLを設定した場合のみ。次のフラグがあります。

_curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $gatewayURI);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
_

返されるヘッダーは

_HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 01:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Content-Type: text/html
Set-Cookie: ASPSESSIONIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
Cache-control: private
_

また、さまざまなサイトをcURLしてみましたが、コンテンツは正常に返されます。問題はhttps接続と関係があると思います。

私は会社と話しましたが、彼らは役に立たない。

他の誰かがこのエラーを経験し、回避策を知っていますか? cURLを捨ててfsockopen()を試してみるべきですか?

ありがとうございました。 :)

63
alex

Curl_error()のエラーメッセージも確認してください。 curl_ *関数ごとにこれを1回行う必要がある場合があります。

http://www.php.net/curl_error

33
too much php

今日も同じ問題がありました。 Curlには、HTTPS証明書を認証するための古いファイルが付属しています。

以下から新しいものを入手してください:

http://curl.haxx.se/ca/cacert.pem

サイトのいくつかのディレクトリに保存します

そして追加

curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem"); 

すべてのリクエストに:-)

CURLOPT_VERIFYPEERとCURLOPT_VERIFYHOSTを無効にすることについての馬鹿げたコメントは無視してください!!これにより、コードが中間者攻撃に対して脆弱になります。

2016年12月の編集:

下記のJasenの方法を使用して、これを適切に解決します。

curl.cainfo=/etc/ssl/certs/ca-certificates.crtをphp.iniに追加します

2017年10月編集:

現在、ca証明書の管理に役立つcomposerパッケージがあります。これにより、証明書の失効によりcacert.pemが古くなっても脆弱ではありません。

https://github.com/paragonie/certainty -> composer require paragonie/certainty:dev-master

98
SchizoDuckie

注:これは厳密には実稼働使用ではありません。すぐにデバッグしたい場合、これは役に立つかもしれません。それ以外の場合は、上記の@SchizoDuckieの回答を使用してください。

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 

追加するだけです。できます。

28
mixdev

非常によく似た問題があり、追加して解決しました

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

どうやら私がフェッチしているサイトは別の場所にリダイレクトされ、php-curlはデフォルトではリダイレクトに従いません。

6
Cobra_Fast

これが役立つ状況がありました:(Windows上のPHP 5.4.16)

curl_setopt($ch, CURLOPT_SSLVERSION, 3);
4
user203319

PHP/Curlで何かをテストするときはいつでも、最初にコマンドラインから試して、何が機能するかを理解し、それからオプションをPHPに移植します。

3
Issac Kelly

Httpsでエラーが発生しないように、Curl証明書を最新バージョンにアップグレードする必要がある場合があります。

2
Elzo Valugi

file_get_contentsを使用してstream_create_contextを使用しましたが、正常に動作します。

$postdataStr = http_build_query($postdataArr);

$context_options = array (
        'http' => array (    <blink> // this will allways be http!!!</blink>
            'method' => 'POST',
            'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
                . "Content-Length: " . strlen($postdataArr) . "\r\n"
                . "Cookie: " . $cookies."\r\n"
            'content' => $postdataStr
            )
        );

$context = stream_context_create($context_options);
$HTTPSReq = file_get_contents('https://www.example.com/', false, $context);
1
adyphp

Httpsを使用してセキュリティの問題を回避する最良の方法は、Firefox(または別のツール)を使用して、サーバーに証明書をダウンロードすることです。 このウェブページは私を大いに助けてくれました 、そしてこれらは私のために働いたステップでした:

1)Firefoxで、CURLで使用するURLを開きます

2)アドレスバーでpadlock> more informationをクリックします(FFバージョンにはさまざまなメニューがありますが、それを見つけてください)。クリック View certificate ボタン> Detailsタブ。

3)Certificate hierarchyで「正しい」証明書を強調表示します。私の場合、「cPanel、Inc. Certification Authority」と呼ばれる3つのうちの2番目でした。 「試行錯誤」の方法で正しいものを見つけました。

4)をクリックします Export ボタン。私の場合、働いていたのはファイルタイプ「チェーン付きPEM」でした(これも試行錯誤による)。

5)次に、PHPスクリプトの追加:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);    
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);

さらに、これらの手順はおそらく1年に1回、またはURL証明書が置換または更新されるたびにやり直す必要があるという事実に注意を払う必要があると思います。

0
Heitor

最近のアプリケーションプロジェクトでこのエラーを発見しました。コマンドラインまたはブラウザウィンドウから実行するように書いていたので、サーバー検出を使用して、要求しているドキュメントの相対URLを取得していました。問題は、サイトがhttpsであり、 http://(same server)にアクセスしようとするたびに、cURLがhttpsに変更してくれたことです。

これはブラウザからは正常に機能しますが、コマンドラインからは、両方の検証をfalseに設定してもSSLエラーが発生します。私がしなければならなかったことは、

1)$ _SERVER ['HTTP_Host']を確認します。存在する場合は、($ _ SERVER ['HTTPS']? "https://": "http://")。$ _ SERVER ['HTTP_Host']を使用します

2)$ _SERVER ['COMPUTERNAME']を確認し、本番サーバーと一致する場合は、https URLを提供します。 ( " https://(servername) ")

3)どちらの条件も満たさなかった場合、別のサーバーでコマンドラインを実行していることを意味し、「 http:// localhost 」を使用します。

これでうまくいきましたが、ハックです。また、1つのサーバー(https)でcURLがURLを変更したのに対し、他のサーバー(https)でURLが変更された理由を理解できませんでした。

奇妙な。

0
Michael