我的 http 服务器收到 post 请求,包括文件,如何也使用 POST 方法转发到外部 URL

my http server got post request including file, how to forward to external URL using POST method too

我有一个问题,我搜索了很多,但这里的 none 个代码符合我的要求

我 运行 python 本地服务器使用 http.server - BaseHTTPRequestHandler

这是我的代码

def run_http():
    port=80
    server_address = ('', port)
    httpd = ThreadingHTTPServer(server_address, serverClass)

    # print('HTTP server running on port %s'% port)
    httpd.serve_forever()

class serverClass(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        self._set_headers()

        if self.path == '/':
            with open("static\index.html", 'r') as f:
                res = f.read()
            self.wfile.write(res.encode('utf-8'))

        elif self.path == '/favicon.ico':
            with open("static\favicon.ico", 'rb') as f:
                res = f.read()
            self.wfile.write(res)
        
        else:
            ...


    def do_HEAD(self):
        self._set_headers()
        
    def do_POST(self):
        # content_length = int(self.headers['Content-Length'])
        # post_data = self.rfile.read(content_length)
        # <= here I need to forward the post request to another URL _POST_URL
        # The post request I received may include file and may be not, so I need to forward the post request as it is

我尝试了一些代码,例如:

ctype, pdict = cgi.parse_header(self.headers['content-type'])
pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
if ctype == 'multipart/form-data':
    fields = cgi.parse_multipart(self.rfile, pdict)
    field_file = {'file':(fields.get('file'), "multipart/form-data")}
    fields.pop('file')
    r = requests.post(_POST_URL+'/in.php', files = field_file, data = fields)

注意:我知道该文件将使用 post 名称 file 该代码有效,但问题是我没有发送文件类型或文件名,我真的无法得到它。 我的方法对吗,或者我应该使用更高效的代码

好的我用了cgi.FieldStorage

如果有人感兴趣,这里是代码;

def do_POST(self):
    form = cgi.FieldStorage( fp=self.rfile, headers=self.headers, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'] })
    
    post_data = {}
    for field in form:
        if field != 'file':
            post_data[field] = form.getvalue(field)

    # print(post_data)
    try:
        fileitem = form['file']
        if fileitem.filename:
            fn = os.path.basename(fileitem.filename)
            open('./tmp/' + fn, 'wb').write(fileitem.file.read())
            data_files = {'file' : open('./tmp/' + fn, 'rb')}
        # print(data_files)
        r = requests.post(_POST_URL, data = post_data, files = data_files)
    except:
        r = requests.post(_POST_URL, data = post_data)
    
    res = r.text

    try:
        data_files = None
        os.remove('./tmp/' + fn)
    except:
        pass
    self._set_headers()
    self.wfile.write(res.encode('utf-8'))

这段代码对我有用,我不知道是否有更好的方法!