Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 31, 2017 16:14:25

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Python 2.7.13 (Python 3.5.2 тоже не хочет отсылать нормально).
Есть один “секретный сервис”, куда спокойно отсылались файлы через requests.post:

 files = {'sample': (file_to_check.name, file_to_check.read(), 'multipart/form-data')}
requests.post(scan_url, data={'api_key':apikey, 'private':'true'}, files=files)
Пока кто-то не решил отправить файл вроде “Квартальный отчет.xls”, тот сервис возвращает ошибку 500.
Казалось бы, сервис не работает как надо, но, curl отправляет такой файл на ура:
 curl -X POST https://secret_url -F "sample=@Квартальный отчет.xls" -F "private=true"

Значит, что-то с питоном не так. Начал тестировать отправку файлов и дополнительных параметров здесь:
http://posttestserver.com
И вот файл:
 files = {'sample': (u"Тестовый файл.exe", 'dumb content', 'multipart/form-data')}
и таков результат http://www.posttestserver.com/data/2017/10/31/example/13.57.27111436832

То есть, вроде и есть контент, но файл не передан. Если же, передать через urllib2, а не через requests с помощью такого решения: http://python.su/forum/topic/7182/, то на этом тестовом сервисе показывает, что файл был передан, но тот “секретный сервис” до сих пор возвращает ошибку 500.

Что же можеть быть не так, и какое может быть решение?



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#2 Окт. 31, 2017 16:28:28

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Master_Sergius
возвращает ошибку 500
А я бы на вашем месте задумался над тем, что код 500 - это ошибка сервера. Постольку поскольку эта ошибка возникает, её можно куда-нибудь залогировать (да хоть в консоль) и понять, на чем же собственно скрипт падает. Постольку поскольку вы пишите в ветку для экспертов, я не собираюсь вас учить дебажить код (раз уж вы эксперт, то вероятно, умеете это делать). Покажите трейсбэк ошибки.



Офлайн

#3 Окт. 31, 2017 16:40:48

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Ну, в ветку для экспертов пишу в надежде найти экспертов
Во-вторых, никак не могу показать трейсбек, так как это не мой сервис, у меня есть лишь урл и апи ключ, далее всё закрыто от меня. Библиотека requests выполняет запрос и возвращает вот такое:

 <html>
<head><title>500 Internal Server Error</title></head>
<body bgcolor="white">
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>
Естественно, это никак не помогает. Я писал им в поддержку и всё, что они отписали - curl работает, у вас что-то с питоном.



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#4 Окт. 31, 2017 16:43:54

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Master_Sergius
Ну, в ветку для экспертов пишу в надежде найти экспертов
Надо полагать, если вы пишете в ветку для новичков, то ожидаете получить ответ от новичка .



Офлайн

#5 Окт. 31, 2017 16:48:19

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Master_Sergius
Пробовали переименовать файл в латиницу?



Офлайн

#6 Окт. 31, 2017 16:48:27

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

FishHook
Надо полагать, если вы пишете в ветку для новичков, то ожидаете получить ответ от новичка
Ну, да, так звучит смешно. Но, обычно, в ветке для новичков простенькие вопросы, почему бы и новичкам не помочь другим новичкам?
В любом случае, это не решает мою проблему



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#7 Окт. 31, 2017 20:04:31

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Подумал, а что если подменять тело запроса - ведь при нормальном раскладе, тело выглядит как-то так:

 <кусок начала опущен>
--e2876811736e4bdb80db97b7e4927548                                              
Content-Disposition: form-data; name="private"                                  
                                                                                 
true                                                                            
--e2876811736e4bdb80db97b7e4927548                                              
Content-Disposition: form-data; name="sample"; filename="dumb filename"
Content-Type: multipart/form-data                                               
                                                                                 
dumb content                                                                    
--e2876811736e4bdb80db97b7e4927548--         

А когда подсунуть юникод в либу requests, то получается так:

 <кусок начала опущен>
--e2876811736e4bdb80db97b7e4927548                                              
Content-Disposition: form-data; name="private"                                  
                                                                                 
true                                                                            
--e2876811736e4bdb80db97b7e4927548                                              
Content-Disposition: form-data; name="sample"; filename*=utf-8''%2F%D0%9F%D0%B0%D1%81%D0%BB%D0%B0%D0%B2%D1%81%D0%BA%D0%B8%D0%B9
Content-Type: multipart/form-data                                               
                                                                                 
dumb content                                                                    
--e2876811736e4bdb80db97b7e4927548--         

К примеру, появляется, звёздочка и кодировка. Пробовал хотя бы звёздоку убрать, ну а вдруг - но лезут ошибки типа плохой запрос. Я вроде добавил символ “\r”, что ещё ему не так?
То есть код теперь такой:
 req = requests.Request('POST', scan_url, data={'api_key': API_KEY, 'private':'true'}, files=files)
prepared = req.prepare()                                                               
s = requests.Session()
prepared.body = re.sub('filename.*', 'filename="%s"\r' % fname, prepared.body)
response = s.send(prepared)
print response.text

Ну и отсылать не хочет. Но, может вы подскажете, что ещё не хватает, либо это подтолкнет вас к другому решению.



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#8 Ноя. 1, 2017 04:43:25

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

спрошу еще раз
вы пробовали “Квартальный отчет.xls” переименовать так, чтобы в его названии были только буквы ASCII?



Офлайн

#9 Ноя. 1, 2017 11:42:35

Master_Sergius
Зарегистрирован: 2013-09-12
Сообщения: 271
Репутация: +  7  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Ну если передать строку юникод, но там все ASCII, то всё работает, да. А как заставить работать вот это? Тем более, что это скрипт автоматический, то есть никто руками переименовывать файлы не будет. Что пришло, то и должно переслаться туда.



———————————————————————————
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Офлайн

#10 Ноя. 1, 2017 11:55:25

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как передать файл через post с именем в юникоде?

Master_Sergius
А с чего вы уверены, что оно должно работать? Это сторонний сервис, у него вполне могут быть свои ограничения. Мы с вами нашли вроде как корень проблемы - кодировка названия файла. Боюсь, что это ваши проблемы и вам придется что-то придумывать с названиями. Впрочем, зачем вам физически переименовывать файл в файловой системе? Вам надо, чтобы он улетел с нужным именем в хидере, ну и подсовывайте туда какой-нибудь шаблон типа “file.xls” в своём скрипте непосредственно в момент отправки.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version