Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Curl + Base64 encode


Автор: EasyTask 26.5.2012, 04:31
Добрый день! Помогите разобраться с непростой задачкой. Ситуация обстоит следующим образом:

Наш сайт генерирует XML, затем кодирует его в base64 и с помощью POST запроса отправляет кодированный XML на биллинг, где он уже конкретно обрабатывается. Проблемы пришла оттуда, откуда ее меньше всего ждали. При определенном сочетании символов мы получаем следующий кодированный XML:
Код

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPGNoZWNrX29yZGVyIHBhcnRuZXJfaWQ9IjEwMjEiIHJlcXVlc3RfaWQ9IjEzMDc1MDQxIj48c2lnbmF0dXJlPjg4MDRmYjgyZDBjYWVlYmYzYjYyYjZlNzhhMGYxN2EzPC9zaWduYXR1cmU+PC9jaGVja19vcmRlcj4K

Что в оригинале означает:
Код

<?xml version="1.0" encoding="UTF-8"?>
<check_order partner_id="1021" request_id="13075041"><signature>8804fb82d0caeebf3b62b6e78a0f17a3</signature></check_order>

Все ыбы хорошо, если бы не одно НО. НО это заключается в одном, маленьком символе создающем большие проблемы:
Вырезка из кодированного XML:
Код

mU+PC

При отправке POST запроса, символ "+" проходит urlencode и в результате приобретает вид "%2B" и при раскодировке "бьет" нашу XML. 

Кто то сталкивался с подобным? Помогите с решением проблемы.

Автор: EasyTask 26.5.2012, 05:01
Пока что отвечу сам себе smile 
На данный момнет вижу два пути решения проблемы:

1. Существуют специальные функции для безпопасного base64 кодирования:
Код

function urlsafe_b64encode($string) {
    $data = base64_encode($string);
    $data = str_replace(array('+','/','='),array('-','_',''),$data);
    return $data;
}

function urlsafe_b64decode($string) {
    $data = str_replace(array('-','_'),array('+','/'),$string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

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

2. Более изященое решение, перед декодом проводить замену "заурлэнкоженных" символов, на нормальные (т.е проводить "обратный" urlencode)

%2B => +
%3D => =
%26 => &
%2F => /

Но может все же есть более изященое решение? Например опция курла? (POST запросы отправляются через curl)

Автор: ksnk 26.5.2012, 08:19
Цитата(EasyTask @  26.5.2012,  04:31 Найти цитируемый пост)
Наш сайт генерирует XML, затем кодирует его в base64 и с помощью POST запроса отправляет кодированный XML на биллинг, где он уже конкретно обрабатывается

Как посылается этот XML? Curl? Какой тип передачи данных используется - загрузка файла или передача в поле формы?

По всей видимости, в процессе генерации-получения происходит еще одно, лишнее url-кодирование, так как в обычной жизни раскодировать вручную не нужно.

Автор: Fortop 26.5.2012, 08:43
Цитата(EasyTask @  26.5.2012,  04:31 Найти цитируемый пост)
Наш сайт генерирует XML, затем кодирует его в base64 и с помощью POST запроса отправляет кодированный XML на биллинг

А зачем кстати? Почему не передавать просто XML?

Что касается вопроса, то 
Код

base64_decode(rawurldecode($encodedXml))
 должно решить проблему.
Проверять действительно ли где-то кодируется POST параметр, как писал ksnk,  сейчас негде

Автор: EasyTask 26.5.2012, 13:13
Код

Как посылается этот XML? Curl? Какой тип передачи данных используется - загрузка файла или передача в поле формы?

Да курл. Ни так и ни так. xml кодируется в строку и выступает в результате post параметра отправляемых курлом.

Код

А зачем кстати? Почему не передавать просто XML?

Ранее был другой способ передачи:
http://billing.url/?order=xml_in_base64

Опережая вопрос, сейчас нельзя переделать под отправку без него т.к у нас очень много проектов и везде используется такой механизм.

Да, об этом я и писал что перед декодом, на биллинге, нужно использовать декодер урл.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)