hanxi / http-file-server

use python, upload and download file.
MIT License
32 stars 18 forks source link

大文件上传失败 | Large file upload failure #1

Open BunnySakura opened 1 week ago

BunnySakura commented 1 week ago

当文件>4GB时就会失败,因为超出了上限。 It fails when the file is >4GB because the limit is exceeded.

    line 95, in do_POST
    filecontent = self.rfile.read(filesize)
OverflowError: signed integer is greater than maximum

修改do_POST

    def do_POST(self):
        query = urllib.splitquery(self.path)
        path = query[0]
        queryParams = {}

        if "?" in self.path:
            if query[1]:
                queryParams = transDicts(query[1])

        resultdict = {"result": 0, "msg": "OK"}
        if path == "/upload":
            if "name" in queryParams:
                filesize = int(self.headers["content-length"])
                fn = queryParams["name"]
                resultdict["filename"] = fn
                fn = "%s%s" % (g_filepath, fn)
                dirname = os.path.dirname(fn)
                if not os.path.exists(dirname):
                    os.makedirs(dirname)
                if os.path.isdir(fn):
                    resultdict["result"] = 1
                    resultdict["msg"] = "File name is directory."
                else:
                    print "Recv file %s, length: %d" % (queryParams["name"], filesize)
                    with open(fn, "wb") as f:
                        transmit_size = 0
                        while transmit_size != filesize:
                            block_size = min(1024 * 1024, filesize - transmit_size)
                            filecontent = self.rfile.read(block_size)  # Read in chunks of 1MB
                            if not filecontent:
                                print "Receive none file data"
                                break
                            f.write(filecontent)
                            transmit_size += block_size
                            print "Recv transmit %d/%d byte" %(transmit_size, filesize)
            else:
                resultdict["result"] = 2
                resultdict["msg"] = "Need file name."
        else:
            resultdict["result"] = 3
            resultdict["msg"] = "No this API."

        content = json.dumps(resultdict)
        self.send_response(200)
        self.send_header("content-type", "application/json")
        self.end_headers()
        self.wfile.write(content)

并可增加一个上传网页: And you can add an upload page:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Upload with Progress</title>
<script>
function uploadFile() {
    var fileInput = document.getElementById('fileInput');
    var file = fileInput.files[0]; // 获取选中的文件
    var fileName = file.name; // 获取文件名

    // 创建FormData对象
    var formData = new FormData();
    formData.append('file', file); // 添加文件到表单数据中

    // 创建XMLHttpRequest对象
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload?name=' + encodeURIComponent(fileName), true);

    // 监听上传进度事件
    xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
            var percentComplete = (e.loaded / e.total) * 100;
            document.getElementById('progress').value = percentComplete;
            document.getElementById('status').innerText = 'Upload Progress: ' + percentComplete.toFixed(2) + '%';
        }
    };

    // 请求完成的处理
    xhr.onload = function() {
        if (xhr.status == 200) {
            document.getElementById('status').innerText = 'Upload Complete!';
        } else {
            document.getElementById('status').innerText = 'Upload Failed!';
        }
    };

    // 发送请求
    xhr.send(formData);
}
</script>
</head>
<body>

<h2>Upload File with Progress</h2>
<input type="file" id="fileInput" name="fileInput">
<button onclick="uploadFile()">Upload</button>
<br>
<progress id="progress" value="0" max="100" style="width: 100%;"></progress>
<p id="status">Ready to Upload...</p>

</body>
</html>

最后感谢你的代码对我提供的帮助,在一个只有内网的老服务器上上传文件真麻烦! Finally, thanks for the help your code provided me, it's a pain to upload files on an old intranet-only server!

BunnySakura commented 1 week ago

发现了一个问题,上传时Content-Length和实际大小不同,导致传过去的文件不能用。

hanxi commented 1 week ago

修复了欢迎提pr哈,这个项目只是写来临时用的,没有使用标准的文件上传接口。