Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Web
  • » Философия и практика upload файлов на сервер [RSS Feed]

#1 Ноя. 13, 2009 22:49:07

mistercx
От:
Зарегистрирован: 2009-09-21
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

Приветствую всех!

Столкнулся с интересной проблемой и нагуглить её решение пока не удалось.

Есть HTML-форма:

<FORM name="postform" enctype="multipart/form-data" method="post" action="/admin/pcgi/upload.py">
<INPUT name="filename" type="file"/>
<INPUT name="access" type="hidden" value="12345"/>
<input type="submit"/>
</FORM>
Как все успели заметить, традиционная форма отправки файла на сервер.

Так вот: скрипт на Python начинает свою работу ТОЛЬКО ПОСЛЕ ТОГО, КАК ЗАГРУЖЕН ВЕСЬ ФАЙЛ, а это не есть гуд, поскольку можно закачивать любые объемы. Решение следующего плана:

SIZE=int(os.environ['CONTENT_LENGTH'])
LIMIT=24000

if SIZE>LIMIT:
print "Размер данных превышен!"
sys.exit()
не работает, файл опять таки закачивается полностью до выполнения этого кода.

Отсюда следующие вопросы:

1. Возможно-ли решение проблемы принципиально?
2. Если да, тогда опубликуйте работающий кусок кода и 2-3 пояснения к нему.

