Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
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и мегабайт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2013, 12:02 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet, poWinHttp.setRequestHeader( "Content-Type", "multipart/form-data") может еще boundary придется указать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2013, 12:16 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
ZvezdochetPHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые.Сложно сказать, кто именно превратил. Может, "Msxml2.ServerXMLHTTP.6.0". Вы же читаете HTTP_RAW_POST_DATA. Насколько понимаю, на отправке была однобайтовая кодировка, а до PHP данные дошли уже в utf-8. Самое простое iconv'ом конвертнуть полученный текст обратно в однобайтовую. Конечно, если только не встретится каких-то "непотребных" символов. Либо, при отправке попробовать сыммитировать атрибут "accept-charset" формы с нужной кодировкой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2013, 18:23 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
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% прийдёт правильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2013, 19:26 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet, кстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2013, 19:36 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
r upoWinHttp.setRequestHeader( "Content-Type", "multipart/form-data") может еще boundary придется указать Подозреваю что это не поможет. Пробовал другие провайдеры WinHttp.WinHttprequest, MSXML2.XMLHTTP, Microsoft.XMLHTTP У них у всех похоже передача бинарных данных идет в UTF-8. Тем неменее попробую вариант с Boundary обязательно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 11:31 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
vkleСложно сказать, кто именно превратил. Может, "Msxml2.ServerXMLHTTP.6.0". Вы же читаете HTTP_RAW_POST_DATA. Насколько понимаю, на отправке была однобайтовая кодировка, а до PHP данные дошли уже в utf-8. Самое простое iconv'ом конвертнуть полученный текст обратно в однобайтовую. Конечно, если только не встретится каких-то "непотребных" символов. Либо, при отправке попробовать сыммитировать атрибут "accept-charset" формы с нужной кодировкой. Похоже что таки Msxml2.ServerXMLHTTP.6.0 отправляет в UTF-8, при чем видимо все виндовые провайдеры этим страдают. iconv не поможет так как в потоке будут сканы документов и ZIP архивы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 11:36 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Програмёркстати вот php://input Говорят юзать предпочтительнее (мало ли... а вдруг с этим связано:) ) Попробовал. Результат тот же самый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 11:41 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
ZvezdochetРазмер с 5и байт увеличился до 9 из-за того что PHP превратил символы CHR(240), CHR(172), CHR(237), CHR(254) в 2х байтовые. Вопрос: как на стороне PHP получить именно те 5 байт которые были отправлены? Не PHP превратил, и не 5 байт были отправлены. Попробуйте массив байтов отправить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 11:46 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
ПрограмёрТак у автора не строка ведь, а бинарные данные. там спокойно может попасться неконвертируемый символ (представим, что нужно exe передать). Как вариант - использовать base64 (на клиенте кодируем, а на сервере раскодируем). Это немного увеличит объём передаваемых данных, но зато на все 100% прийдёт правильно. Сейчас эта задача на base64 и работает. Но при больших объемах данных после base64 и URLencode пакеты распухают до неприличных размеров. По техническим причинам скорость между некоторыми офисами всего 50кб/с и процесс обмена иногда затягивается так что хотелось бы решения чтобы как можно меньше канал нагружало. P.S. После ряда эспериментов и чтения инета пришел к выводу что проблема всё же не в PHP. Так что пойду в виндовом форуме народ спрашивать. В инете еще посоветовали в сторону libCurl посмотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 11:55 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
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? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 20:02 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
авторpoWinHttp.SetRequestHeader("content-type", "application/octet-stream") poWinHttp.Send(CHR(240)+CHR(15)+CHR(172)+CHR(237)+CHR(254))а зачем символьную инфу передавать в octet-stream-е? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2013, 20:47 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
?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 синтаксис будет немного другой но по сути это ничего не меняет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2013, 15:21 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
пых-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 архивы и сканы документов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2013, 15:27 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet?пропущено... Это чего? VBA? Это Visual Foxpro. В VBA синтаксис будет немного другой но по сути это ничего не меняет.А строки в foxpro какие? Из однобайтных символов или из юникодных символов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 08:43 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Выяснил, в фокспро строки не юникодные. При передаче в 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. Так что чтобы отослать двоичные данные, надо передавать туда не строку, а массив байтов. Но кажется фокспро так не умеет. (Вообще топик надо в раздел фокспро перенести). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 09:30 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
?Выяснил, в фокспро строки не юникодные. При передаче в 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. Если у кого-то всё же найдется другое более изящное решение – буду очень благодарен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 10:24 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet, чтобы свернуть обратно в бинарные - надо знать изначальную кодовую страницу, из которой перекодирует фокспро. Но и тут есть грабли. Нельзя взять произвольные бинарные данные, перекодировать из произвольной кодовой страницы в юникод, а потом перекодировать обратно. Не в любой кодовой странице определены все 256 символов. Скажем, в 1251 нет символа с кодом 0x98 и после перекодировки в юникод он неизвестно во что превратится, возможно в "?". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 10:39 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
?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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 12:38 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
ZvezdochetКонвертация так же может быть независимой от языка, т.е. просто биты одного байта разделяются и записываются в 2 разных байта чтобы верхние биты были свободны и информацию можно было передавать текстовыми протоколамиЭто бред какой-то Zvezdochet<?php echo $HTTP_RAW_POST_DATA ; ?> на стороне фокса вернулись теже 5 байт в том же состоянии как они были отправлены. Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 12:56 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
?Это бред какой-то Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное. ?Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается? Да http://sites.kis.net.ua/vfp_http_sql_ru.jpg А что должно было вернуться? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 13:36 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet?Это бред какой-то Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное. Угу, это про кодирование символов юникода в UTF8. Байты - это не символы юникода. ZvezdochetДа http://sites.kis.net.ua/vfp_http_sql_ru.jpg А что должно было вернуться? Не знаю, это зависит от того, какая кодовая страница в фокспро установлена и как он в юникод и обратно перекодирует. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 13:45 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
Zvezdochet?Это бред какой-то Ссылку, которую я привел, смотрели? Раздел <Принцип кодирования> второй пример. Зеленая часть бит ушла в один байт, синяя часть бит ушла во второй байт. Никакого намека на кодовые страницы, языковые раскладки и тому подобное. ?Это вам просто повезло... chr(152) вставьте. Тоже нормально возвращается? Да http://sites.kis.net.ua/vfp_http_sql_ru.jpg А что должно было вернуться? Я смотрел )). И стало немного смешно (не от того, что там написано... там может и всё правильно, а просто от найденной альтернативы для base64). Итак, когда мы кодируем в base64, то объём передаваемых данных составляет 8/6 первоначального объёма. Перекодируя по указанному принципу в UTF-8, мы получаем base64 (точно также максимальное количество значащих бит равно 6 на один байт), только с кучей проверок на больше-меньше и разными приблудами. А ЗАЧЕМ?!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 14:03 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
?ZvezdochetА что должно было вернуться? Не знаю, это зависит от того, какая кодовая страница в фокспро установлена и как он в юникод и обратно перекодирует. Это не фокс перекодирует а msxml6.dll в лице Msxml2.ServerXMLHTTP.6.0 провайдера, как впрочем и все остальные. Там жестко зашито гнать все бинарные данные в UTF-8. Устанавливать заголовок Content-transfer-encoding: binary бесполезно, он будет проигнорирован и принудительно установлено UTF-8. А вот libcurl эту установку отрабатывает и честно посылает данные как есть, без перекодировки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 14:59 |
|
||
|
Искажение бинарных данных в _POST
|
|||
|---|---|---|---|
|
#18+
ПрограмёрЯ смотрел )). И стало немного смешно (не от того, что там написано... там может и всё правильно, а просто от найденной альтернативы для base64). Итак, когда мы кодируем в base64, то объём передаваемых данных составляет 8/6 первоначального объёма. Перекодируя по указанному принципу в UTF-8, мы получаем base64 (точно также максимальное количество значащих бит равно 6 на один байт), только с кучей проверок на больше-меньше и разными приблудами. А ЗАЧЕМ?!!! Глубоко в детали не вникал но на вскидку заметил что 7и битные символы (коды 0-127) передаются как есть (пример 1) а 8и битные уже делятся на 2 байта. В base64 вроде только буквы и цифры допускаются. Так что по идее если количество байт в пакете с кодами > 127 преобладает, то кодированное в UTF-8 будет занимать меньше места. Может еще есть какие-то причины.... P.S. Мы уже основательно уходим от первоначальной темы. Мне бы как-то этой чехарды с перекодированием избежать вообще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2013, 15:06 |
|
||
|
|

start [/forum/topic.php?fid=23&msg=38300157&tid=1463697]: |
0ms |
get settings: |
10ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
81ms |
get tp. blocked users: |
2ms |
| others: | 227ms |
| total: | 401ms |

| 0 / 0 |
