Skip to content

Instantly share code, notes, and snippets.

@wwarne
Last active February 23, 2020 10:12
Show Gist options
  • Save wwarne/c72c0ec5fbfe3adecfc0214133f1b965 to your computer and use it in GitHub Desktop.
Save wwarne/c72c0ec5fbfe3adecfc0214133f1b965 to your computer and use it in GitHub Desktop.
import base64
import hashlib
import hmac
import textwrap
# key and salt can be generated via echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
IMGPROXY_KEY='5360fd1a41998f8c568127a3053f26960d69e735530d5e5df9dcb3e4c4dff8cb55b23cf459f94baf7dbda42400d36006b080881187d80f1bb9f52731df6b8b5b'
IMGPROXY_SALT='d9a8a7419ca0dd96214a02c29c5f88b835fbb4a9dd788359cc753f9ac18233b52c1bea5cf87257d2e0730c8c8aa88dbd347616cc3cd3dbeb3241356c9392d9cd'
def get_signed_url(image_uri: str, processing_options: str, key: str, salt: str, output_format: str = '') -> str:
"""
Generate signed url for imgproxy. Uses advanced url format.
https://github.com/DarthSim/imgproxy/blob/master/docs/generating_the_url_advanced.md
:param image_uri: uri to source image
:param processing_options: options to apply to image
:param key: imgproxy key
:param salt: impgroxy salt
:param output_format: output image format. Can be omitted
- in this case, imgproxy will use source image format as resulting one.
:return: signed url for imgproxy
"""
key = bytes.fromhex(key)
salt = bytes.fromhex(salt)
encoded_source_url = base64.urlsafe_b64encode(image_uri.encode(encoding='utf-8')).rstrip(b'=').decode()
# The next line adds a slash every 16 symbols (for a better-looking url)
# but it increases time to calculate so if you're generating A LOT of urls - the next note is for you.
encoded_source_url = '/'.join(textwrap.wrap(encoded_source_url, 16))
"""
NOTE - I did a time comparison:
min(timeit.repeat(get_url_without_wrap, number=100000)) - version without .wrap
... 0.709092406000309
min(timeit.repeat(get_url_with_wrap, number=100000)) - version with .wrap
2.557214036000005 (x3.6 times slower)
So it's your choice between speed vs prettier urls. You need to generate A LOT of urls to see the difference.
I think this is not a big deal but worth a mention. I use this function with `wrap` and never had any problems.
"""
processing_url_b = f'/{processing_options}/{encoded_source_url}.{output_format}'.encode(encoding='utf-8')
digest = hmac.new(key, msg=salt + processing_url_b, digestmod=hashlib.sha256).digest()
signature = base64.urlsafe_b64encode(digest).rstrip(b'=')
final_url = b'/' + signature + processing_url_b
return final_url.decode(encoding='utf-8')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment