|
|
|
|
|
для: heed
(20.09.2009 в 20:50)
| | Везет Вам =). Этот же пример у меня не работает. Единственное, что у меня версия питона 2.5. Короче голова уже кругом идкт %) | |
|
|
|
|
|
|
|
для: nskrypnik
(20.09.2009 в 16:17)
| | у меня сохраняются точные копии (win32 Apache2.2.11)
только скрипт кривоватый :)
#!c:\Pyton\python.exe
#<?Python v2.6.2
import sys
sys.stderr = sys.stdout
import cgi
print "Content-Type: text/html; charset=cp1251" # HTML is following
print # blank line, end of headers
print "hellofworld"
print '<form enctype="multipart/form-data" action="" method="post">'
print '<input type="hidden" name="MAX_FILE_SIZE" value="30000" />'
print ' : <input name="userfile" type="file" />'
print '<input type="submit" value="Send File" />'
print '</form>'
form = cgi.FieldStorage()
if not (form.has_key("userfile") and form.has_key("MAX_FILE_SIZE")):
print "<H1>Empty</H1>"
print "<p>MAX_FILE_SIZE:", form["MAX_FILE_SIZE"].value
fileitem = form["userfile"]
with open('test.bin', 'wb') as file:
file.write(fileitem.value)
print fileitem
|
| |
|
|
|
|
 86 байт |