Если такое невозможно, остается только загружать файлы через Flash (там можно получать размер файла локально), но в принципе от подделки TCP-пакетов и отправки их по сокетам это, увы, тоже не спасет… :(

Какие будут мнения?


Кстати, интереса ради проверил проблему на PERL - аналогичная картина и на Windows и на FreeBSD



Отредактировано (Ноя. 13, 2009 23:07:46)

Офлайн

#2 Ноя. 14, 2009 00:24:02

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

1. Решается настройками веб-сервера (например для Apache http://httpd.apache.org/docs/2.0/mod/core.html#limitrequestbody)



Офлайн

#3 Ноя. 14, 2009 00:51:53

pioner
От:
Зарегистрирован: 2009-10-21
Сообщения: 146
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

Посмотрите модуль CGI. В нем есть переменная maxlen=0, т.е. неограниченная длина.
Попробуйте с ней поработать, если вы CGI пользуетесь.



Офлайн

#4 Ноя. 14, 2009 17:34:57

mistercx
От:
Зарегистрирован: 2009-09-21
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

Нагуглил всё же решение: ограничивать на уровне Apache .htaccess (LimitRequestBody 1024000 - при привышении upload возвращает 413 ошибку: Request Entity Too Large).

Ещё можно поиграться с RLimitCPU, RLimitMEM, RLimitNPROC - пока с ними не разбирался. Одним словом:

1. Проблема решается.
2. Решается на уровне Web-сервера (Python тут не при чём, он получает то, что отдает Web-сервер)
3. Для PHP есть отдельные директивы для .htaccess (для Python пока ничего похожего не нашёл)
4. Все манипуляции с Python'овским модулем cgi, исходя из этого, ни к чему не приведут - Python вторичен.

Если есть ещё какие комментарии по сабжу - welcome!

dimabest - респект, пока нашел сие сам - ночь пропала!



Отредактировано (Ноя. 14, 2009 17:37:02)

Офлайн

#5 Ноя. 15, 2009 00:00:50

pioner
От:
Зарегистрирован: 2009-10-21
Сообщения: 146
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

можно LimitRequestBody использовать…это как вам удобнее.
насчет вторичности питона - да он от сервера берет, но в самом питоне обработать можно изящнее.
4. манипуляции с питоном и приведут к тому что питоновское решение будет и без апача работать.



Офлайн

#6 Ноя. 15, 2009 00:40:46

mistercx
От:
Зарегистрирован: 2009-09-21
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

pioner
можно LimitRequestBody использовать…это как вам удобнее.
насчет вторичности питона - да он от сервера берет, но в самом питоне обработать можно изящнее.
4. манипуляции с питоном и приведут к тому что питоновское решение будет и без апача работать.
Я не совсем понимаю Вашу мысль. Попробовал сабмитить форму вообще “налево” - всё равно без LimitRequestBody сначала заливает весь файл, а только потом возвращает в браузер 404 - Not found

Как Вы предлагаете обрабатывать upload на Питоне если он ждет данные от Апача, а тот их все грузит?
Разве что путём написания демона на Питоне который будет слушать специально отведённый для этого порт…



Офлайн

#7 Ноя. 15, 2009 14:46:13

pioner
От:
Зарегистрирован: 2009-10-21
Сообщения: 146
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

mistercx
Как Вы предлагаете обрабатывать upload на Питоне если он ждет данные от Апача, а тот их все грузит?
повторюсь:
pioner
Посмотрите модуль CGI. В нем есть переменная maxlen=0…
Модуль CGI постоянно проверяет величину загруженного и сравнивает с maxlen. До вызова cgi.FieldStory, поставте cgi.maxlen=ваше значение в байтах.
Кроме этого, если файл короткий, он его не в файл запишет а в объект StringIO, …
Посмотрите исходник CGI ОБЯЗАТЕЛЬНО и некоторые вопросы отпадут.
Если вы не используете mod_python, то столкнетесь с тем что бинарные файлы апач обрезает и до питона они не доходят. С mod_python такой проблемы нет. Скажу честно, maxlen не пробовал, но она там есть и для того о чем я уже написал.

mistercx
…всё равно без LimitRequestBody сначала заливает весь файл, а только потом возвращает в браузер 404 - Not found
Как ваш скрипт отдает 404 (или что-то еще), без вашего ведома? Или это апач так шалит? C mod_python у вас должен быть полный контроль над заголовками.

mistercx
путём написания демона на Питоне который будет слушать специально отведённый для этого порт…
Хотел поступить так же, пока не поставил mod_python - апач обрезал бинарники. Вы хотите ограничить файл по величине. Давайте попробуйте с maxlen, сюда отпишитесь…будет нам обоим польза.



Офлайн

#8 Ноя. 15, 2009 18:28:16

mistercx
От:
Зарегистрирован: 2009-09-21
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

lorien
> Как ваш скрипт отдает 404 (или что-то еще), без вашего ведома?

Видимо, имелос в виду, что обращение к несуществующему CGI скрипту всё равно сопровождается закачкой файла на сервер полностью.
Да, именно это и имелось ввиду. Я попробовал сабмитить форму на несуществующий сценарий. Результат: сначала загрузился весь большой файл, а только затем Апач вернул в броузер 404 ошибку - не найдено. Из чего сделал, как мне кажется, логический вывод о непричастности к закачке Питона вообще и модуля CGI в частности. К тому же, постингом выше писал, что исключил Питон ещё раньше, попробовав принимать файл через Перл - результат тот же.

pioner
> Если вы не используете mod_python, то столкнетесь с тем что бинарные файлы апач обрезает и до питона они не доходят.
mod_python пока не использую, смотрю в сторону WSGI, но тем не менее бинарники у меня загружаются без всяких проблем и на Windows локально и на FreeBSD удалённо. Т.е. или стд. вход у Вас не переключён в бинарный режим, или локализированный Web-сервер чудит, имхо.



Отредактировано (Ноя. 15, 2009 18:30:15)

Офлайн

#9 Ноя. 16, 2009 00:42:48

pioner
От:
Зарегистрирован: 2009-10-21
Сообщения: 146
Репутация: +  0  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

mistercx
Т.е. или стд. вход у Вас не переключён в бинарный режим, или локализированный Web-сервер чудит, имхо.
Как stdin в бинарный режим перевести?
stdin открыт с флагом ‘r’. Не нашел как поменять режим открытия файла когда он уже открыт.

p.s. бинарники и в текстовом режиме должны читаться, перевод строк не будет работать. Заметил что файл режется случайным образом - скорее это не питон а апач, НО ЗАЧЕМ! защита такая?



Отредактировано (Ноя. 16, 2009 00:55:40)

Офлайн

#10 Ноя. 16, 2009 16:49:10

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Философия и практика upload файлов на сервер

pioner
p.s. бинарники и в текстовом режиме должны читаться, перевод строк не будет работать. Заметил что файл режется случайным образом - скорее это не питон а апач, НО ЗАЧЕМ! защита такая?
У меня на хост через cgi все бинарники нормально заливаются. Дело в апаче.
Помню, на одном хостинге с аплоадом были проблемы. Заработало после прочтения FAQ:
Почему при загрузке скриптом не загружаются (бьются) бинарные файлы (картинки, архивы)?
На нашем сервере используется русский Apache, который по умолчанию перекодирует все принимаемые данные из множества русских кодировок, используемых у клиента, в одну стандартную, в которой они хранятся на сервере. На нашем сервере это windows-1251. Бинарные данные не должны подвергаться перекодированию, соответственно, эту функцию следует отключить. Для этого нужно в каталоге, где лежит загружающий скрипт, создать файл .htaccess и поместить в него директиву, отключающую перекодировку.

CharsetRecodeMultipartForms off

Эта директива отключает перекодировку данных, отправляемых из html-формы в формате multipart/form-data (который и применяется для загрузки файлов на сервер с помощью html-формы). Учитывайте, что если в форме, данные из которой принимает скрипт с отключенной перекодировкой, есть текстовые поля, то перекодировать их вам придется самостоятельно.
возможно и вам поможет…



Отредактировано (Ноя. 16, 2009 16:50:03)

Офлайн

  • Начало
  • » Web
  • » Философия и практика upload файлов на сервер[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version