Estoy tratando de cargar un archivo grande (como si no cabe en la memoria ) en S3 mediante una solicitud prefirmada. Finalmente conseguí que funcionara con curl.
curl -v -T video.mp4 "http://<myBucket>.s3.amazonaws.com/video.mp4?AWSAccessKeyId=<myAccessKey>&Expires=1492187347&Signature=vpcUnvGALlVXju31Qk2nXNmBTgc%3D"Estoy tratando de hacer eso ahora desde mi aplicación. Primero probé con AF (que preferiría no usar):
let videoPath = Bundle.main.path(forResource: "media", ofType: "mov")! let videoUrl = URL(fileURLWithPath: videoPath) let presignedUrl = "http://<myBucket>.s3.amazonaws.com/video.mp4?AWSAccessKeyId=<myAccessKey>&Expires=1492187347&Signature=vpcUnvGALlVXju31Qk2nXNmBTgc%3D" request = Alamofire.upload(videoUrl, to: presignedUrl, method: .put, headers: [:]) request.responseString(completionHandler: { response in print(response) }) request.resume()Lo que imprime una respuesta exitosa que en realidad es un error:
The request signature we calculated does not match the signature you provided. Check your key and signing method.He leído en algunos lugares que puede haber problemas con los encabezados y, de todos modos, preferiría no usar AF aquí.
¿Qué es en Swift un equivalente de curl -T filePath url ?
Al firmar la solicitud, pase el tipo de contenido. En nodo:
var AWS = require('aws-sdk'); AWS.config.update({ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey, region: 'us-east-1', }); var s3 = new AWS.S3(); var params = { Bucket: bucketName, Key: 'path/my-video.mp4', Expires: 1800000, ContentType: 'video/mp4', }; var signedUrl = s3.getSignedUrl('putObject', params) // returns something like: // https://<- my bucket ->.s3.amazonaws.com/path/my-video.mp4?AWSAccessKeyId=<- my access key ->&Content-Type=video%2Fmp4&Expires=1492203291&Signature=HeRBUObYQiQ6FIH%2Fg%2FOI0qv57VY%3Dy ahora en rápido:
let request = NSMutableURLRequest(url: presignedUrl) request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData request.httpMethod = "PUT" request.setValue("video/mp4", forHTTPHeaderField: "Content-Type") request.setValue("<- my bucket ->.s3.amazonaws.com", forHTTPHeaderField: "host") let uploadTask = session.uploadTask(with: request as URLRequest, fromFile: videoUrl) { data, response, error in ... } uploadTask.resume()