0

追加情報については、下部の編集を参照してください。

私は2つのサーバーを持っています。どちらも GET リクエストで互いに呼び出すことができるはずです。リクエストを行うには(実際にリクエストを行うよりもイベントを発生させます)、次のコードを使用しています:

function URLCallAsync($url, $params, $type='POST')
{
      foreach ($params as $key => &$val) {
        if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
      }
  $post_string = implode('&', $post_params);

  $parts=parse_url($url);

  $fp = fsockopen($parts['host'],
      isset($parts['port'])?$parts['port']:80,
      $errno, $errstr, 30);

  // Data goes in the path for a GET request
  if('GET' == $type) $parts['path'] .= '?'.$post_string;

  $out = "$type ".$parts['path']." HTTP/1.1\r\n";
  $out.= "Host: ".$parts['host']."\r\n";
  $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
  $out.= "Content-Length: ".strlen($post_string)."\r\n";
  $out.= "Connection: Close\r\n\r\n";
  // Data goes in the request body for a POST request
  if ('POST' == $type && isset($post_string)) $out.= $post_string;

  fwrite($fp, $out);
  fclose($fp);
}

両方のサーバーでまったく同じデータ(ただしURL)を関数にフィードします(呼び出しファイルをコピーしてテストしました!!)が、一方向にしか機能しません!

その関数の呼び出しをログ ファイルに書き込んで、何か問題が発生しているかどうかを調査できるようにします。

サーバー A -> サーバー B、正常に動作します。サーバー A のログファイルには正しい URL が含まれています。

サーバー B -> サーバー A は、サーバー B のログファイルに正しい情報のみを出力しますが、サーバー A は要求を受信しません。

このようなことの理由は何でしょうか?

編集:サーバーの種類が違うのでしょうか?サーバー A は nginx、サーバー B は apache です。サーバー A の URL にも「~」記号が含まれていますが、これが問題なのでしょうか? get リクエストのパラメータは php の「urlencode」でエンコードされているため、問題が発生する可能性がありますか?

少し試してみましたが、問題はまだリクエストがサーバー A に到達していないことです。しかし、ブラウザーからは何とか完全に機能します (パラメーターを使用して正しい URL を入力すると仮定します)。

edit2:「URLCallAsync」を「file_get_contents」と交換すると、正常に動作します。しかし、問題は file_get_contents がブロックしていることです! したがって、それは関数自体にしかなり得ません。しかし、奇妙なことに、それは反対方向に機能します:(

edit3: 関数「URLCallAsync」は、エラー、通知、またはその他の何もなしに実行されます。他のサーバーで受信されないだけです。file_get_contents は正確に何をしているのでしょうか?

4

1 に答える 1

0

私はそれを働かせました。

Wireshark をいじってみたところ、file_get_contents は私の非同期関数よりもさらに簡単であることがわかりました。

Content-Length フィールドを完全に省略しているだけです。「GET ...」と「Host」を提供するだけです。また、1.1 の代わりに HTTP/1.0 を使用しますが、何も変わりませんでした。

したがって、解決策は次のとおりです。Content-Lengthヘッダー(GETを使用したため、値が0でした)も投稿すると、サーバーがリクエストを拒否します。リクエストを拒否したのがサーバーだったのか、「不正な」リクエストを検出した可能性のあるファイアウォールのような何か他のものだったのかはわかりませんが、少なくとも問題は解決しています。

したがって、次にリクエストを送信するときは、必要がない場合は Content-Length ヘッダーを提供しないでください:)

于 2012-08-01T01:27:14.063 に答える