Search code examples
pythonuploadcgimultipart

Python CGI - How can I get uploaded file in TCP server?


I made TCP server like this

serverPort = 8181
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('', serverPort))
serverSocket.listen(5)

and I can receive user's login data like this

elif path == '/login':
        header, query = message.split(b'\r\n\r\n')
        fp = io.BytesIO(query)
        form = cgi.FieldStorage(fp, environ={'REQUEST_METHOD':'POST'})

        connectionSocket.send(b'HTTP/1.1 200 OK\r\n')
        connectionSocket.send(b'Content-type: text/html\r\n\r\n')
        connectionSocket.send('<p>Hello {}!</p>'.format(form.getvalue('id')).encode('utf-8'))

but I can't receive multipart upload data!!T^T

I wrote HTML for upload file

<HTML>
<BODY>

<FORM ENCTYPE="multipart/form-data" ACTION="http://127.0.0.1:8181/upload" METHOD=POST>
    File to process: <INPUT NAME="file" TYPE="file">
    <INPUT TYPE="submit" VALUE="Send File">
</FORM>

</BODY>
</HTML>

how can I receive file and save that?

I know about using HTTP server is good way for this problem

but I shoud using TCP server like that...

please help me! i cant solve this problem...T^T


Solution

  • File uploads use a different content type; normally a POST uses application/x-www-form-urlencoded, but a file upload requires the form to use multipart/form-data.

    The cgi.FieldStorage class will normally sniff this from the CGI environment variables, but you are not using CGI here, you are parsing everything at the lowest level. You'll have to pass in a CONTENT_TYPE header here:

    form = cgi.FieldStorage(fp, environ={
        'REQUEST_METHOD':'POST', 'CONTENT_TYPE': 'multipart/form-data'})
    

    Ideally, that header is parsed from the incoming headers, of course.