bustoutsolutions / siesta

The civilized way to write REST API clients for iOS / macOS
https://bustoutsolutions.github.io/siesta/
MIT License
2.19k stars 159 forks source link

RemoteImageView can not load image from aws cloudfront #45

Closed roma86 closed 8 years ago

roma86 commented 8 years ago

Thank you for great library, i love siesta so much.

Today i cutch interesting issue with RemoteImageView, i am not clear is it problem of response from my aws cloudfront settings, or the extension.

This is what is go on.

This works fine:

self.demoImage.imageURL = "http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg"

But this do not display image

self.demoImage.imageURL = "https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg"

I check same urls with AlamofireImage library and both images are displayed, but Siesta's image extension does not.

My current configuration is pod 'Siesta/Alamofire', '>=1.0-beta.6'

Debug log looks interesting

this is for image which is displayed

cachesPath: /var/mobile/Containers/Data/Application/AFCA65BD-5E5C-40B1-98FE-06A283C4DECE/Library/Caches
         [Siesta:Configuration] Computing configuration for Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[]
         [Siesta:Configuration] Applying config 0 [Siesta default response transformers] to Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[]
         [Siesta:Staleness] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[] is not up to date: no error | no data
         [Siesta:Network] GET http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg
         [Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[L] sending Requested to 0 observers
         [Siesta:Network] 200 ← GET http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg
         [Siesta:ResponseProcessing] ResponseContentTransformer<NSData, UIImage>(processor: (Function), skipWhenEntityMatchesOutputType: true, transformErrors: false) matches content type "image/jpeg"
         [Siesta:StateChanges] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[] received new data from Network : Entity(content: <UIImage: 0x155ba860>, {1800, 1200}, charset: nil, headers: ["date": "Sun, 03 Apr 2016 13:23:34 GMT", "accept-ranges": "bytes", "server": "Microsoft-IIS/5.0", "last-modified": "Tue, 07 Apr 2015 02:34:49 GMT", "content-type": "image/jpeg", "etag": "\"e693396bdb70d01:8b8\"", "content-l…
         [Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[D] sending NewData(Network) to 1 observer
         [Siesta:Observers] Siesta.Resource(http://www.plantanswers.com/Gallery/Bluebonnet-LadyBirdWildseeds/images/IMG_3475a.jpg)[D] sending NewData(Network) to (ClosureObserver in _C44BB9FA2CCB62875EDCC4C65C6D80F6)(closure: (Function))

This is for AWS CloudFront

cachesPath: /var/mobile/Containers/Data/Application/1B4EC435-C915-46FE-AB66-05D76FC79810/Library/Caches
         [Siesta:Configuration] Computing configuration for Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[]
         [Siesta:Configuration] Applying config 0 [Siesta default response transformers] to Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[]
         [Siesta:Staleness] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[] is not up to date: no error | no data
         [Siesta:Network] GET https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg
         [Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[L] sending Requested to 0 observers
         [Siesta:Network] 200 ← GET https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg
         [Siesta:StateChanges] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[] received new data from Network : Entity(content: <OS_dispatch_data: data[0x1564b580] = { composite, size = 231103, num_records = 11 record[0] = { from = 0, length = 16384, data_object = 0x15649a00 }, record[1] = { from = 0, length = 16384, data_object = 0x15557f80 }, record[2] = { from = 0, length = 16384, data_object = 0x156499b0 …
         [Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[D] sending NewData(Network) to 1 observer
         [Siesta:Observers] Siesta.Resource(https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg)[D] sending NewData(Network) to (ClosureObserver in _C44BB9FA2CCB62875EDCC4C65C6D80F6)(closure: (Function))

For me, noticeable difference in Entity(content: <UIImage and Entity(content: <OS_dispatch_data: data is interesting part. But my knowledge in cocoa is as deep.

Maybe this is incorrect settings in my CloudFront configuration, but in reason AlamofireImage extension get it right.

What do you think?

pcantrell commented 8 years ago

Glad you like Siesta!

At a very quick glance, I’m guessing the problem is that S3 isn’t sending a content type for the image:

$ curl -I https://d3lpseitn39rtz.cloudfront.net/uploads/images/admin/ZdqrV5RKwKugOKu3HpeH7w.jpg
HTTP/1.1 200 OK
Content-Length: 231103
Connection: keep-alive
Date: Sun, 03 Apr 2016 19:32:02 GMT
Last-Modified: Wed, 23 Mar 2016 09:36:37 GMT
ETag: "a7247e54aa9aadbcd94ef8dfcdee311e"
Accept-Ranges: bytes
Server: AmazonS3
Age: 72
X-Cache: Hit from cloudfront
Via: 1.1 f8375738cc4acf5f5ea814a0efd10a17.cloudfront.net (CloudFront)
X-Amz-Cf-Id: gEPwvVZf_Uhu0o16kHL-aTfqLX8gSryLfkerjS0HJ2uTh-vXCN8F-Q==

By default, Siesta does not parse the data as an image unless the server says it’s an image. You need to either:

Let me know if that isn’t the problem, and we can dig in a little deeper.

roma86 commented 8 years ago

Thank you for quick answer. I will try to find the right configuration for CloudFront if it is possible first. Also i got the point about Custom Service. Thank you one more time. Issue can be closed if it matter.

pcantrell commented 8 years ago

I’ll close it once we've tracked down the problem and verified that it's not a Siesta issue. So let me know!

roma86 commented 8 years ago

I come back with update. S3 storage does not determine content-type for uploaded images by self.

Offtopic notes: This is not related for Siesta, but nevertheless. Clients should mark uploaded objects with appropriate content-type or it can be changed in s3 buckets interface manually for each file

S3 buckets content-type

Example for ruby aws-sdk

object_name = "uploads/images/#{img_name}"
obj = s3.bucket('demo_site').object(object_name)
obj.upload_file(temp_file_path, :content_type => file_content_type)

Issue not in Siesta, but noob as me can catch this, in reason AlamofireImage or SDWebImage successfully present image in UIImageView without warnings.

Thank you for help and for awesome library.

pcantrell commented 8 years ago

Thanks for the follow up!

Next round of Siesta work, I may add a little logging on the content type matching that will help the next person to encounter a problem like this more easily track the problem down.