Use cache-busting URLs for proxied files (#294)
Migrates (in a backwards-compatible way) from `/proxy/identity_image/271/` to `/proxy/identity_image/271/f5d8e72f2b/`. dently).
This commit is contained in:
parent
161b1a8af1
commit
296780d5cc
|
@ -169,7 +169,9 @@ class Emoji(StatorModel):
|
||||||
if self.file:
|
if self.file:
|
||||||
return AutoAbsoluteUrl(self.file.url)
|
return AutoAbsoluteUrl(self.file.url)
|
||||||
elif self.remote_url:
|
elif self.remote_url:
|
||||||
return AutoAbsoluteUrl(f"/proxy/emoji/{self.pk}/")
|
return AutoAbsoluteUrl(
|
||||||
|
f"/proxy/emoji/{self.pk}/", hash_tail_input=self.remote_url
|
||||||
|
)
|
||||||
return StaticAbsoluteUrl("img/blank-emoji-128.png")
|
return StaticAbsoluteUrl("img/blank-emoji-128.png")
|
||||||
|
|
||||||
def as_html(self):
|
def as_html(self):
|
||||||
|
|
|
@ -81,13 +81,17 @@ class PostAttachment(StatorModel):
|
||||||
elif self.file:
|
elif self.file:
|
||||||
return RelativeAbsoluteUrl(self.file.url)
|
return RelativeAbsoluteUrl(self.file.url)
|
||||||
else:
|
else:
|
||||||
return AutoAbsoluteUrl(f"/proxy/post_attachment/{self.pk}/")
|
return AutoAbsoluteUrl(
|
||||||
|
f"/proxy/post_attachment/{self.pk}/", hash_tail_input=self.remote_url
|
||||||
|
)
|
||||||
|
|
||||||
def full_url(self):
|
def full_url(self):
|
||||||
if self.file:
|
if self.file:
|
||||||
return RelativeAbsoluteUrl(self.file.url)
|
return RelativeAbsoluteUrl(self.file.url)
|
||||||
else:
|
else:
|
||||||
return AutoAbsoluteUrl(f"/proxy/post_attachment/{self.pk}/")
|
return AutoAbsoluteUrl(
|
||||||
|
f"/proxy/post_attachment/{self.pk}/", hash_tail_input=self.remote_url
|
||||||
|
)
|
||||||
|
|
||||||
### ActivityPub ###
|
### ActivityPub ###
|
||||||
|
|
||||||
|
|
14
core/uris.py
14
core/uris.py
|
@ -1,3 +1,4 @@
|
||||||
|
import hashlib
|
||||||
import sys
|
import sys
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
|
@ -27,8 +28,19 @@ class AutoAbsoluteUrl(RelativeAbsoluteUrl):
|
||||||
or a passed identity's URI domain.
|
or a passed identity's URI domain.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, relative: str, identity=None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
relative: str,
|
||||||
|
identity=None,
|
||||||
|
hash_tail_input: str | None = None,
|
||||||
|
hash_tail_length: int = 10,
|
||||||
|
):
|
||||||
self.relative = relative
|
self.relative = relative
|
||||||
|
if hash_tail_input:
|
||||||
|
# When provided, attach a hash of the input (typically the proxied URL)
|
||||||
|
# SHA1 chosen as it generally has the best performance in modern python, and security is not a concern
|
||||||
|
# Hash truncation is generally fine, as in the typical use case the hash is scoped to the identity PK
|
||||||
|
self.relative += f"{hashlib.sha1(hash_tail_input.encode('ascii')).hexdigest()[:hash_tail_length]}/"
|
||||||
if identity:
|
if identity:
|
||||||
absolute_prefix = f"https://{identity.domain.uri_domain}/"
|
absolute_prefix = f"https://{identity.domain.uri_domain}/"
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -104,8 +104,6 @@ http {
|
||||||
proxy_cache_valid 301 307 12h;
|
proxy_cache_valid 301 307 12h;
|
||||||
proxy_cache_valid 500 502 503 504 0s;
|
proxy_cache_valid 500 502 503 504 0s;
|
||||||
proxy_cache_valid any 72h;
|
proxy_cache_valid any 72h;
|
||||||
proxy_hide_header Cache-Control;
|
|
||||||
add_header Cache-Control "public, max-age=3600";
|
|
||||||
add_header X-Cache $upstream_cache_status;
|
add_header X-Cache $upstream_cache_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class BaseProxyView(View):
|
||||||
headers={
|
headers={
|
||||||
"X-Accel-Redirect": "/__takahe_accel__/",
|
"X-Accel-Redirect": "/__takahe_accel__/",
|
||||||
"X-Takahe-RealUri": remote_url,
|
"X-Takahe-RealUri": remote_url,
|
||||||
"Cache-Control": "public, max-age=3600",
|
"Cache-Control": "public",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -52,7 +52,9 @@ class BaseProxyView(View):
|
||||||
"Content-Type": remote_response.headers.get(
|
"Content-Type": remote_response.headers.get(
|
||||||
"Content-Type", "application/octet-stream"
|
"Content-Type", "application/octet-stream"
|
||||||
),
|
),
|
||||||
"Cache-Control": "public, max-age=3600",
|
"Cache-Control": remote_response.headers.get(
|
||||||
|
"Cache-Control", "public, max-age=3600"
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -211,23 +211,23 @@ urlpatterns = [
|
||||||
path("debug/500/", debug.ServerError.as_view()),
|
path("debug/500/", debug.ServerError.as_view()),
|
||||||
path("debug/oauth_authorize/", debug.OauthAuthorize.as_view()),
|
path("debug/oauth_authorize/", debug.OauthAuthorize.as_view()),
|
||||||
# Media/image proxy
|
# Media/image proxy
|
||||||
path(
|
re_path(
|
||||||
"proxy/identity_icon/<identity_id>/",
|
"^proxy/identity_icon/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
||||||
mediaproxy.IdentityIconCacheView.as_view(),
|
mediaproxy.IdentityIconCacheView.as_view(),
|
||||||
name="proxy_identity_icon",
|
name="proxy_identity_icon",
|
||||||
),
|
),
|
||||||
path(
|
re_path(
|
||||||
"proxy/identity_image/<identity_id>/",
|
"^proxy/identity_image/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
||||||
mediaproxy.IdentityImageCacheView.as_view(),
|
mediaproxy.IdentityImageCacheView.as_view(),
|
||||||
name="proxy_identity_image",
|
name="proxy_identity_image",
|
||||||
),
|
),
|
||||||
path(
|
re_path(
|
||||||
"proxy/post_attachment/<attachment_id>/",
|
"^proxy/post_attachment/(?P<attachment_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
||||||
mediaproxy.PostAttachmentCacheView.as_view(),
|
mediaproxy.PostAttachmentCacheView.as_view(),
|
||||||
name="proxy_post_attachment",
|
name="proxy_post_attachment",
|
||||||
),
|
),
|
||||||
path(
|
re_path(
|
||||||
"proxy/emoji/<emoji_id>/",
|
"^proxy/emoji/(?P<emoji_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
||||||
mediaproxy.EmojiCacheView.as_view(),
|
mediaproxy.EmojiCacheView.as_view(),
|
||||||
name="proxy_emoji",
|
name="proxy_emoji",
|
||||||
),
|
),
|
||||||
|
|
|
@ -268,7 +268,9 @@ class Identity(StatorModel):
|
||||||
if self.icon:
|
if self.icon:
|
||||||
return RelativeAbsoluteUrl(self.icon.url)
|
return RelativeAbsoluteUrl(self.icon.url)
|
||||||
elif self.icon_uri:
|
elif self.icon_uri:
|
||||||
return AutoAbsoluteUrl(f"/proxy/identity_icon/{self.pk}/")
|
return AutoAbsoluteUrl(
|
||||||
|
f"/proxy/identity_icon/{self.pk}/", hash_tail_input=self.icon_uri
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return StaticAbsoluteUrl("img/unknown-icon-128.png")
|
return StaticAbsoluteUrl("img/unknown-icon-128.png")
|
||||||
|
|
||||||
|
@ -279,7 +281,9 @@ class Identity(StatorModel):
|
||||||
if self.image:
|
if self.image:
|
||||||
return AutoAbsoluteUrl(self.image.url)
|
return AutoAbsoluteUrl(self.image.url)
|
||||||
elif self.image_uri:
|
elif self.image_uri:
|
||||||
return AutoAbsoluteUrl(f"/proxy/identity_image/{self.pk}/")
|
return AutoAbsoluteUrl(
|
||||||
|
f"/proxy/identity_image/{self.pk}/", hash_tail_input=self.image_uri
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
Loading…
Reference in New Issue