curl https проблемы с отправкой запроса

slim-akim

Новичок
curl https проблемы с отправкой запроса

Здравствуйте!
Друзья, надеюсь, вы сможете подсказать советом или поделиться опытом по возникшей у меня проблеме. Ситуация такая: реализуется виджет "поиск авиабилетов", источник данных - веб сервис, который в качестве входных данных принимает XML и возвращает XML с результатами поиска по параметрам.
Сам сервис работает следующим образом:
запрос отправляется на https, затем запрос перенаправляется на http ресурсс ответом. Приложение должно поддерживать редирект и
session Cookie. Для отправки запроса используется библиотека Curl. Проблема в том, что с тестового сервера запрос отправляется нормально, ответ приходит. А с основного сервера запрос отправляется, а в ответ приходит 400 Bad Request (nginx). Запрос через командную строку на основном сервере работает.
3rd party утверждает, что на их сервере никаких фильтров по IP нет. На серверах стоит (жирным выделил отличия):
---------------------------------
тестовый сервер:
ОС: OS Linux (CentOS 5) x86
PHP: PHP 5.3.1 (cli) (built: Nov 20 2009 17:51:14)

CURL: curl 7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Protocols: tftp ftp telnet dict ldap http file https ftps
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

Apache: Apache/2.2.3
выход в интернет: запросы на 80й порт через прокси
--------------------------------
основной сервер:
ОС: OS Linux (CentOS 5) x64
PHP: PHP 5.3.1 (cli) (built: Nov 20 2009 18:18:28)

CURL: curl 7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Protocols: tftp ftp telnet dict ldap http file https ftps
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

Apache: Apache/2.2.3
выход в интернет: напрямую
--------------------------------
Вопрос следующий: где копать? В чем может быть ошибка. Есть предположение, что дело в настройке php или недостатке каких-то библиотек, но каких? Может быть для такой ситуации необходимы дополнительные заголовки в запросе? Буду благодарен за любую помощь. Спасибо.
 

slim-akim

Новичок
Первый шаг для тестового и основного получаются одинаковые запрос-ответ (ну примерно, за исключением куки):

запрос

POST /ibe/deeplink/apiEntryPoint.do HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)
Host: **********
Accept: */*
Connection: close
Content-Length: 1346
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

ответ

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Wed, 12 May 2010 08:52:40 GMT
Content-Type: text/html;charset=UTF-8
Connection: close
Set-Cookie: JSESSIONID=564D137CC17343796D477BA07BA7E683; Path=/ibe
Cache-Control: no-store
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: JSESSIONID=564D137CC17343796D477BA07BA7E683
Location: http://**********/ibe/deeplink/apiEntryPointResponse.do
Content-Length: 0

отсюда получаем куки и location и вот тут начинается непонятное:
тестовый сервер:

запрос:
POST /ibe/deeplink/apiEntryPointResponse.do
HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)
Host: **********
Accept: */*
Cookie: JSESSIONID=564D137CC17343796D477BA07BA7E683
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

ответ:

HTTP/1.0 200 OK
Server: nginx
Date: Wed, 12 May 2010 08:52:41 GMT
Content-Type: text/html;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Cache: MISS from adam
X-Cache-Lookup: MISS from adam:3128
Via: 1.0 adam:3128 (squid/2.6.STABLE21)
Connection: close

{длинный XML}

основной сервер:

(тут куки другие потому что запрос другой, но первая часть за исключением куки такая же)
POST /ibe/deeplink/apiEntryPointResponse.do HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)
Host: **********
Accept: */*
Cookie: JSESSIONID=2CBE5ED6081D12D8F9A32FE00491D7C6
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Wed, 12 May 2010 09:18:06 GMT
Content-Type: text/html;charset=UTF-8
Connection: close
Set-Cookie: JSESSIONID=2CBE5ED6081D12D8F9A32FE00491D7C6; Path=/ibe
Cache-Control: no-store
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: JSESSIONID=2CBE5ED6081D12D8F9A32FE00491D7C6
Location: http://**********/ibe/deeplink/apiEntryPointResponse.do
Content-Length: 0

