Тайм-аут PHP Curl, но Unix Curl не делает - PullRequest
0 голосов
/ 25 февраля 2011

--- Обновление внизу, оно связано с CURLOPT_COOKIE -

Я работаю на своем локальном компьютере (192.168.1.103), и у меня есть PHP-скрипт, который делает CURL-вызов для получения заголовка и содержимого, возвращаемого удаленным скриптом.

Я установил 2 копии удаленного скрипта, который должен возвращать его содержимое:
- Один на моей локальной машине, под тем же виртуальным хостом. (http://192.168.1.103/test/output_script.php)
- Один на удаленном сервере. (http://site.com/text/outputscript.php)

Сценарий CURL работает очень хорошо, когда я пытаюсь получить контент с удаленного сервера, но полностью истекает при попытке получить контент с локального сервера.

Подробное описание PHP CURL:

* About to connect() to 192.168.1.103 port 80 (#0)
*   Trying 192.168.1.103... * connected
* Connected to 192.168.1.103 (192.168.1.103) port 80 (#0)
> GET /app/getContent HTTP/1.1

Host: 192.168.1.103

Accept: */*

Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72



* Operation timed out after 5001 milliseconds with 0 bytes received
* Closing connection #0

Обратите внимание, что URI переписывается с помощью следующего файла .htaccess (в обоих местах):

RewriteEngine on

RewriteBase /cms/client1/public_html

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

Также обратите внимание, что я активировал журнал перезаписи и сравнил запрос, чтобы убедиться, что действие mod_rewrite было одинаковым во всех ситуациях. (Я на 100% уверен, что это не проблема переписывания)

Если я пытаюсь получить файл с помощью приложения CURL под Ubuntu, он работает хорошо:

$ curl -v --cookie PHPSESSID=u8spbervheh3tcrv62gcnc2j72 http://192.168.1.103/app/getContent
* About to connect() to 192.168.1.103 port 80 (#0)
*   Trying 192.168.1.103... connected
* Connected to 192.168.1.103 (192.168.1.103) port 80 (#0)
> GET /app/getContent HTTP/1.1
> User-Agent: curl/7.21.0 (i686-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
> Host: 192.168.1.103
> Accept: */*
> Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72
> 
< HTTP/1.1 403 Forbidden
< Date: Thu, 24 Feb 2011 21:40:17 GMT
< Server: Apache/2.2.16 (Ubuntu)
< X-Powered-By: PHP/5.3.3-1ubuntu9.3
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Vary: Accept-Encoding
< Content-Length: 82
< Content-Type: text/html; charset=UTF-8
< 
* Connection #0 to host 192.168.1.103 left intact
* Closing connection #0
WT_AUTH non défini. (strictement aucune authentification actuellement en session)

Ошибка 403 и содержимое WT_AUTH - это то, что я ожидаю получить вместо тайм-аута, который у меня есть с PHP.
Это также тот же (требуемый и правильный) результат, который я получу, если использовать php curl на удаленном сервере:

* About to connect() to site.com port 80 (#0)
*   Trying 123.123.123.123... * connected
* Connected to site.com (123.123.123.123) port 80 (#0)
> GET /app/getContent HTTP/1.1

Host: site.com

Accept: */*

Cookie: PHPSESSID=u8spbervheh3tcrv62gcnc2j72



< HTTP/1.1 403 Forbidden

< Date: Thu, 24 Feb 2011 21:45:30 GMT

< Server: Apache/2.2.16 (Debian) DAV/2 SVN/1.6.12 mod_fcgid/2.3.6

< Expires: Thu, 19 Nov 1981 08:52:00 GMT

< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

< Pragma: no-cache

< Content-Length: 28

< Content-Type: text/html; charset=UTF-8

< 

* Connection #0 to host site.com left intact
* Closing connection #0

И я тоже получу то же самое, если получу прямой доступ к 192.168.1.103/app/getContent в моем браузере.

Наконец, я также убедился, что скрипт getContent работает, поместив в него логи. Странная часть заключается в том, что если я запускаю запрос в 16:45:00, а время ожидания наступает в 16:45:05, зарегистрированные данные из сценария getContent будут датированы 16:45:05. Так что, если бы CURL поддерживал связь в «начальном» состоянии. И когда соединение закрыто, скрипт php разрешается запускать.

Есть идеи, что это не работает локально?

Если вы хотите взглянуть на код PHP, вот соответствующая часть:

$ressource = curl_init();
curl_setopt($ressource, CURLOPT_URL, $destinationUrl);
curl_setopt($ressource, CURLOPT_VERBOSE, true);
$handle = fopen(FRAMEWORK_ROOT . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'curl_debug.txt', 'w');
curl_setopt($ressource, CURLOPT_STDERR, $handle);

// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ressource, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ressource, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ressource, CURLOPT_RETURNTRANSFER, TRUE); //retourn content
curl_setopt($ressource, CURLOPT_HEADER, TRUE); //get HTTP headers
curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());
curl_setopt($ressource, CURLOPT_TIMEOUT, 5);


echo "\n<br />" . date('Y/m/d H:i:s');
$httpResponse = curl_exec($ressource);

echo "\n<br />" . date('Y/m/d H:i:s');
if(curl_errno($ressource) != 0)
     throw new Core_Exc_Def(curl_error($ressource)); // WILL THROW AN ERROR ON 192.168.1.103, BUT NOT ON THE REMOTE SITE.

Забавный факт: до добавления TIMEOUT загрузка была бесконечной. Местный сайт не отвечал, даже другие страницы. Мне нужно было перезапустить сервер apache, чтобы снова иметь доступ к сайту ...

Обновление:
Если я прокомментирую строку:

curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());

Это «работает» (это вызывает другую проблему, но ничего не связано с таймаутом). Оба сценария находятся на одном виртуальном хосте и используют один и тот же сеанс, но это не должно создавать CURL TimeOut?!

1 Ответ

4 голосов
/ 26 апреля 2011

Это происходит потому, что сессии заблокированы для записи. Когда вы пытаетесь соединиться с вашим сценарием с тем же сервером с тем же идентификатором session_id, второй сценарий ожидает, пока не будет снята блокировка сеанса.

Вам необходимо изменить session_id, который вы отправляете в запросе:

Изменение:

curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . session_id());

Кому:

curl_setopt($ressource, CURLOPT_COOKIE, session_name() . '=' . md5(session_id() . mktime()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...