Python 实现http server接收mutipart/form-data文件 方法2

Python 实现http server接收mutipart/form-data文件 方法2

    • [1 Server端代码](#1 Server端代码)
    • [2 测试](#2 测试)

1 Server端代码

以下代码亲测有效,仅适应于接收客户端上传的图片,其他文件未曾测试,作者主要应用于平时的自测工具。
说明1: 如有特殊需求,请自行更改,有意见,评论区留言。
说明2: 建议使用这个方法用于生产、成熟软件开发。Python 实现http server接收mutipart/form-data文件 方法1

python 复制代码
from dataclasses import replace
from http.server import HTTPServer, BaseHTTPRequestHandler
import json,os,re,chardet,posixpath,codecs
from urllib.parse import unquote

class Resquest(BaseHTTPRequestHandler):
    def do_POST(self):
        print("headers:", self.headers)
        print("command:",self.command)
        print("path:",self.path)
        
        bdy = self.headers.get_boundary()
        if not  bdy is None:
            print(" = in headers")
            boundary = self.headers['content-type'].split("=")[1]
            print("boundary:",boundary)
            if "Boundary" in boundary :
                print("parser image")
                self.deal_post_data()
            else :
                print("can't handle boundary")
        else :
             print(" = not in headers")
             req_datas = self.rfile.read(int(self.headers['content-length'])) 
             print("--------------------接受client发送的数据----------------")
             res1 = req_datas.decode('utf-8')
             res = json.loads(req_datas)
             print(res)
             #f = open('1.txt', 'w')
             #f.write(req_datas.decode())
             #f.close()
             #print(req_datas)
             print("--------------------接受client发送的数据完毕------------------")
             #data1 = {'bbb':'222'}
             #data = json.dumps(data1)
             #self.send_response(200)
             #self.send_header('Content-type', 'application/json')
             #self.end_headers()
             #self.wfile.write(data)

    def deal_post_data(self):
        boundary = self.headers["Content-Type"].split("=")[1].encode('ascii')
        print("boundary===", boundary)
        remain_bytes = int(self.headers['content-length'])
        print("remain_bytes===", remain_bytes)

        res = []
        line = self.rfile.readline()
        print("line=",line)
        bdarys = boundary.decode()
        bdarys = bdarys.replace(" ","")
        boundary = bdarys.encode()
        while boundary in line and str(line, encoding = "utf-8")[-4:] != "--\r\n":
            #line = self.rfile.readline()
            remain_bytes -= len(line)
            if boundary not in line:
                return False, "Content NOT begin with boundary"
            line = self.rfile.readline()
            remain_bytes -= len(line)
            print("line!!!==",str(line))    
            strLine = str(line)      
            fn = strLine.split(';') [2].replace(' filename=','')
            fn= fn[:-5]
            print("fn==",fn)
            if not fn:
                print("False, Can't find out file name...")
                return False, "Can't find out file name..."
            path = translate_path(self.path)
            print("path==",path)

            fname = fn
            #fname = fname.replace("\\", "\\\\")
            fname = self.str_to_chinese(fname)
            print("fname==",fname)
            
            fn = os.path.join(path, fname)
            print("SavefilePath==",fn)
            dirname = os.path.dirname(fn)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            line = self.rfile.readline()
            remain_bytes -= len(line)
            line = self.rfile.readline()
            # b'\r\n'
            remain_bytes -= len(line)
            try:
                out = open(fn, 'wb')
            except IOError:
                return False, "Can't create file to write, do you have permission to write?"

            pre_line = self.rfile.readline()
            print("pre_line", pre_line)
            remain_bytes -= len(pre_line)
            print("remain_bytes", remain_bytes)
            Flag = True
            while remain_bytes > 0:
                line = self.rfile.readline()
                #print("while line", line)
                
                if boundary in line:
                    remain_bytes -= len(line)
                    pre_line = pre_line[0:-1]
                    if pre_line.endswith(b'\r'):
                        pre_line = pre_line[0:-1]
                    out.write(pre_line)
                    out.close()
                    #return True, "File '%s' upload success!" % fn
                    res.append("File '%s' upload success!" % fn)
                    Flag = False
                    break
                else:
                    out.write(pre_line)
                    pre_line = line
            if pre_line is not None and Flag == True:
                out.write(pre_line)
                out.close()
                res.append("File '%s' upload success!" % fn)
            #return False, "Unexpect Ends of data."
        return True, res

    def str_to_chinese(self,var):
        not_end = True
        while not_end:
            start1 = var.find("\\x")
            # print start1
            if start1 > -1:
                str1 = var[start1 + 2:start1 + 4]
                print(str1)
                start2 = var[start1 + 4:].find("\\x") + start1 + 4
                if start2 > -1:
                    str2 = var[start2 + 2:start2 + 4]

                    start3 = var[start2 + 4:].find("\\x") + start2 + 4
                    if start3 > -1:
                        str3 = var[start3 + 2:start3 + 4]
            else:
                not_end = False
            if start1 > -1 and start2 > -1 and start3 > -1:
                str_all = str1 + str2 + str3
                # print str_all
                str_all = codecs.decode(str_all, "hex").decode('utf-8')

                str_re = var[start1:start3 + 4]
                # print str_all, "   " ,str_re
                var = var.replace(str_re, str_all)
        # print var.decode('utf-8')
        return var

def translate_path(path):
    """Translate a /-separated PATH to the local filename syntax.
    Components that mean special things to the local file system
     (e.g. drive or directory names) are ignored.  (XXX They should
    probably be diagnosed.)
    """
    # abandon query parameters
    path = path.split('?', 1)[0]
    path = path.split('#', 1)[0]
    path = posixpath.normpath(unquote(path))
    words = path.split('/')
    words = filter(None, words)
    path = os.getcwd()
    for word in words:
        drive, word = os.path.splitdrive(word)
        head, word = os.path.split(word)
        if word in (os.curdir, os.pardir):
            continue
        path = os.path.join(path, word)
    return path
        
if __name__ == '__main__':
    host = ('192.168.1.16', 18098)
    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: %s:%s" % host)
    server.serve_forever()

2 测试

参见链接文章中的客户端测试方法进行测试。

如有其他需求或问题,烦请评论区留言。
Python 实现http server接收mutipart/form-data文件 方法1

相关推荐
神仙别闹1 小时前
基于Python实现英词语自动对齐系统
开发语言·python
akinggw1 小时前
libagentcore - 一个基于c++的AI多agent系统升级到2.0版本
开发语言·jvm·c++
老歌老听老掉牙2 小时前
圆柱端面四平面交线及其在yoz面投影的几何解析与 Python 实现
开发语言·python·平面
我要见SA姐12 小时前
Chrome 扩展安全攻防实录:从权限滥用到供应链投毒
运维·人工智能·python·机器学习·自动化
2601_962885722 小时前
给 backtrader 接 A 股数据:用 AlphaFeed 喂PandasData
python
旖旎夜光2 小时前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
YYYing.3 小时前
【Agent系列 (十一) 】上下文工程
人工智能·python·ai·agent·上下文工程
俩个逗号。。3 小时前
Kotlin flow 详解
android·开发语言·kotlin
计算机毕业编程指导师3 小时前
基于深度学习的光伏组件红外图像缺陷识别系统设计与实现
人工智能·python·深度学习·目标检测·毕业设计·课程设计·光伏
前端精髓3 小时前
langchain 短期记忆(状态)动态运行时上下文
python·langchain