Т.е. вместо ответа 200 снова происходит редирект. На тестовом такого нет.
 

slim-akim

Новичок
Автор оригинала: Fortop
конфиги серверов в чем отличаются?
Вы имеете в виду в чем разница в конфигах тестового и основного? Ничем, конфигурация тестового подогнана под основной. Единственная разница в версии ОС и curl (32 битная и 64 битная сборки соответственно) и в том, что тестовый выходит в интернет через прокси.
 

slim-akim

Новичок
Автор оригинала: baev
slim-akim, время на основном сервере какое?

А то мне вот это:
http://phpclub.ru/talk/showthread.php?s=&threadid=108490
напомнило.
Сервер тестовый и основной синхронизированы по времени с ntp.org, (adjust time server 91.121.104.170 offset 0.002641 sec), хотя Ваш случай любопытный, спасибо.
 

Fortop

Новичок
slim-akim
Фокус в том, что симптом очень похож на описанный baev.

В ответе вам пытаются повторно поставить куку.
Как вы ее сохраняете? В файл?

Может на основном сервере нет прав на запись?
 

WebAngel

Новичок
Первый шаг для тестового и основного получаются одинаковые запрос-ответ (ну примерно, за исключением куки):
уверен? по всей видимости дело в неверных кукисах.
возможно даннные авторизации разные или с тестового запрос идет на test.example.com, а с основного на api.example.com.

если шаг 2 сделать с заранее неверными кукисами, то ответ будет такой же как и для основного?

спроси у саппорта почему они тебя посылают.
 

slim-akim

Новичок
Автор оригинала: Fortop
slim-akim
Фокус в том, что симптом очень похож на описанный baev.
В ответе вам пытаются повторно поставить куку.
Как вы ее сохраняете? В файл?
Может на основном сервере нет прав на запись?
Согласен, что похож, но админ разубедил.
Куку храню не в файле, а делаю с помощью курла 2 шага:
1) отправляю запрос с xml в теле


PHP:
               $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, self::GATE);
        сurl_setopt($ch, CURLOPT_HEADER,true);
        curl_setopt($ch, CURLOPT_FAILONERROR, true);       
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);       
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'XML_QUERY='.urlencode($xml) );
затем в headers ищу cookie и location, если в массиве curl_getinfo http_code 301 или 302
и отправляю запрос на новый location с указанием cookie

PHP:
              preg_match_all('|Location: (.*)\n|U', $result, $matches);
       $location = implode(';', $matches[1]);
       preg_match_all('|Set-Cookie: (.*);|U', $result, $matches);
       $cookies = implode(';', $matches[1]);              
       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $location);  
       curl_setopt($ch, CURLOPT_FAILONERROR, true);
       curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
       curl_setopt($ch, CURLOPT_COOKIE, $cookies);
и в теле ответа на этот запрос на тестовом сервере приходит xml, а на основном - ошибка.
само решение разбить на 2 шага нашлось на stackoverflow.

-~{}~ 12.05.10 16:00:

Автор оригинала: WebAngel
уверен? по всей видимости дело в неверных кукисах.
возможно даннные авторизации разные или с тестового запрос идет на test.example.com, а с основного на api.example.com.

если шаг 2 сделать с заранее неверными кукисами, то ответ будет такой же как и для основного?

спроси у саппорта почему они тебя посылают.
Да, идентичны до обидного, запрос идет на один и тот же хост, данные авторизации подтвердил саппорт сервиса.
Если сделать шаг 2 с заведомо неверными куки или вообще без них, то возвращается (на тестовом)