|
|
для: heed
(20.09.2009 в 17:26)
| | [quote=heed]в том что здесь смоглось напечататься нет \x00 :)[/quote]
Угу, сейчас Вам напечатается знак терминала в форуме =). В аттаче находится тот самый гиф, можете глянуть его в хексе.
fileitem.file.readline() - только для текстовых файлов катит. Файл у меня открывается с буквой b, а насчет stdin - это уже надо смотреть реализацию cgi.FieldStorage(), но тем не мене когда апач запускается на линуксе - все работает нормально. Проблема только под вин. В общем так и не разобрался. | |
|
|
|
|
|
|
|
для: nskrypnik
(20.09.2009 в 16:13)
| | в том что здесь смоглось напечататься нет \x00 :)
мне кажется Content-Length: 381 на что нужно ориентироваться читая stdin , и проверяя длинну полученных данных
открыл справку по случайно однажды установленному у меня pyton :) , а там такой пример чтения файла с использованием import cgitb
#<?pyton
fileitem = form["userfile"]
if fileitem.file:
# It's an uploaded file; count lines
linecount = 0
while 1:
line = fileitem.file.readline()
if not line: break
linecount = linecount + 1
|
что-то мне не нравится это fileitem.file.readline() , должен быть способ считать столько данных сколько нужно в байтах
или должно быть что-то из другого модуля
#<?pyton
import cgi
form = cgi.FieldStorage()
user = form.getfirst("user", "").upper() # This way it's safe.
for item in form.getlist("item"):
do_something(item)
|
Думаю и файл и stdin должны открываться с буквой b во втором параметре open или подобных функций
, насчёт переключения режима уже после открытия дескрипторов не смог найти | |
|
|
|
|
|
|
|
для: .......
(20.09.2009 в 14:15)
| | Согласен, но допустим в примере выше NULL присутствует даже в том, что уже передалось.
Пайтон думаю совсем не обязательно знать - проблема в том, что апач передает в stdin скрипту, я не проверял другие языки, но мне кажется возникла бы аналогичная ошибка.
И еще: такая проблема только под win32. В линуксе все работает отлично. | |
|
|
|
|
|
|
|
для: Trianon
(20.09.2009 в 14:08)
| | Вот запрос отловленный LiveHTTPheaders
http://localhost:8080/ezoloto/uploader.py
POST /ezoloto/uploader.py HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; uk; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: uk,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost:8080/ezoloto/?opt=manage&addnew=1&catId=84
Cookie: sid=5b2a296273a7699b3835a360e393b560f4e b8a16; sk_your_site=20090916211847-003f9172703d8eed8d0f7e18fe8257e2; virtuemart=mqcao6d2i2h0os3co4oeioagu7; 4877db55482b87a0f08ee84fe6e3e6ad=-; clickedFolderFrameless=; clickedFoldercheckboxTree=; d541b16baa4b2002091e84ca9bed5da2=gqove9440f8abi9s0j7hbt9nc1; 87356eef8b63a9eda98f3f384caac2ee=baa2428d2a28dca66a5b715d0148dc16; s=1
Content-Type: multipart/form-data; boundary=---------------------------207831803532226
Content-Length: 381
-----------------------------207831803532226
Content-Disposition: form-data; name="upThumbImg"
1
-----------------------------207831803532226
Content-Disposition: form-data; name="datafile"; filename="cart.gif"
Content-Type: image/gif
GIF89a Ђ ---яяя!щ , -ЊЏ©Лќ ‚QАЁ¦щъЂ-бш)ЫЦЃ_hb¤љќ•И^хTѕO^>чl
‡Ѓ ;
-----------------------------207831803532226--
HTTP/1.x 200 OK
Date: Sun, 20 Sep 2009 12:08:43 GMT
Server: Apache/2.2.13 (Win32) PHP/5.2.9-2
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
----------------------------------------------------------
Вот то, что выдает чтение stdin CGI-скриптом.
-----------------------------207831803532226
Content-Disposition: form-data; name="upThumbImg"
1
-----------------------------207831803532226
Content-Disposition: form-data; name="datafile"; filename="cart.gif"
Content-Type: image/gif
GIF89a Ђ ---яяя!щ , -ЊЏ©Лќ ‚Q | |
|
|
|
|
автор: ....... (20.09.2009 в 14:15) |
|
|
для: nskrypnik
(20.09.2009 в 11:43)
| | обычно такое бывает когда строковым функциям попадается в строках NULL (\x00)
, должны использоваться только бинарно-безопасные функции
Возможно проблема в том как идёт запись в файл, или как считывается в переменную то что возвращено CGI-модулем
, самим модулям тоже не всегда бывает вполное можно доверять :)
совсем не зная Pyton ничего не могу сказать | |
|
|
|
|
|
|
|
для: nskrypnik
(20.09.2009 в 11:43)
| | можно же сравнить эти два файла (86 и 52 байта)
А вообще неполохо было бы поглядеть сырой поток данных запроса. | |
|
|
|
|
|
|
|
для: heed
(19.09.2009 в 23:32)
| | Разумеется в python есть модуль CGI, разбирающий и stdin и переменные среды. Плюс я так же выводил stdin, как я говорил выше и воочию видел, что данные теряются. Правда я эксперементировал с картинками, только что попробовал текстовый файл - все передалось нормально.
Может в бинарных данных символ есть какой-то, который не нравится апачу или он его принимает за какой-то знак? | |
|
|
|
|
|
|
|
для: nskrypnik
(19.09.2009 в 21:13)
| | незнаю как там в Pyton, но браузер отправляет например такой запрос при отправке мелкого текстового файла
POST /PERL/test_UPLOAD.pl HTTP/1.1
User-Agent: Opera/9.22 (Windows NT 5.1; U; ru)
Host: src
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: ru-RU,ru;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 409
Content-Type: multipart/form-data; boundary=----------k37XzkMiLnoUT0ZP00kwdo
------------k37XzkMiLnoUT0ZP00kwdo
Content-Disposition: form-data; name="MAX_FILE_SIZE"
30000
------------k37XzkMiLnoUT0ZP00kwdo
Content-Disposition: form-data; name="userfile"; filename="test.txt"
Content-Type: text/plain
test test test test test test test test test
test test test test test test test test test
test test test test test test test test test
------------k37XzkMiLnoUT0ZP00kwdo--
|
из такой формы
<form enctype="multipart/form-data" action="http://src/PERL/test_UPLOAD.pl" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Отправить этот файл: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
|
А Apache запускает CGI-обработчили просто передавая post-данные как стандартный ввод
например таким скриптом
#!C:/Perl/bin/perl.exe -w
#<?perl
print "Content-type:text/plain\n\n";
foreach my $var (sort keys %ENV) { # просмотр переменных окружения
print $var . "\t=\t" . $ENV{$var} . "\n";
}
print "\n\n\t\t---\n";
if ($ENV{'CONTENT_LENGTH'}){ # чтение STDIN
my $buffer = '';
binmode STDIN;
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
print $buffer; # с бинарным файлом вывод не всегда получится
}
|
будет получена такая распечатка сначала переменных окружения, а потом того что полученно из STDIN
COMSPEC = C:\WINDOWS\system32\cmd.exe
CONTENT_LENGTH = 409
CONTENT_TYPE = multipart/form-data; boundary=----------wY7Khdy9o1O52CvjuVLbRo
DOCUMENT_ROOT = C:/X_DOCS/src
.................. Здесь немного сократил..............................
SERVER_SOFTWARE = Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.11-dev
SYSTEMROOT = C:\WINDOWS
WINDIR = C:\WINDOWS
---
------------wY7Khdy9o1O52CvjuVLbRo
Content-Disposition: form-data; name="MAX_FILE_SIZE"
30000
------------wY7Khdy9o1O52CvjuVLbRo
Content-Disposition: form-data; name="userfile"; filename="test.txt"
Content-Type: text/plain
test test test test test test test test test
test test test test test test test test test
test test test test test test test test test
------------wY7Khdy9o1O52CvjuVLbRo--
|
Думаю что Вы просто неправильно разбираете то читается из STDIN
, или я не знаю есть-ли вшитые в Pyton функции разбирающие STDIN | |
|
|
|
|