Skip to content

Instantly share code, notes, and snippets.

@coudron
Last active May 20, 2016 20:58
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coudron/5258947 to your computer and use it in GitHub Desktop.
Save coudron/5258947 to your computer and use it in GitHub Desktop.
Python and Objective-C code that enables an iOS app to upload images directly to an S3 bucket using a secure authorization header generated by a python server Code is a Fork from Stackoverflow answer: http://stackoverflow.com/questions/4481311/architectural-and-design-question-about-uploading-photos-from-iphone-app-and-s3 Let me know what you th…
- (void)uploadImage:(UIImage *)image
{
//Set up the upload request from our server
NSURL *url = [NSURL URLWithString:@"http://<your-server-url-here>/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
// Pull out any required information out of the response
NSString *serverDate = [JSON valueForKeyPath:@"date_string"];
NSString *serverHmacDigest = [JSON valueForKeyPath:@"auth_string"];
NSString *S3AccessKey = [JSON valueForKeyPath:@"s3_key"];
NSString *S3BucketName = [JSON valueForKeyPath:@"bucket_name"];
NSString *content_type = [JSON valueForKeyPath:@"content_type"];
NSString *full_pathname = [JSON valueForKeyPath:@"full_pathname"];
NSString *filename = [JSON valueForKeyPath:@"filename"];
// Create the headers.
NSMutableDictionary *headers = [[NSMutableDictionary alloc] init];
[headers setObject:content_type forKey:@"Content-Type"];
NSString *host = [NSString stringWithFormat:@"%@.s3.amazonaws.com", S3BucketName];
[headers setObject:host forKey:@"Host"];
[headers setObject:serverDate forKey:@"Date"];
NSString *authorization = [NSString stringWithFormat:@"AWS %@:%@", S3AccessKey, serverHmacDigest];
[headers setObject:authorization forKey:@"Authorization"];
// Create the new Amazon S3 request.
NSMutableURLRequest *postrequest = [[NSMutableURLRequest alloc] init];
[postrequest setAllHTTPHeaderFields:headers];
NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
[postrequest setHTTPBody:imageData];
[postrequest setHTTPMethod:@"PUT"];
NSString *postUrl = [NSString stringWithFormat:@"http://%@.s3.amazonaws.com/images/%@", S3BucketName, filename];
[postrequest setURL:[NSURL URLWithString:postUrl]];
// Set up the POST request to Amazon S3
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:postrequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
//At this point, we have successfully uploaded the photo to Amazon.
// TODO: Do shit after upload
NSLog(@"Image uploaded: %@", postUrl);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser){
NSLog(@"Error uploading image to Amazon S3: %@", error);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(@"Error requesting authorization headers from app server: %@", error);
}];
[operation start];
}
def request_upload_location(request):
# DO NOT PASS BACK SECRET!
_S3_SECRET = "<secret here>"
_S3_ACCESS_KEY = "<key here>"
_S3_BUCKET_NAME = "<bucket name here>"
filename = str(uuid.uuid4()) +".jpeg" #TODO: Support for other non-jpeg file types
content_type = "image/jpeg"
now = datetime.utcnow()
date_string = now.strftime("%a, %d %b %Y %H:%M:%S +0000")
full_pathname = '/%s/images/%s' % (_S3_BUCKET_NAME, filename)
string_to_sign = "PUT\n\n%s\n%s\n%s" % (content_type, date_string, full_pathname)
h = hmac.new(_S3_SECRET, string_to_sign, sha)
auth_string = base64.encodestring(h.digest()).strip()
output = { "bucket_name": _S3_BUCKET_NAME,
"filename": filename,
"full_pathname" : full_pathname,
"date_string" : date_string,
"auth_string" : auth_string,
"content_type" : content_type,
"s3_key" : _S3_ACCESS_KEY,
}
return HttpResponse(json.dumps(output), content_type="application/json")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment