Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 21, 2009 12:10:13

kvazar
От:
Зарегистрирован: 2009-01-05
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение входящего потока

Здравствуйте, Всем.
Надеюсь, что мне кто-нибудь поможет понять.
Версия Python 3.1,Денвер, Винда.
Я написал небольшую функцию, которя читает входящий поток, переданный методом POST в формате multipart/form-data.
Всё вроде бы замечательно, но стоит передать допустим картинку, начинаются проблемы.
В теле передаётся лишь часть содержимого картинки.
То есть допустим читаю тело картинки, потом записываю в файл, открываю её и чёрный экран, либо картинка показывается частично.
Вот ветка в функции, которая разбирает поток в формате multipart/form-data.
Убрал всё лишнее. Вставил некоторые комментарии, где возникают проблемы.Данный код лишь для примера, он может и не работать.

res = re.search("boundary\=(.*)",os.environ['CONTENT_TYPE'],re.I)
boundary = res.group(1)
name = ""
step = True
dVars = {}
pStream = sys.stdin # Если вывести pStream с помощью print() выдаётся <_io.TextIOWrapper name='' encoding='cp1251'>
while step:
line = pStream.readline() # Иногда при чтении строки тела картинки вылетает ошибка UnicodeDecodeError
line = parse.unquote(line.replace("+"," "),encoding=encodeName) # в моём случае encodeName='cp1251'
if bool(line) == False: step = False; continue
if 'name=' in line and name == "":
res = re.search("name\=(?:\"|\'|)([^\"\'\s]+)",line)
name = res.group(1)
keyDict = re.search("\[([^\]]*)\]",name)
if keyDict != None:
name = name[:-(len(keyDict.group(0)))]
if name not in dVars: dVars[name] = {}
if len(keyDict.group(1)) > 0:
keyDict = keyDict.group(1)
else:
keyDict = str(len(dVars[name]))
dVars[name][keyDict] = ""
else:
dVars[name] = ""
pStream.readline()
elif boundary in line:
name = ""
else:
if keyDict != None:
dVars[name][keyDict] += line.strip()
else:
dVars[name] += line.strip()

Я бы не стал сюда писать, если бы не было тех же проблем при использовании cgi.FieldStorage().
У кого-нибудь есть какие-нибудь мысли?
В принципе всё работает, если не передавать файлы.
И у меня единственное предположение, что когда python читает поток в кодировке cp1251, то не все символы в этой кодировке определяются.
Но я не знаю, как это всё работает на самом деле, не хотелось бы гадать.



Отредактировано (Июнь 21, 2009 12:11:07)

Офлайн

#2 Июнь 21, 2009 19:02:02

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Чтение входящего потока

Используя свои телепатические способности могу предположить что ошибка в записи файла.
При записи бинарного файла в мастдае надо указывать параметр “wb” а не только “w”.

Офлайн

#3 Июнь 22, 2009 09:05:19

kvazar
От:
Зарегистрирован: 2009-01-05
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение входящего потока

Да нет, дело совсем не в этом. Записываю с mode='wb'.
Ну не передаётся всё тело файла во вхоядщем потоке. Вот допустим читаю PNG'шку в теле файла во входящем потоке находится только “‰PNG” и ВСЁ. То есть непосредственно содержимого картинки нет. И там хоть как записывай в файл, ничего не будет.
Проблема именно в том, что содержимое файла не передаётся и иногда возникают ошибки UnicodeDecodeError даже просто при чтении sys.stdin.readline().
Правда попалось одно исключение при передачи одной маленькой картинки, содержимое передалось полностью и потом она нормально открылась.
Поэтоу мне и кажется, что когда читается поток в cp1251, то многие символы не определяются…



Офлайн

#4 Июнь 22, 2009 11:38:08

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Чтение входящего потока

В картинках почти всегда есть символы, которые “не помещаются” в cp1251.

Кстати, вместо
parse.unquote(line.replace(“+”,“ ”))
можно использвать
parse.unquote_plus(line) с тем же эффектом



Офлайн

#5 Июнь 22, 2009 11:51:37

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Чтение входящего потока

Ну и еще, можно увидеть небольшое сообщение, которое отправляется и доолжно поступить на вход функции. В кодированном виде, конечно.



Офлайн

#6 Июнь 22, 2009 16:00:45

kvazar
От:
Зарегистрирован: 2009-01-05
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение входящего потока

Lexander
Кстати, вместо
parse.unquote(line.replace(“+”,“ ”))
можно использвать
parse.unquote_plus(line) с тем же эффектом
Это я знаю)
Lexander
Ну и еще, можно увидеть небольшое сообщение, которое отправляется и доолжно поступить на вход функции. В кодированном виде, конечно.
Честно говоря не понял, что вы имеете ввиду…
Какое небольшое сообщение и что за функция?..



Офлайн

#7 Июнь 22, 2009 17:29:58

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Чтение входящего потока

Забыл поставить знак вопроса :)
Давайте исходные данные, короче.



Офлайн

#8 Июнь 23, 2009 15:15:22

kvazar
От:
Зарегистрирован: 2009-01-05
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение входящего потока

Было бы гораздо легче, если бы вы смогли это повторить у себя на компе.
У вас есть под windows веб-сервер с python?
Я бы тогда мог прислать файл, чтобы вы попробовали отправить его через форму python'у.



Офлайн

#9 Июнь 23, 2009 18:17:30

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Чтение входящего потока

К сожалению, не могу уделить этому вопросу много времени.
Установлен Denwer+ActivePython 2.5 к нему. Если все заведется с полоборота, могу посмотреть. Если нет - уж не обессудьте.



Отредактировано (Июнь 23, 2009 18:18:27)

Офлайн

#10 Июнь 23, 2009 20:25:20

kvazar
От:
Зарегистрирован: 2009-01-05
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение входящего потока

понимаю конечно, время дорого -)
для нужной картины всё-таки нужна версия 3.0.
Заводится вроде легко, просто папку с питоном закинуть.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version