Detect content-type for designs uploaded to LFS
What does this MR do and why?
What
This MR sets content-type
property on files uploaded using the design management feature.
For now the content-type detection is under the same FF (design_management_allow_dangerous_images
) as the SVG file uploads, as currently SVG design uploads is the only use case for custom content-types. It impacts all uploaded design files, but changes are targeting setups with remote object storage on GCS.
Why
- Because of the
Content-Type: application/octet-stream
header, the uploaded (and valid) SVGs are rendered as broken images #34279 (comment 303545297) (which blocks enabling of the SVG uploads feature) - GCS only uses the content-type that is stored with the file and doesn't allow it to be overwritten at the download time
Context
- <code data-sourcepos="15:5-15:16">Content-Type</code> on GCS and Git LFS investigation thread
- Similar thing with
content-type
inDependencyProxy
Screenshots or screen recordings
Image HTTP requests
Before
curl -L -vvv http://gdk.test:3000/plan-sandbox/design-management-sample/-/design_management/designs/7/4001414bbe26178cc4d5604513d82139a8766180/raw_image
> GET /plan-sandbox/design-management-sample/-/design_management/designs/7/4001414bbe26178cc4d5604513d82139a8766180/raw_image HTTP/1.1
> Host: gdk.test:3000
...
< HTTP/1.1 302 Found
< Cache-Control: max-age=60, public
< Content-Type: text/html; charset=utf-8
> Host: storage.googleapis.com
...
< HTTP/2 200
< content-type: application/octet-stream
< content-disposition: attachment; filename="gitlab-logo-100.svg"; filename*=UTF-8''gitlab-logo-100.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 990 380"><defs ...
After
curl -L -vvv http://gdk.test:3000/plan-sandbox/design-management-sample/-/design_management/designs/8/c1ad3f10531ee29dde485e85c8ccea3f7ea399d0/raw_image
> GET /plan-sandbox/design-management-sample/-/design_management/designs/8/c1ad3f10531ee29dde485e85c8ccea3f7ea399d0/raw_image HTTP/1.1
> Host: gdk.test:3000
...
< HTTP/1.1 302 Found
< Cache-Control: max-age=60, public
< Content-Type: text/html; charset=utf-8
> Host: storage.googleapis.com
...
< HTTP/2 200
< content-type: image/svg+xml
< content-disposition: attachment; filename="gitlab-logo-200.svg"; filename*=UTF-8''gitlab-logo-200.svg
...
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 990 380">...%
GitLab designs UI
Before | After | |
---|---|---|
Preview | ||
Full | , |
As you can see in the last row, even after applying the new content-type, an SVG image is not visible as it can't identify the image dimension on frontend side (and raises a JS exception). But the image is there, after setting height
& width
CSS props manually it appears. That's a separate issue, I will work on it after.
How to set up and validate locally
- Enable the management of dangerous image formats (
Feature.enable(:design_management_allow_dangerous_images)
) - Configure remote object storage (Please ping me in case help is needed here, I can provide credentials/access to my private GCS, so you don't need to set up your own)
- Navigate to the issue page
- Upload a design (
.svg
format) - Checkout the image attributes on GCS (Type should be
image/svg+xml
now) - CURL image URL
curl -L -vvv
(content-type: image/svg+xml
header should be present) - Check "Designs" of issue from step 2, the uploaded images shouldn't appear as broken (more details in in GitLab designs UI section)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #34279