HTTP/1.0 200 OK
Server: nginx
Date: Wed, 12 May 2010 11:56:55 GMT
Content-Type: text/html;charset=UTF-8
Set-Cookie: JSESSIONID=3F5FC90E0EBA4D83A2F7D36A0866A4DE; Path=/ibe
Cache-Control: no-store
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Length: 266
X-Cache: MISS from adam
X-Cache-Lookup: MISS from adam:3128
Via: 1.0 adam:3128 (squid/2.6.STABLE21)
Connection: close

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- The jsp used to create this page was [org.apache.jsp.deeplink.jsp.apiEntryPointResponse_jsp] -->

т.е. пустая страница. По идее ниже этой строчки должен быть xml.

От саппорта не удается добиться объяснений, увы.
 

baev

‹°°¬•
Команда форума
slim-akim, а почему у Вас вот в этой строке:
PHP:
 сurl_setopt($ch, CURLOPT_HEADER,true);
— первая буква — русская «с»?
 

slim-akim

Новичок
Автор оригинала: baev
slim-akim, а почему у Вас вот в этой строке:
PHP:
 сurl_setopt($ch, CURLOPT_HEADER,true);
— первая буква — русская «с»?
Думаю, при удалении комментариев из кода уже непосредственно на форуме вкралась опечатка. В коде проверил - все в порядке, но на всякий случай заменил еще раз и протестировал на обоих серверах. Результат, к сожалению, все тот же.
 

Fortop

Новичок
Проверьте свой же код при помощи сервера к которому у вас есть доступ.

Сделайте для него тестовую страничку, которая будет ставить куку и делать редирект.
 

WebAngel

Новичок
у них один сервер или несколько?
возможно с твоих серверов идет запрос к разным ихним серверам, и один из них неверно обрабатывает :)

сделай на основном сервере курл через прокси тестового
 

slim-akim

Новичок
Автор оригинала: WebAngel
у них один сервер или несколько?
возможно с твоих серверов идет запрос к разным ихним серверам, и один из них неверно обрабатывает :)
сделай на основном сервере курл через прокси тестового
не получится. тестовый сервер выходит через прокси который в локальной сети, как запрос с основного (который заграницей) через него пустить я не знаю даже :confused:
поднять же прокси на основном пока не представляется возможным.
про количество серверов у них тоже умалчивается.
спасибо за информацию, в любом случае

-~{}~ 12.05.10 16:54:

Автор оригинала: Fortop
Проверьте свой же код при помощи сервера к которому у вас есть доступ.

Сделайте для него тестовую страничку, которая будет ставить куку и делать редирект.
Вы имеете в виду попробовать сэмулировать работу их веб-сервиса на тестовом?
 

WebAngel

Новичок
Найди список паблик проксей и попробуй через них, с разных стран. Особенно с той, где тестовый.

А с кукой должно быть все нормально, если она не верная ответ будет совсем другой.

-~{}~ 12.05.10 15:59:

но в идеале конечно же поднять проксик на основном.
 

slim-akim

Новичок
Автор оригинала: WebAngel
Найди список паблик проксей и попробуй через них, с разных стран. Особенно с той, где тестовый.

А с кукой должно быть все нормально, если она не верная ответ будет совсем другой.

-~{}~ 12.05.10 15:59:

но в идеале конечно же поднять проксик на основном.
That'll take some time
Спасибо за советы.
 

alexv

Новичок
может лучше не парсить куки и не разбивать запрос на два ??

попробуйте
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookiefile");
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookiefile");
 

slim-akim

Новичок
Автор оригинала: alexv
может лучше не парсить куки и не разбивать запрос на два ??

попробуйте
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookiefile");
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookiefile");
да, такой вариант сработал. спасибо.
но дополнительно надо было указать:
curl_setopt($ch , CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt($ch , CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Transfer-Encoding: ','Expect:'));
без этого не работало.
в пределах одного метода генерируем имя кукифайла и удаляем его после получения результатов.
Но так и непонятно, почему при разбивке на 2 этапа не работал запрос.
Возможно, что, как указал в начале ветки baev , имеют место быть особенности 64-битной системы.

Всем большое спасибо за помощь.
 
Сверху