質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

12362閲覧

Content-Lengthを指定するとPHPのcURLライブラリが異様に遅くなる現象

ksakurai

総合スコア17

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/07/31 12:46

PHPのcURLライブラリでContent-Lengthを指定すると、
レスポンスが異様に遅くなるというか、返ってこなくなる事があります。
特定のサイトへの特定のリクエストで起きます。(もしかしたら、そのサイトにPOSTリクエストを送るときは、全部そうなるのかもしれません。)
そのような現象が起きる原因として考えられる要因はありますか?
ご教示いただけますと幸いです。
何卒宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Content-LengthとはHTTPボディの長さを表します。
リクエスト送信時はPOSTするデータの長さ
(※Content-Typeがapplication/x-www-form-urlencodedの場合は
key=value&key=valueの形式です。)
になります。
Content-Lengthと実際のボディの長さが一致しない場合、
特にContent-Lengthのが実際のボディデータより大きい場合、
サーバーは全部のデータを受信していないと判断し、すべてのデータを受信するまで待ちます。

同様に、レスポンスのContent-Lengthと実際のレスポンスボディが一致しない場合も
同様に全データを受信しようとして待機します。

待機しても、データは来ないので、最終的にタイムアウトになります。

投稿2017/07/31 13:04

Tak1016

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ksakurai

2017/08/01 02:47

ご回答いただきありがとうございます。 Content-Typeは、application/x-www-form-urlencodedです。 ボディ(key=value&key=valueの値)から、 strlenでContent-Lengthを計算して渡しているのですがそれで発生します。 これまで、同様のやり方でこの事象が発生したことはなかったので、 サーバー特有の原因があるのではと勝手に推測したりしていまいます。 また、Content-Length自体をヘッダに追加しなければ正常に送信が出来ます。 この場合、Content-Lengthは自動で補完されているのでしょうか? 解らないことばかりで申し訳ないのですが、 似たような事象を経験された方はいらっしゃいますか?
guest

0

Content-Lengthは基本、指定しなくても補完されます。
Content-Lengthは文字列の長さではなくバイトの長さです。
ボディの値はURLエンコーディングされているはずですし、UTF-8であれば1文字あたり、1~4byte消費します。

投稿2017/08/01 03:23

Tak1016

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ksakurai

2017/08/01 22:02

ご丁寧にご回答いただきありがとうございます。 Content-Lengthは基本的には補完されるんですね。 ようやく納得がいきました。 となると、どうもご指摘のあたりが怪しそうです。 しかし、Content-Lengthを指定しないとエラーが返ってくるAPIなどもあります。 Content-Lengthの補完はサーバー側で行われるということでしょうか? またPHPのリファレンスには、 strlenは文字列の長さではなく、バイト数を返すとあるのですが、 http://php.net/manual/ja/function.strlen.php こちら以外に、PHPで文字列のバイト数を取得する、もっと妥当な方法はありますでしょうか?
Tak1016

2017/08/02 00:58

リクエストヘッダーのContent-Length補完はクライアントが行います。 レスポンスヘッダーのContent-Lengthはサーバーです。 リクエストを送る際に--verboseをつけてみてください。送信したヘッダーの内容が出力されます。 Content-Lengthも自動的に入るはずです。 また、PHPを使ってるのであれば、ローカルのapacheにPHPを配置してローカルのPHPにcurlしてみるといいと思います。ローカルのPHPで受信したリクエストのヘッダーをすべて出力してみると、Content-Lengthがいくつになってるのか分かると思います。 strlenをするときにutf-8に変換していますか? また、リクエストの再にcharset-utf8を指定していますか?
ksakurai

2017/08/02 12:04

ご回答いただきありがとうございます。 申し訳ございません、試してみたのですが、やはり原因はわからずでした。 しかし、Content-Lengthをしたことによって受信が完了せずにレスポンスが返ってこないというのは、 事象からして納得のいく答えでしたので、本件は締めさせていただきたいと思います。 再度時間をかけて深く掘り下げてみようと思います。 何度もご回答いただき本当にありがとうございました。 大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問