python CGI:上传错误 [英] python CGI : upload error

查看:101
本文介绍了python CGI:上传错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是Python 3.4版

I use Python version 3.4

这是python中的服务器源代码

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()

并在此处上传HTML源代码

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''

我听不懂这个问题吗?

有时消息查询为空!

所以我写了if not query: return,对吗?

如何接收上传的文件并将其保存在服务器中?

and how can I receive uploaded file and save them in server?

推荐答案

您需要将查询拆分为尽可能多的换行符;里面可以嵌入换行符.在此处使用str.partition()代替:

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')

您将不得不解析标题; Content-Type标头包含多部分边界; FieldStorage实例需要使用它来确定字段的开始和结束位置.

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})

请注意,带有文件上传的HTTP消息很容易包含1024字节以上的内容;你只会读那么一点. 仅标题就可以轻松组成大部分邮件;我的浏览器发送了819个字节的标头,并将其保存在一个数据包中.然后,您的connectionSocket.recv(1024)呼叫将仅包含那些标题,并且您将需要仍然读取更多数据.

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.

这篇关于python CGI:上传错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