Html Upload mit Python-CGI - korrupte files

OP #3536027
Lesenswert?

Hallo,

ich versuche gerade nach einem Beispiel einen lokalen File-Upload per 
Python-CGI zu implementieren. Der Transfer läuft durch und das Script 
meldet einen erfolgreichen Upload - nur leider sind die Files (z.B. 
jpeg-Bilder) danach viel kleiner und lassen sich nicht öffnen.

Server:
1
import http.server
2
PORT = 8080
3
handler = http.server.CGIHTTPRequestHandler
4
httpd = http.server.HTTPServer(("", PORT), handler)
5
print("serving at port", PORT)
6
httpd.serve_forever()

Upload-Form:
1
<div>
2
<form enctype="multipart/form-data" action="cgi-bin/upload.py" method="post">
3
    <p>File: <input type="file" name="file"></p>
4
      <input type="submit" value=" Start Upload ">
5
</form>
6
<div>

CGI:
1
#!C:\Python33\python.exe 
2
#!/usr/bin/env python
3
import cgi, os
4
import cgitb; cgitb.enable()
5

6
try: # Windows needs stdio set for binary mode.
7
    import msvcrt
8
    msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
9
    msvcrt.setmode (1, os.O_BINARY) # stdout = 1
10
except ImportError:
11
    pass
12

13
form = cgi.FieldStorage()
14

15
# A nested FieldStorage instance holds the file
16
fileitem = form['file']
17

18
# Test if the file was uploaded
19
if fileitem.filename:
20
   
21
   # strip leading path from file name to avoid directory traversal attacks
22
   fn = os.path.basename(fileitem.filename)
23
   open('files\\' + fn, 'wb').write(fileitem.file.read())
24
   message = 'The file "' + fn + '" was uploaded successfully'
25
   
26
else:
27
   message = 'No file was uploaded'
28
   
29
print("""\
30
Content-Type: text/html\n
31
<html><body>
32
<p>%s</p>
33
</body></html>
34
""" % (message,))

Hat jemand eine Idee?
OP #3537422
Lesenswert?

Stimmt, das Schließen des Files fehlt. Scheint aber leider nicht das 
Problem zu sein. Der Aufruf "fileitem.file.read()" liefert schon eine 
Sequenz, die viel kleiner ist als das hochgeladene File. Außerdem ist 
die Größe jedes Mal anders.

> Und wenn du schon ein File hast: Warum nicht verschieben statt zu
> kopieren?
Steh grad auch dem Schlauch...wie meinst Du das?
Persönliche Seite #3537689
Lesenswert?

Philip K. schrieb:
> Steh grad auch dem Schlauch...wie meinst Du das?

fileitem.file scheint doch shcon ein File zu sein. Wieso also nicht 
diese mit move(? schau halt mal in die API...) ans gewünschte Ziel 
verschieben?

Philip K. schrieb:
> Der Aufruf "fileitem.file.read()" liefert schon eine Sequenz, die viel
> kleiner ist als das hochgeladene File

Lies dir mal die API durch und nimm dir meinen Hinweis bezüglich der 
Rückgabewerte zu Herzen. Ich kenne nun die Python API nicht aber in 
nahezu allen I/O APIs ist es so, das das lesen nicht immer vollständig 
sein muss sondern in "Happen" passiert, d.h. man liest (und schreibt) 
solange bis der "da-kommt-nix-mehr" Marker (siehe API!!) kommt.
OP #3537753
Lesenswert?

fileitem.file ist vom Typ io.BufferedIOBase also ein Stream-Object.

http://docs.python.org/3.3/library/io.html#io.BufferedIOBase

Da steht:
"read(n=-1)¶
Read and return up to n bytes. If the argument is omitted, None, or 
negative, data is read and returned until EOF is reached. An empty bytes 
object is returned if the stream is already at EOF."

Sollte also nach meinem Verständnis so funktionieren. Ein nochmaliger 
Aufruf liefert auch ein leeres bytes-Objekt. Ich habe auch mehrere 
Beispiele zu dem Thema gefunden und in allen wird auf diese Art gelesen.

Vielleicht stimmt ja auch was mit dem Python-Server nicht. Ich werds mal 
auf meinem RPI mit lighttpd testen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren