powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Искажение бинарных данных в _POST
25 сообщений из 32, страница 1 из 2
Искажение бинарных данных в _POST
    #38295952
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PHP скрипту передаются бинарные данные следующим образом:

poWinHttp = Createobject("Msxml2.ServerXMLHTTP.6.0")
poWinHttp.Open("POST", “ http://10.10.1.1/test.php”, .F.)
poWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))

GotData=poWinHttp.ResponseText

Если отправленную строку прочитать в PHP

<?php
for ($i=0; $i < strlen($HTTP_RAW_POST_DATA); $i++) {
echo "Pos: ".$i." -> ".ord(substr($HTTP_RAW_POST_DATA,$i,1))."<br>";
}
?>

То в результате получим:
Pos: 0 -> 209
Pos: 1 -> 128
Pos: 2 -> 15
Pos: 3 -> 194
Pos: 4 -> 172
Pos: 5 -> 208
Pos: 6 -> 189
Pos: 7 -> 209
Pos: 8 -> 142

Размер с 5и байт увеличился до 9 из-за того что PHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые.

Вопрос: как на стороне PHP получить именно те 5 байт которые были отправлены?
Перебирать байты по очереди и превращать 2х байтовые в однобайтовые в цикле - не вариант так как пакеты могут достигать 8и мегабайт.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38295990
Фотография r u
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zvezdochet,

poWinHttp.setRequestHeader( "Content-Type", "multipart/form-data")
может еще boundary придется указать
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38296752
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZvezdochetPHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые.Сложно сказать, кто именно превратил. Может, "Msxml2.ServerXMLHTTP.6.0". Вы же читаете HTTP_RAW_POST_DATA. Насколько понимаю, на отправке была однобайтовая кодировка, а до PHP данные дошли уже в utf-8.
Самое простое iconv'ом конвертнуть полученный текст обратно в однобайтовую. Конечно, если только не встретится каких-то "непотребных" символов.
Либо, при отправке попробовать сыммитировать атрибут "accept-charset" формы с нужной кодировкой.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38296863
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkleZvezdochetPHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые.Сложно сказать, кто именно превратил. Может, "Msxml2.ServerXMLHTTP.6.0". Вы же читаете HTTP_RAW_POST_DATA. Насколько понимаю, на отправке была однобайтовая кодировка, а до PHP данные дошли уже в utf-8.
Самое простое iconv'ом конвертнуть полученный текст обратно в однобайтовую. Конечно, если только не встретится каких-то "непотребных" символов.
Либо, при отправке попробовать сыммитировать атрибут "accept-charset" формы с нужной кодировкой.

Так у автора не строка ведь, а бинарные данные. там спокойно может попасться неконвертируемый символ (представим, что нужно exe передать). Как вариант - использовать base64 (на клиенте кодируем, а на сервере раскодируем). Это немного увеличит объём передаваемых данных, но зато на все 100% прийдёт правильно.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38296875
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zvezdochet,

кстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) )
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38297559
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
r upoWinHttp.setRequestHeader( "Content-Type", "multipart/form-data")
может еще boundary придется указать
Подозреваю что это не поможет. Пробовал другие провайдеры WinHttp.WinHttprequest, MSXML2.XMLHTTP, Microsoft.XMLHTTP
У них у всех похоже передача бинарных данных идет в UTF-8. Тем неменее попробую вариант с Boundary обязательно.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38297573
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vkleСложно сказать, кто именно превратил. Может, "Msxml2.ServerXMLHTTP.6.0". Вы же читаете HTTP_RAW_POST_DATA. Насколько понимаю, на отправке была однобайтовая кодировка, а до PHP данные дошли уже в utf-8.
Самое простое iconv'ом конвертнуть полученный текст обратно в однобайтовую. Конечно, если только не встретится каких-то "непотребных" символов.
Либо, при отправке попробовать сыммитировать атрибут "accept-charset" формы с нужной кодировкой.
Похоже что таки Msxml2.ServerXMLHTTP.6.0 отправляет в UTF-8, при чем видимо все виндовые провайдеры этим страдают.
iconv не поможет так как в потоке будут сканы документов и ZIP архивы.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38297580
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Програмёркстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) )

Попробовал. Результат тот же самый.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38297587
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
ZvezdochetРазмер с 5и байт увеличился до 9 из-за того что PHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые.

Вопрос: как на стороне PHP получить именно те 5 байт которые были отправлены?
Не PHP превратил, и не 5 байт были отправлены.

Попробуйте массив байтов отправить.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38297597
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ПрограмёрТак у автора не строка ведь, а бинарные данные. там спокойно может попасться неконвертируемый символ (представим, что нужно exe передать). Как вариант - использовать base64 (на клиенте кодируем, а на сервере раскодируем). Это немного увеличит объём передаваемых данных, но зато на все 100% прийдёт правильно.

Сейчас эта задача на base64 и работает. Но при больших объемах данных после base64 и URLencode пакеты распухают до неприличных размеров. По техническим причинам скорость между некоторыми офисами всего 50кб/с и процесс обмена иногда затягивается так что хотелось бы решения чтобы как можно меньше канал нагружало.

P.S. После ряда эспериментов и чтения инета пришел к выводу что проблема всё же не в PHP. Так что пойду в виндовом форуме народ спрашивать. В инете еще посоветовали в сторону libCurl посмотреть.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38298305
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
ZvezdochetPHP скрипту передаются бинарные данные следующим образом:

poWinHttp = Createobject("Msxml2.ServerXMLHTTP.6.0")
poWinHttp.Open("POST", “ http://10.10.1.1/test.php”, .F.)
poWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))

GotData=poWinHttp.ResponseText
Это чего? VBA?
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38298334
пых-illhead
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторpoWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))а зачем символьную инфу передавать в octet-stream-е?
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299033
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
?ZvezdochetPHP скрипту передаются бинарные данные следующим образом:

poWinHttp = Createobject("Msxml2.ServerXMLHTTP.6.0")
poWinHttp.Open("POST", “ http://10.10.1.1/test.php”, .F.)
poWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))

GotData=poWinHttp.ResponseText
Это чего? VBA?

Это Visual Foxpro. В VBA синтаксис будет немного другой но по сути это ничего не меняет.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299036
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пых-illheadавторpoWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))а зачем символьную инфу передавать в octet-stream-е?

Потому, что если передавать её как текст (application/x-www-form-urlencoded и подобные) то символы с кодами больше 128 (бинарные данные) будут либо потеряны либо каждый символ с кодом > 128 будет преобразован в 3 символа типа %F0 в результате чего пакет сильно распухнет. Сточка в примере приведена чтобы продемонстрировать проблему, в жизни этим методом должны будут передаваться ZIP архивы и сканы документов.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299343
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Zvezdochet?пропущено...
Это чего? VBA?

Это Visual Foxpro. В VBA синтаксис будет немного другой но по сути это ничего не меняет.А строки в foxpro какие? Из однобайтных символов или из юникодных символов?
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299382
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Выяснил, в фокспро строки не юникодные. При передаче в Com объект строка автоматически преобразуется в юникод. Ну а дальше отсылается в UTF-8.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms755436(v=vs.85).aspx
там написано
send MethodThis method takes one optional parameter, which is the requestBody to use. The acceptable VARIANT input types are BSTR, SAFEARRAY of UI1 (unsigned bytes), IDispatch to an XML Document Object Model (DOM) object, and IStream *. You can only use chunked encoding (for sending) when sending IStream *input types. The component automatically sets the Content-Length header for all but IStream *input types.

If the input type is a BSTR, the response is always encoded as UTF-8. The caller must set a Content-Type header with the appropriate content type and include a charset parameter.

If the input type is a SAFEARRAY of UI1, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

Так что чтобы отослать двоичные данные, надо передавать туда не строку, а массив байтов. Но кажется фокспро так не умеет. (Вообще топик надо в раздел фокспро перенести).
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299470
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
?Выяснил, в фокспро строки не юникодные. При передаче в Com объект строка автоматически преобразуется в юникод. Ну а дальше отсылается в UTF-8.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms755436(v=vs.85).aspx
там написано
send MethodThis method takes one optional parameter, which is the requestBody to use. The acceptable VARIANT input types are BSTR, SAFEARRAY of UI1 (unsigned bytes), IDispatch to an XML Document Object Model (DOM) object, and IStream *. You can only use chunked encoding (for sending) when sending IStream *input types. The component automatically sets the Content-Length header for all but IStream *input types.

If the input type is a BSTR, the response is always encoded as UTF-8. The caller must set a Content-Type header with the appropriate content type and include a charset parameter.

If the input type is a SAFEARRAY of UI1, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

Так что чтобы отослать двоичные данные, надо передавать туда не строку, а массив байтов. Но кажется фокспро так не умеет. (Вообще топик надо в раздел фокспро перенести).

Данному топику наверное место всё же здесь, так как изначально вопрос стоял как на стороне PHP свернуть UTF-8 данные обратно в бинарные.
На данный момент мои исследования по этому вопросу сводятся к 2м вариантам:
1. Использовать функцию из этой библиотеки http://code.google.com/p/php5-utf8/ которая может конвертить UTF-8 независимо от кодировки самих символов.
2. Использовать libcurl. В одном англоязычном мейл листе мне ответили что все мелкософтовские классы по работе с HTTP, FTP имеют ряд жестко зашитих установок. Это сделано для того чтобы писатели на .NET, VB и прочих делали меньше ошибок и меньше путались. Как следствие, ряд нестандартных задач (как моя) становится из-за этого практически не решаемым. Если нужен полный контроль над тем что, куда и как передается – следует использовать libcurl. Почитал про него немного, действительно можно кастомайзить практически всё но написать для него обвязку будет стоить приличной доли геморроя.

Вобщем методы решения можно сказать обозначились. Если 1й вариант будет сильно нагружать сервер прийдется долбаться с libcurl.

P.S. Если у кого-то всё же найдется другое более изящное решение – буду очень благодарен.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299501
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Zvezdochet, чтобы свернуть обратно в бинарные - надо знать изначальную кодовую страницу, из которой перекодирует фокспро. Но и тут есть грабли. Нельзя взять произвольные бинарные данные, перекодировать из произвольной кодовой страницы в юникод, а потом перекодировать обратно. Не в любой кодовой странице определены все 256 символов. Скажем, в 1251 нет символа с кодом 0x98 и после перекодировки в юникод он неизвестно во что превратится, возможно в "?".
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299777
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
?Zvezdochet, чтобы свернуть обратно в бинарные - надо знать изначальную кодовую страницу, из которой перекодирует фокспро. Но и тут есть грабли. Нельзя взять произвольные бинарные данные, перекодировать из произвольной кодовой страницы в юникод, а потом перекодировать обратно. Не в любой кодовой странице определены все 256 символов. Скажем, в 1251 нет символа с кодом 0x98 и после перекодировки в юникод он неизвестно во что превратится, возможно в "?".

Немного не так. Конвертация между UTF-8 и другой кодировкой может быть языкозависимой, т.е. в целевой кодировке выбирается символ (буква) соответствующий такой же по значению в исходной кодировке, такое преобразование делает функция iconv. Конвертация так же может быть независимой от языка, т.е. просто биты одного байта разделяются и записываются в 2 разных байта чтобы верхние биты были свободны и информацию можно было передавать текстовыми протоколами, подробнее описано здесь http://ru.wikipedia.org/wiki/UTF-8 .
Виндовые HTTP / FTP классы используют 2й вариант когда кодируют / декодируют пакеты при передаче по сети.

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

<?php
echo $HTTP_RAW_POST_DATA ;
?>

