3

I am relatively new to amazon web services. There is problem that came up while I was coding my new web app. I am currently storing profile pictures in an s3 bucket.

I don’t want these profile pictures to be seen by the public, only authorized members. So I have a php file like this:

This php file executes getObject and sends out a header to show the picture but only if the user is allowed to see the picture. I query the database and also check session to make sure that the currently logged in user has access to the picture. All is working fine, but it takes around 500 milliseconds to the get request to execute, even on small files (40kb). On bigger files it gets even longer as well as if I embed the php file in an img tag multiple times with different query string values.

I need to mention that I’m testing this in a localhost environment with apache webserver.

Could be the the problem is that getObject is optimized to be run from an ec2 instance and that if I would test this on an ec2 the response time is much better? My s3 is based in London, and I’m testing it in Hungary with a good internet connection so I’m not sure if this response time is what I should get here.

I read that other people had similar issues, but from my understanding the time it takes from s3 to transfer the files to an ec2 should be minimal as they are all in the cloud and the latency between these services and all the other aws services should be minimal (At least if they are in the same region).

Please don’t tell me in comments that I should just make my bucket public and embed the direct link to the file as it is not a viable option for obvious reasons. I also don’t want to generate pre-signed urls for various reasons.

I also tested this without querying the database and essentially the only logic in my code is to get the object and show it to the user. Even with this I get 400+ milliseconds response time. I also tried using doesObjectExist() and I still need to wait around 300-400 milliseconds for that to give me a response.

Multiple get request to the same php file as image source

UPDATE

I tested it on my ec2 instance and I've got much better response time. I tested it with multiple files and all is fine. It seems like that if you use getObject on localhost, the time it takes to connect to s3 and fetch the data multiplies. Thank you for the answers!

Adam8899
  • 231
  • 1
  • 2
  • 7
  • Have you tried enabling S3 Transfer Acceleration? https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html – Mark B Jul 19 '19 at 12:36
  • When you say "500 milliseconds," is that time to retrieve the S3 object _inside_ your PHP script, or the time seen from the browser? – kdgregory Jul 19 '19 at 13:39
  • 1
    At the risk of poking the bear, you should reconsider the use of s3 pre-signed URLs. Time limited, and delivered over a secure channel. – jarmod Jul 19 '19 at 14:58
  • You should check what the average round trip time is to ping an AWS London server/service from your location. Even if you have a good internet connection, it could be that there is a lot of network hops or indirect routing involved. If the RTT is comparably slow even for a ping, then your location is part of the problem. – Matthew Pope Jul 20 '19 at 04:28
  • @MarkB Not yet, but I'll take a look, thanks. – Adam8899 Jul 20 '19 at 06:46
  • @kdgregory It is the time I see in the browser. The download time is very fast from the server to my browser as apache running on my pc. But the Waiting (TTFB) time is the one that takes long. Chrome says pending for that period of time, so I'm guessing it is waiting for the server to give a response back. In conclusion, i think it is the time to get the object from the bucket to the server is the problem here. – Adam8899 Jul 20 '19 at 06:55
  • @jarmod The truth is, I would do it but consider this. That url is still shareable for that period of time till it gets expired, at least from what I've read about it so far. My web app will have a chat system, and If I share a file in the chat, I only want the user with the proper rights to be able download it. If that user for some weird reason shares the link with someone else outside the app, and that person who got the link clicks on it, I want to throw an access denied error. For reference, it would have some similarities with Slack (the company chat SaaS). – Adam8899 Jul 20 '19 at 07:05
  • @MatthewPope I should have mentioned that I already did this test both from localhost and from my ec2 instance. I get around 42 milliseconds RTT from localhost, from ec2 it is less than a millisecond. – Adam8899 Jul 20 '19 at 07:12
  • 1
    The original user has access to the file itself, of course, so can download it directly and then share the file in many other ways. At least the pre-signed URL expires. You can also log all access via the pre-signed URL for later analysis which you can’t do with the ‘download and share’ abuse. – jarmod Jul 20 '19 at 11:00
  • 1
    @jarmod That is actually a good point. I will dig in deeper on the topic. Thank you! – Adam8899 Jul 20 '19 at 12:04

0 Answers0