Найти - Пользователи
Полная версия: Философия и практика upload файлов на сервер
Начало » Web » Философия и практика upload файлов на сервер
1 2 3 4
mistercx
Приветствую всех!

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

Есть 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
dimabest
1. Решается настройками веб-сервера (например для Apache http://httpd.apache.org/docs/2.0/mod/core.html#limitrequestbody)
pioner
Посмотрите модуль CGI. В нем есть переменная maxlen=0, т.е. неограниченная длина.
Попробуйте с ней поработать, если вы CGI пользуетесь.
mistercx
Нагуглил всё же решение: ограничивать на уровне 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 - респект, пока нашел сие сам - ночь пропала!
pioner
можно LimitRequestBody использовать…это как вам удобнее.
насчет вторичности питона - да он от сервера берет, но в самом питоне обработать можно изящнее.
4. манипуляции с питоном и приведут к тому что питоновское решение будет и без апача работать.
mistercx
pioner
можно LimitRequestBody использовать…это как вам удобнее.
насчет вторичности питона - да он от сервера берет, но в самом питоне обработать можно изящнее.
4. манипуляции с питоном и приведут к тому что питоновское решение будет и без апача работать.
Я не совсем понимаю Вашу мысль. Попробовал сабмитить форму вообще “налево” - всё равно без LimitRequestBody сначала заливает весь файл, а только потом возвращает в браузер 404 - Not found

Как Вы предлагаете обрабатывать upload на Питоне если он ждет данные от Апача, а тот их все грузит?
Разве что путём написания демона на Питоне который будет слушать специально отведённый для этого порт…
pioner
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, сюда отпишитесь…будет нам обоим польза.
mistercx
lorien
> Как ваш скрипт отдает 404 (или что-то еще), без вашего ведома?

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

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

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

CharsetRecodeMultipartForms off

Эта директива отключает перекодировку данных, отправляемых из html-формы в формате multipart/form-data (который и применяется для загрузки файлов на сервер с помощью html-формы). Учитывайте, что если в форме, данные из которой принимает скрипт с отключенной перекодировкой, есть текстовые поля, то перекодировать их вам придется самостоятельно.
возможно и вам поможет…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB