Скачать и загрузить zip-файл

Я пытаюсь имитировать такой завиток:

      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)
                        }
                    }
                }
            }

Я получаю следующую ошибку:

Спасибо за помощь

4 ответа

Решение

Следующий код работает:

              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)
                }
            }

Это не помогло:

Как упоминалось в комментариях, которые вы указали, чтобы разрешить произвольные нагрузки. См. Раздел Безопасность транспорта заблокировала открытый текст HTTP. Больше подробностей

Я установил разрешение, как указано в ссылке:

Разрешение

Но получаю следующую ошибку:

Ошибка

Я также внес некоторые изменения в свой код:

                      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 и добавить fileData в запрос, это должен быть запрос 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)

Как упоминалось в комментариях, которые вы указали, чтобы разрешить произвольные нагрузки. См. Раздел Безопасность транспорта заблокировала открытый текст HTTP. Больше подробностей

Другие вопросы по тегам