Skip to content

Instantly share code, notes, and snippets.

@kgn
Created January 28, 2022 05:57
Show Gist options
  • Save kgn/7c14feccbf40183c0f69f1f85fc1e59c to your computer and use it in GitHub Desktop.
Save kgn/7c14feccbf40183c0f69f1f85fc1e59c to your computer and use it in GitHub Desktop.
Simple function to upload files to S3 in Swift with no dependencies
import Foundation
import CryptoKit
extension String {
func hmac(key: String) -> String {
let secret = key.data(using: .utf8)!
let message = self.data(using: .utf8)!
var hmac = HMAC<Insecure.SHA1>(key: SymmetricKey(data: secret))
hmac.update(data: message)
return Data(hmac.finalize()).base64EncodedString()
}
}
struct S3 {
static func upload(_ data: Data, to bucket: String, name: String, contentType: String, publicRead: Bool = false, callback: @escaping (String?, Error?) -> Void) {
let s3_access_key = "<s3_access_key>"
let s3_secret_key = "<s3_secret_key>"
let filepath = "/\(bucket)/\(name)"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss Z"
let date = dateFormatter.string(from: Date())
// construct the signature hash, the order of the elements is important
var signature = ["PUT", "", contentType, date]
if publicRead { signature.append("x-amz-acl:public-read") }
signature.append(filepath)
let signature_hash = signature.joined(separator: "\n").hmac(key: s3_secret_key)
// Upload the file to S3
let url = "https://\(bucket).s3.amazonaws.com/\(name)"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "PUT"
request.httpBody = data
request.setValue("\(bucket).s3.amazonaws.com", forHTTPHeaderField: "Host")
if publicRead { request.setValue("public-read", forHTTPHeaderField: "x-amz-acl") }
request.setValue(date, forHTTPHeaderField: "Date")
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
request.setValue("AWS \(s3_access_key):\(signature_hash)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) { data, response, error in callback(url, error) }.resume()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment