下载和上传 zip 文件

Download & Upload zip file

我正在尝试模仿以下卷曲:

curl -v -F file=@/Users/myuser/Downloads/shelly-homekit-Shelly25.zip http://10.0.1.7/update

为了使用 curl 命令,我下载了 zip 文件并将其保存到我的计算机上。

我的应用程序应下载 zip 文件,将其存储到设备并上传到服务器。

我尝试将其作为文件和数据上传,但都没有成功:

            let destination: DownloadRequest.Destination = { _, _ in
                let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
                let fileURL = documentsURL.appendingPathComponent("shelly-homekit-Shelly1PM.zip")

                return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
            }

            AF.download("https://rojer.me/files/shelly/shelly-homekit-Shelly1PM.zip", to: destination).response { response in
                debugPrint(response)

                if response.error == nil, let zipPath = response.fileURL?.path {
                    
                    let url = URL(string: zipPath)!

                    
                    let headers: HTTPHeaders = [
                        .contentType("multipart/form-data")
                    ]
                    
                    if let data = try? Data(contentsOf: url) {
                        AF.upload(data, to: "http://"+dev.ipAddress+"/update",headers: headers).responseDecodable(of: HTTPBinResponse.self) { response in
                            debugPrint(response)
                        }
                    }
                }
            }

我收到以下错误:

感谢您的帮助

如评论中所述,您需要允许任意加载。参见 。更多详情

这没有帮助:

Like mentioned in the comments you meed to allow arbitrary loads. See Transport security has blocked a cleartext HTTP. For more details

我设置了link中提到的权限:

Permission

但出现以下错误:

Error

我也对我的代码做了一些修改:

                let destination: DownloadRequest.Destination = { _, _ in
                let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
                let fileURL = documentsURL.appendingPathComponent("shelly-homekit-Shelly1PM.zip")

                return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
            }

            AF.download("https://rojer.me/files/shelly/shelly-homekit-Shelly1PM.zip", to: destination).response { response in
                //debugPrint(response)

                if response.error == nil {
                    AF.upload(response.fileURL!, to: "http://"+dev.ipAddress+"/update").responseDecodable(of: HTTPBinResponse.self) { response_up in
                        debugPrint(response_up)
                    }
                }
            }

我用Wireshark嗅探了curl命令发送的请求:

POST /update HTTP/1.1
Host: 10.0.1.10
User-Agent: curl/7.64.1
Accept: */*
Content-Length: 988427
Content-Type: multipart/form-data; boundary=------------------------c67b500e63a02f3d
Expect: 100-continue

    

--------------------------c67b500e63a02f3d
Content-Disposition: form-data; name="file"; filename="shelly-homekit-Shelly25.zip"
Content-Type: application/octet-stream

不确定如何将其转换为 AF 代码并将文件数据添加到请求中,它应该是一个 POST 请求,我相信以下代码创建了正确的 http 主体:

                let boundary = "Boundary-\(UUID().uuidString)"

                let headers: HTTPHeaders = [
                    .contentType("multipart/form-data; boundary=\(boundary)")
                ]

                let parameters = [
                  [
                    "key": "file",
                    "value": "shelly-homekit-Shelly25.zip",
                    "type": "application/octet-stream",
                    "src":response.fileURL!.path
                  ]] as [[String : Any]]

                var body = ""
                for param in parameters {
                    let paramName = param["key"]!
                    body += "--\(boundary)\r\n"
                    body += "Content-Disposition:form-data; name=\"\(paramName)\""
                    body += "\r\nContent-Type: \(param["contentType"] as! String)"
                    //let paramSrc = param["src"] as! String
                    let paramValue = param["value"] as! String
                    let paramType = param["type"] as! String
                    //let fileData = try? NSData(contentsOfFile:paramSrc, options:[]) as Data
                    body += "; filename=\"\(paramValue)\"\r\n" + "Content-Type: " + paramType
                }
                let postData = body.data(using: .utf8)

以下代码有效:

        let data = try? NSData(contentsOf: URL(string:str)!) as Data
    
        AF.upload(multipartFormData: { multipartFormData in
            multipartFormData.append(data!,withName: "file",fileName: file_name ,mimeType: "application/octet-stream")
        }, to: "http://"+dev.ipAddress+"/update")
            .response { response in
                if response.response?.statusCode != 200 {
                    devicesUpdateError.append(dev.name)
                }
            }