S3 CDN URL wird bei Nicht-Bild-Uploads nicht verwendet

Maybe related to S3 CDN URL ignored when uploading into posts.

At first I thought I had missed some configuration, but it’s reproducible here on meta:
https://meta.discourse.org/uploads/short-url/dw1U4hctATusBlHsUmWQXeme66j.csv (uploaded here) is a 302 redirect to
//assets-meta-cdck-prod-meta.s3.dualstack.us-west-1.amazonaws.com/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv

Shouldn’t it redirect to https://d11a6trkgmumsb.cloudfront.net/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv instead?

5 „Gefällt mir“

Hmmm there may possibly be an issue here @martin can you investigate? We should probably redirect to the CDN if possible.

5 „Gefällt mir“

This is a little bit tricky, I had a look at this just now. Basically we are always downloading from S3 with a presigned URL if we are doing a “force download”, which is what happens when we are clicking on the attachment link or clicking on the Download button on an image. This is so the appropriate content-disposition headers can be added:

attachment; filename="#{upload.original_filename}"; filename*=UTF-8''#{upload.original_filename}

I do not think it is possible to make the CDN URL behave in this way? The CDN URL for images is only used when displaying them inline, not when downloading them. Also in the case of secure images and attachments which have a private ACL the presigned URL must always be used.

2 „Gefällt mir“

@martin bezüglich Anhanglinks kann ich nicht sehen, wie sie immer auf „Download erzwingen“ gesetzt werden können. Derzeit wird beim Hochladen einer Nicht-Bilddatei die gerenderte URL zu einer Kurz-URL ohne den ?dl=1-Parameter, die auf den Wert des url-Attributs des entsprechenden Uploads aufgelöst wird (was keine presigned_url ist und in unserem Fall auch fehlschlägt, da die URL nicht die S3 cdn_url ist, sondern eine konstruierte, die möglicherweise nur für bestimmte S3-Anbieter funktioniert).

Gibt es eine Möglichkeit, Anhänge immer zum Download zu zwingen, oder ist das aktuelle Verhalten tatsächlich ein Fehler?

1 „Gefällt mir“

Können Sie das hier näher erläutern? Verwenden Sie Amazon S3 oder einen anderen Anbieter? Wenn ja, welchen?

1 „Gefällt mir“

Ja, ich scheine einen nicht unterstützten S3-Provider (OVH Object Storage) zu verwenden.

Mit einer Endpunkt-URL von https://s3.de.ovh.cloud.net und einer konfigurierten S3-CDN-URL zu https://storage.de.ovh.cloud.net/v1/<some-unique-user-id>/<the-bucket-name>

Wenn kurze URLs aufgelöst werden, verwendet Discourse die Endpunkt-URL, um die resultierende URL zu konstruieren (was fehlschlägt, da sie nicht die korrekte OVH-Benutzer-ID enthält - den Teil in der S3-CDN-URL).

Das Erzwingen von kurzen URLs mit dl=1 würde jedoch eine funktionierende Presigned-URL konstruieren, was für mich in Ordnung wäre.

Ich habe diese (S3-spezifischen) Umgebungsvariablen im Container-YAML gesetzt:

DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: DE
DISCOURSE_S3_ENDPOINT: https://s3.de.cloud.ovh.net
DISCOURSE_S3_ACCESS_KEY_ID: ...
DISCOURSE_S3_SECRET_ACCESS_KEY: ...
DISCOURSE_S3_CDN_URL: https://storage.de.ovh.cloud.net/v1/<some-unique-user-id>/<the-bucket-name>
DISCOURSE_S3_UPLOAD_BUCKET: <the-bucket-name>
DISCOURSE_S3_INSTALL_CORS_RULE: false
1 „Gefällt mir“

Vielleicht ist das nicht Teil dieses Themas, aber wenn das aktuelle Verhalten beabsichtigt ist, wie oder wo könnte man die Darstellung von Kurz-URLs im Frontend überschreiben? Ich denke daran, einfach in den Kochprozess von Beiträgen einzugreifen und dann den Query-Parameter an die Kurz-URLs von Anhängen anzuhängen. Ich weiß, wie man JS-Plugins für Discourse schreibt, aber meistens habe ich einfach Schwierigkeiten, das richtige Widget zu finden, um es neu zu öffnen, oder eine Funktion zum Überschreiben.

Ok, ich habe die Stelle gefunden, an der Markdown für Anhänge generiert wird und soweit ich die Plugin-API verstehe, kann man sie nicht (einfach) überschreiben (ich glaube sogar, man sollte es nicht tun).

Mein ursprünglicher Gedanke, diesen URLs einen ?dl=1-Parameter hinzuzufügen, scheint also der falsche Weg zu sein.

Was das Nicht-Erzwingen von Downloads für aufgelöste Kurz-URLs angeht: Wenn ich das Argument gegen öffentliche ACLs auf S3-Buckets richtig verstehe, sollte man entweder:

  1. Dateien von S3 über ein CDN bereitstellen (für Anhänge nicht machbar, wie @martin anmerkte, da wir in diesem Fall den Dateinamen für den Download möglicherweise nicht korrekt festlegen können)
  2. Eine vorab signierte URL für das S3-Objekt erstellen

Das aktuelle Verhalten tut jedoch keines von beiden und erwartet, dass der S3-Bucket eine öffentliche ACL hat. Dies scheint auch bei unterstützten S3-Anbietern (einschließlich Amazon) der Fall zu sein. Daher würde ich fragen, warum die Option force_download in Discourse.store.url_for nicht standardmäßig auf true gesetzt wird, wenn Kurz-URLs für S3-Stores aufgelöst werden?",“target_locale”:“de”}

1 „Gefällt mir“

Ich habe hier dasselbe Problem. Ich erwarte, dass die Datei hinter uploads/short-url über die S3-CDN-URL heruntergeladen oder dorthin umgeleitet wird.

2 „Gefällt mir“

Wir haben das gleiche Problem mit Cloudflare R2, da es die direkte S3-URL ohne eine vorgenerierte URL nicht zu erlauben scheint.
Und R2 unterstützt keine ACLs für Buckets.

Es sieht so aus, als ob Discourse kürzlich eine Option „s3 use cdn url for all uploads“ hinzugefügt hat, die dieses Problem löst.