i made simple web server like below.
import BaseHTTPServer, os, cgi
import cgitb; cgitb.enable()
html = """
<html>
<body>
<form action="" method="POST" enctype="multipart/form-data">
File upload: <input type="file" name="upfile">
<input type="submit" value="upload">
</form>
</body>
</html>
"""
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("content-type", "text/html;charset=utf-8")
self.end_headers()
self.wfile.write(html)
def do_POST(self):
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
query = cgi.parse_multipart(self.rfile, pdict)
upfilecontent = query.get('upfile')
if upfilecontent:
# i don't know how to get the file name.. so i named it 'tmp.dat'
fout = file(os.path.join('tmp', 'tmp.dat'), 'wb')
fout.write (upfilecontent[0])
fout.close()
self.do_GET()
if __name__ == '__main__':
server = BaseHTTPServer.HTTPServer(("127.0.0.1", 8080), Handler)
print('web server on 8080..')
server.serve_forever()
In the do_Post method of BaseHTTPRequestHandler, i got the uploaded file data successfully.
But i can’t figure out how to get the original name of the uploaded file.
self.rfile.name is just a ‘socket’
How can i get the uploaded file name?
Pretty broken code you’re using there as a starting point (e.g. look at that
global rootnodewhere namerootnodeis used nowhere — clearly half-edited source, and badly at that).Anyway, what form are you using “client-side” for the
POST? How does it set thatupfilefield?Why aren’t you using the normal
FieldStorageapproach, as documented in Python’s docs? That way, you could use the.fileattribute of the appropriate field to get a file-like object to read, or its.valueattribute to read it all in memory and get it as a string, plus the.filenameattribute of the field to know the uploaded file’s name. More detailed, though concise, docs onFieldStorage, are here.Edit: now that the OP has edited the Q to clarify, I see the problem:
BaseHTTPServerdoes not set the environment according to the CGI specs, so thecgimodule isn’t very usable with it. Unfortunately the only simple approach to environment setting is to steal and hack a big piece of code fromCGIHTTPServer.py(wasn’t intented for reuse, whence the need for, sigh, copy and paste coding), e.g….:This could be substantially simplified further, but not without spending some time and energy on that task:-(.
With this
populenvfunction at hand, we can recode:…and live happily ever after;-). (Of course, using any decent WSGI server, or even the demo one, would be much easier, but this exercise is instructive about CGI and its internals;-).