简体   繁体   English

处理curl文件上传请求时,Python HTTP服务器中的KeyError

[英]KeyError in Python HTTP server when handling curl file upload requests

I have a HTTP server in Python which handles file upload requests from curl 我在Python中有一个HTTP服务器,用于处理来自curl的文件上传请求

class HTTPRequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
            if re.search('/api/v1/addphoto', self.path):
                    form_data=cgi.FieldStorage()
                    file_data=form_data['photofile'].value 
                    # Next I will save this file 
                    # fp =open('some/file','wb')
                    # fp.write(file_data)
                    # fp.close()

Now I have to use curl to send the request, and the command is 现在我必须使用curl来发送请求,命令是

curl -i -F name=photofile -F filedata=@01.jpeg http://server_ip:port/api/v1/addphoto

But the server report error 但是服务器报告错误

File "./apiserver.py", line 21, in do_POST
    file_data=form_data['photofile'].value
File "/usr/lib/python2.7/cgi.py", line 541, in __getitem__
    raise KeyError, key
KeyError: 'photofile'

What is the problem here? 这里有什么问题?

KeyError is raised when no key found in the dictionary. 在字典中找不到键时引发KeyError

I'm not familiar with cgi.FieldStorage but I guess you're expected to get a dictionary and the key 'photofile' is missing. 我对cgi.FieldStorage不熟悉,但是我想您应该得到字典,而键'photofile'丢失了。 Just print the entire form_data and see it's content. 只需打印整个form_data并查看其内容即可。

You can use form_data.get('photofile', '') to get default value and avoid the exception. 您可以使用form_data.get('photofile', '')获得默认值并避免异常。

BTW, for writing to a file you can use with statement as a context manager. 顺便说一句,要写入文件,您可以将with语句用作上下文管理器。

with open('some/file','wb') as fp:
    fp.write(file_data)

OK, I find the reason and how to do it from here . 好的,我从这里找到原因以及如何做。

The reason is "You can't embed the CGI code in the server code like that. The whole point of CGIHTTPServer (and CGI in general) is that it executes separate scripts in designated directories and returns the output. Because you had overridden the do_POST method, the code to parse the form data was never called ." 原因是“您不能像这样将CGI代码嵌入服务器代码中。CGIHTTPServer(通常是CGI)的全部要点是,它在指定的目录中执行单独的脚本并返回输出。 因为您已经覆盖了do_POST方法中,从未调用过解析表单数据的代码 。” (Actually I print the form_data and it is empty - " None, None, [] "). (实际上,我打印了form_data,它是空的-“ None, None, [] ”)。

And to fix it, use passed in parameters ( details ) 要解决此问题,请使用传入的参数( 详细信息

 form = cgi.FieldStorage(
        fp=self.rfile, 
        headers=self.headers,
        environ={'REQUEST_METHOD':'POST',
                 'CONTENT_TYPE':self.headers['Content-Type'],
                 })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM