Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Искажение бинарных данных в _POST / 25 сообщений из 32, страница 1 из 2
13.06.2013, 12:02
    #38295952
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
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
13.06.2013, 12:16
    #38295990
r u
r u
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Zvezdochet,

poWinHttp.setRequestHeader( "Content-Type", "multipart/form-data")
может еще boundary придется указать
...
Рейтинг: 0 / 0
13.06.2013, 18:23
    #38296752
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
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
13.06.2013, 19:26
    #38296863
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
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
13.06.2013, 19:36
    #38296875
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Zvezdochet,

кстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) )
...
Рейтинг: 0 / 0
14.06.2013, 11:31
    #38297559
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
r upoWinHttp.setRequestHeader( "Content-Type", "multipart/form-data")
может еще boundary придется указать
Подозреваю что это не поможет. Пробовал другие провайдеры WinHttp.WinHttprequest, MSXML2.XMLHTTP, Microsoft.XMLHTTP
У них у всех похоже передача бинарных данных идет в UTF-8. Тем неменее попробую вариант с Boundary обязательно.
...
Рейтинг: 0 / 0
14.06.2013, 11:36
    #38297573
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
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
14.06.2013, 11:41
    #38297580
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Програмёркстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) )

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

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

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

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

P.S. После ряда эспериментов и чтения инета пришел к выводу что проблема всё же не в PHP. Так что пойду в виндовом форуме народ спрашивать. В инете еще посоветовали в сторону libCurl посмотреть.
...
Рейтинг: 0 / 0
14.06.2013, 20:02
    #38298305
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
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
14.06.2013, 20:47
    #38298334
пых-illhead
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
авторpoWinHttp.SetRequestHeader("content-type", "application/octet-stream")

poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))а зачем символьную инфу передавать в octet-stream-е?
...
Рейтинг: 0 / 0
16.06.2013, 15:21
    #38299033
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
?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
16.06.2013, 15:27
    #38299036
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
пых-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
17.06.2013, 08:43
    #38299343
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Zvezdochet?пропущено...
Это чего? VBA?

Это Visual Foxpro. В VBA синтаксис будет немного другой но по сути это ничего не меняет.А строки в foxpro какие? Из однобайтных символов или из юникодных символов?
...
Рейтинг: 0 / 0
17.06.2013, 09:30
    #38299382
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Выяснил, в фокспро строки не юникодные. При передаче в 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
17.06.2013, 10:24
    #38299470
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
?Выяснил, в фокспро строки не юникодные. При передаче в 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
17.06.2013, 10:39
    #38299501
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
Zvezdochet, чтобы свернуть обратно в бинарные - надо знать изначальную кодовую страницу, из которой перекодирует фокспро. Но и тут есть грабли. Нельзя взять произвольные бинарные данные, перекодировать из произвольной кодовой страницы в юникод, а потом перекодировать обратно. Не в любой кодовой странице определены все 256 символов. Скажем, в 1251 нет символа с кодом 0x98 и после перекодировки в юникод он неизвестно во что превратится, возможно в "?".
...
Рейтинг: 0 / 0
17.06.2013, 12:38
    #38299777
Zvezdochet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
?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
17.06.2013, 12:56
    #38299824
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Искажение бинарных данных в _POST
ZvezdochetКонвертация так же может быть независимой от языка, т.е. просто биты одного байта разделяются и записываются в 2 разных байта чтобы верхние биты были свободны и информацию можно было передавать текстовыми протоколамиЭто бред какой-то

Zvezdochet<?php
echo $HTTP_RAW_POST_DATA ;
?>

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

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

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

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

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

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

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


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