Reputation: 15
I use Python version 3.4
and this is server source code in python
import io
from socket import *
import threading
import cgi
serverPort = 8181
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('', serverPort))
serverSocket.listen(5)
def serverHandle(connectionSocket, addr):
try:
message = connectionSocket.recv(1024)
if not message:
return
path = message.split()[1].decode('utf-8')
if path == '/':
connectionSocket.send(b'HTTP/1.1 200 OK\r\n')
connectionSocket.send(b'Content-type: text/html\r\n\r\n')
with open('upload.html', 'rb') as f:
connectionSocket.send(f.read())
elif path == '/upload':
header = message.split(b'\r\n\r\n')[0]
query = message.split(b'\r\n\r\n')[-1]
if not query:
return
fp = io.BytesIO(query)
form = cgi.FieldStorage(fp, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE': 'multipart/form-data'})
f = open(form.filename, 'w')
f.write(form.file)
f.close()
connectionSocket.close()
except IOError:
connectionSocket.send('404 File Not Found\r\n\r\n'.encode('utf_8'))
connectionSocket.close()
while True:
connectionSocket, addr = serverSocket.accept();
threading._start_new_thread(serverHandle, (connectionSocket, addr))
serverSocket.close()
and upload HTML source is here
<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>
I try upload file to server and save file in directory but error is occurred like this
Unhandled exception in thread started by <function serverHandle at 0x000000000240CBF8>
Traceback (most recent call last):
File "C:\Users\Inwoo\Eclipse\workspace\WebServer\src\webserver1.py", line 36, in serverHandle
form = cgi.FieldStorage(fp, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE': 'multipart/form-data'})
File "C:\Python34\lib\cgi.py", line 559, in __init__
self.read_multi(environ, keep_blank_values, strict_parsing)
File "C:\Python34\lib\cgi.py", line 681, in read_multi
raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
ValueError: Invalid boundary in multipart form: b''
I cant understand this problem?
and sometimes query of message is empty!
so I wrote if not query: return
, is it correct?
and how can I receive uploaded file and save them in server?
Upvotes: 1
Views: 1287
Reputation: 1123420
You need to not split the query on as many newlines as you do; there can be embedded newlines in it. Use str.partition()
instead here:
header, _, query = message.partition(b'\r\n\r\n')
You'll have to parse the headers; the Content-Type
header contains the multipart boundary; the FieldStorage
instance needs this to determine where the fields begin and end.
import re
content_type = re.search(br'content-type:\s+(.*?)\r\n', header, flags=re.I).group(1)
form = cgi.FieldStorage(fp, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE': content_type})
Take into account that a HTTP message with a file upload can easily contain much more that 1024 bytes; you only ever read that little. Just the headers can easily make up most of the message; my browser sends 819 bytes for the header and keeps that in one packet. Your connectionSocket.recv(1024)
call will then contain just those headers and you'll need to read more data still.
Upvotes: 1