neudor

log

Entries Comments



Month: July, 2008

SSL из PHP: socket и cURL

31 July, 2008 (08:11) | other | By: neudor

Сегодня, этим сонным летним утром, я расскажу вам про SSL соединение из PHP скрипта. Расскажу исходя не только лишь из теории, а ещё и решая вполне себе практическую задачу – логин на гугловский блогосервис blogger.com.

Начнём с сокетов. В хелпе заявлена возможность использования HTTPS протокола, поэтому пробуем. Набор POST переменных взят из developer’s guide.

$postvars = array(
  ”Email” => “mail@gmail.com”,
  ”Passwd” => “pass”,
  ”service” => “blogger”
);

$postdata = “”;
foreach ( $postvars as $key => $value )
    $postdata .= “&”.rawurlencode($key).”=”.rawurlencode($value);
$postdata = substr( $postdata, 1 );

$fp = fsockopen(”ssl://www.google.com”, 443);
$send = “”;
$send .= “POST /accounts/ClientLogin HTTP/1.1\r\n”;
$send .= “Host: www.google.com\r\n”;
$send .= “Content-length: “.strlen($postdata).”\r\n”;
$send .= “Content-type: text/plain\r\n”;
$send .= “Connection: close\r\n”;
$send .= “\r\n”;
$send .= $postdata.”\r\n\r\n”;

fputs($fp, $send);
$html = fread($fp, 1000000);
fclose($fp);

echo $html;

В функции fsockopen в качестве префикса перед именем сервера используем не https, а ssl. Так прямым текстом написано в хелпе. Дальше всё просто. Формируем HTTP-header, и пихаем его в открытый сокет. Читаем ответ, и получаем

Error=BadAuthentication

Короче, если опустить часовые мытарства и пляски вокруг функций сокета, у меня ничего не вышло. Ну то есть не вышло передать POST данные, хотя GET запросы возвращаются нормально. Может это связано только с гугловским сервером, а где-то в другом месте получится. Вобщем, переходим ко второму способу.

Открываем страницу мана про cURL и радуемся. Столько возможностей для запросов, для всякого конфигурирования. Должно получиться. Итак, лезем в curl_setopt. Нам понадобятся
CURLOPT_URL — это URL запроса.
CURLOPT_POST — говорим, что будем посылать POST запрос.
CURLOPT_POSTFIELDS — собственно POST переменыые.
CURLOPT_RETURNTRANSFER — вернуть результат запроса, а не выводить в браузер.

Теперь собственно о SSL параметрах:
CURLOPT_SSL_VERIFYPEER — если поставить его в 0, то удалённый сервер не будет проверять наш сертификат. В противном случае необходимо этот самый сертификат послать.
CURLOPT_CAINFO — указывать файл сертификата, если CURLOPT_SSL_VERIFYPEER установлен в 1.
CURLOPT_SSLVERSION — целое число, указывает версию SSL (2 или 3), обычно определяется автоматически.
CURLOPT_SSL_VERIFYHOST — будет ли производиться проверка имени удалённого сервера, указанного в сертификате. Если установить значение “2″, то будет произведена проверка соответствия имени хоста. (если честно, я так и не понял что делает этот флаг)

Вот и всё. Нам для гугла понадобится только указать, что мы с собой никаких сертификатов не принесли, пустите нас так пожалуйста. Пишем код.

$postvars = array(
  ”Email” => “mail@gmail.com”,
  ”Passwd” => “pass”,
  ”service” => “blogger”
);

$postdata = “”;
foreach ( $postvars as $key => $value )
    $postdata .= “&”.rawurlencode($key).”=”.rawurlencode($value);
$postdata = substr( $postdata, 1 );

$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, “https://www.google.com/accounts/ClientLogin”);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close($ch);

echo $result;

В переменной $result у нас теперь находятся три строки, из которых нужна только одна — последняя, которая начинается с “Auth=”. Но про это, наверное, в следующий раз.

Уникализация контента. Перевод на английский и обратно.

30 July, 2008 (14:29) | PHP, Splog | By: neudor

Итак, будем переводить тексты. Поскольку инструмент в предыдущем посте довольно бесполезен сам по себе, необходимо накатать скрипт. Но для начала скажу ещё об одном способе перевода.

Это Yahoo pipes. Я накатал простейшую трубу для перевода текста с русского на английский и обратно. И всё бы хорошо, но есть две проблемы. Первая — при переводе яху тупо убирает все html теги. И как их восстанавливать — это отдельный вопрос. Я бы даже сказал, нетривиальная задача. Ну и второе — модуль перевода иногда бывает банально не работает. Я нашёл жалобы в саппорт по этому поводу на форуме про yahoo pipes, и вроде всё починили. Но у меня всё равно из 10 запусков трубы в разное время суток нерезультативными оказываются примерно 6.

Подводя итог можно сказать, что yahoo pipes — это хороший и быстрый инструмент, но я его не использую. Может вам повезёт больше, а для меня очень критично наличие тегов и стабильная работа сервиса.

Подходим ко второму способу — через AJAX API от гугла. Собственно скрипт. Я там в самом начале оставил set_time_limit(5) для отладки. Это чтоб сначала всё хорошо проеврить, а уже потом запускать на сутки (ну или у кого как), убирая ограничения set_time_limit(0).

И есть ещё две тонкости, без которых скрипт работать не будет. Во-первых, предполагается что все входные и выходные строки будут в юникоде. Так что если будете редактировать, убедитесь что ваш редактор умеет сохранять в UTF-8 (я юзаю notepad++). И второе — для работы с БД вам понадобится библиотека dbsimple. Ну, то есть я её использую, а вы вполне можете приспособить все её вызовы под свои нужды. Там всё просто и прозрачно.

У гугловского API есть одно существенное ограничение — это длина строки, которую вы будете переводить. Вроде как она составляет 700 символов, но иногда вываливаются ошибки при запросе на перевод строки в 600 символов, а иногда нормально проходят строки по 690 символов. Закономерность явлений установить не удалось. Опытным путём установлено, что всё железно работает при длине строки до 545 символов. На ней я и остановился.

Основная функция в скрипте — это string translate(string $src, string $langpair).
string $src — это строка для перевода (строка в полную длину)
string $langpair — это языковая пара перевода. Например, “ru%7Cen”. Именно в таком виде, поскольку эта строка подставляется без изменений в url запрос.

Ну и вот. Строка переводится один раз туда, а второй раз — обратно. Скрипт мал, изящен, открыт и даже как-то там прокомментирован. Любые изменения и дополнения приветствуются.

В достоинствах скрипта то, что мне так необходимо. Это надёжность и сохранение тегов. Но вот время выполнения оставляет желать лучшего. Хотя я не пробовал запускать его на хостинге — только дома на локалхосте, на не очень толстой выделенке.

P.S. Для себя в процессе написания скрипта выделил одну вещь. Уникализация контента путём превращения его в нечто нечитаемое — это не труъ. Гораздо лучше фигачить мешапы. =)

Автоматический перевод текстов

17 July, 2008 (20:07) | Splog | By: neudor

Заниматься этим можно используя гугл. Все схватили инструмент и побежали уникализировать каталоги, нафигачивая страницы для сапы!

Related картинки с google image search

16 July, 2008 (14:03) | Splog | By: neudor

Накидал вот трубу. Легко можно юзать в мешапах, ибо фотки с фликра – они только залитые посетителями, а нужно иногда просто релевантных картинок по кейворду.

Пользоваться очень просто — запрашиваете RSS и всё. Можно творить что душе угодно.

Есть, конечно, и недостатки. Например — выдаётся рсс только первых 20 результатов поиска. Кому как, а мне хватает. В любом случае исходник трубы есть, можно совершенствовать.

Яндекс и дублированный контент.

11 July, 2008 (08:48) | catalogs | By: neudor

Первый каталог уже давно доделан, выложен и проиндексирован сапой. Полностью. Больше 11000 страниц. Клёво быть программистом, и не ныть про вордпресс =). А вот Яндекс, сцуко, тупит. Основных записей почти нет. Есть только страницы со списками, ссылающимися как раз на страницы с контентом.

Видимо, всё дело в том, что я контент тупо пёр с википедии. Надо бы намутить какой-то мега мешап, добавить каменты, голосовалки, последние новости по теме… Если разрожусь чем-то подобным и оно будет мега крутым — пожалуй выложу.

Хотя, может у яндекса бот тупо тормоз. Вон, ещё вчера (10.07) у него в кэше лежал индекс хабра от 7.06. Гугл, например, даже ко мне чаще заходит. Форменное безобразие.

Ахмед

2 July, 2008 (06:48) | other | By: neudor

Чудовищно! =)