на стороне фокса вернулись теже 5 байт в том же состоянии как они были отправлены. Получается что большинству нужно загрузить данные на сервер и потом в нужный момент их отдать. И этот вариант работает нормально, при отдаче данные обратно сворачиваются в бинарные. Вот народ и не заморачивается вопросом что сам сервер, внутри, хранит эти данные как-то по другому. В моем же случае в самих данных находятся управляющие последовательности, которые сервер должен распарсить и решить что с этими данными делать дальше, а этого он сделать не может из-за того что данные внутри представлены в UFT-8.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299824
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
ZvezdochetКонвертация так же может быть независимой от языка, т.е. просто биты одного байта разделяются и записываются в 2 разных байта чтобы верхние биты были свободны и информацию можно было передавать текстовыми протоколамиЭто бред какой-то

Zvezdochet<?php
echo $HTTP_RAW_POST_DATA ;
?>

на стороне фокса вернулись теже 5 байт в том же состоянии как они были отправлены.
Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается?
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299907
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
?Это бред какой-то
Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное.

?Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается?
Да http://sites.kis.net.ua/vfp_http_sql_ru.jpg
А что должно было вернуться?
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299924
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Zvezdochet?Это бред какой-то
Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное.
Угу, это про кодирование символов юникода в UTF8. Байты - это не символы юникода. ZvezdochetДа http://sites.kis.net.ua/vfp_http_sql_ru.jpg
А что должно было вернуться? Не знаю, это зависит от того, какая кодовая страница в фокспро установлена и как он в юникод и обратно перекодирует.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38299971
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zvezdochet?Это бред какой-то
Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное.

?Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается?
Да http://sites.kis.net.ua/vfp_http_sql_ru.jpg
А что должно было вернуться?

Я смотрел )). И стало немного смешно (не от того, что там написано... там может и всё правильно, а просто от найденной альтернативы для base64). Итак, когда мы кодируем в base64, то объём передаваемых данных составляет 8/6 первоначального объёма. Перекодируя по указанному принципу в UTF-8, мы получаем base64 (точно также максимальное количество значащих бит равно 6 на один байт), только с кучей проверок на больше-меньше и разными приблудами.

А ЗАЧЕМ?!!!
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38300140
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
?ZvezdochetА что должно было вернуться? Не знаю, это зависит от того, какая кодовая страница в фокспро установлена и как он в юникод и обратно перекодирует.
Это не фокс перекодирует а msxml6.dll в лице Msxml2.ServerXMLHTTP.6.0 провайдера, как впрочем и все остальные. Там жестко зашито гнать все бинарные данные в UTF-8. Устанавливать заголовок Content-transfer-encoding: binary бесполезно, он будет проигнорирован и принудительно установлено UTF-8. А вот libcurl эту установку отрабатывает и честно посылает данные как есть, без перекодировки.
...
Рейтинг: 0 / 0
Искажение бинарных данных в _POST
    #38300157
Zvezdochet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ПрограмёрЯ смотрел )). И стало немного смешно (не от того, что там написано... там может и всё правильно, а просто от найденной альтернативы для base64). Итак, когда мы кодируем в base64, то объём передаваемых данных составляет 8/6 первоначального объёма. Перекодируя по указанному принципу в UTF-8, мы получаем base64 (точно также максимальное количество значащих бит равно 6 на один байт), только с кучей проверок на больше-меньше и разными приблудами.

А ЗАЧЕМ?!!!
Глубоко в детали не вникал но на вскидку заметил что 7и битные символы (коды 0-127) передаются как есть (пример 1) а 8и битные уже делятся на 2 байта. В base64 вроде только буквы и цифры допускаются. Так что по идее если количество байт в пакете с кодами > 127 преобладает, то кодированное в UTF-8 будет занимать меньше места. Может еще есть какие-то причины....

P.S. Мы уже основательно уходим от первоначальной темы. Мне бы как-то этой чехарды с перекодированием избежать вообще.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Искажение бинарных данных в _POST
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]