非画像アップロードでS3 CDN URLが使用されていない

S3 CDN URL が投稿へのアップロード時に無視される と関連があるかもしれません。

最初は設定を見落としたのかと思いましたが、Meta 上でも再現可能です。
https://meta.discourse.org/uploads/short-url/dw1U4hctATusBlHsUmWQXeme66j.csvこちら にアップロード)は、302 リダイレクトで
//assets-meta-cdck-prod-meta.s3.dualstack.us-west-1.amazonaws.com/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv へ移動します。

代わりに https://d11a6trkgmumsb.cloudfront.net/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv へリダイレクトすべきではないでしょうか?

「いいね!」 5

うーん、ここに問題があるかもしれません。@martin、調査してもらえますか?可能であれば、CDN にリダイレクトするべきでしょう。

「いいね!」 5

少し複雑な点ですが、今すぐ確認しました。基本的には、「強制ダウンロード」を行う場合、つまり添付ファイルのリンクをクリックしたり、画像の「ダウンロード」ボタンをクリックしたりする場合は、S3 からプレサインド URL を介して常にダウンロードを行います。これは、適切な Content-Disposition ヘッダーを追加するためです:

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

CDN URL がこのように動作することは可能だとは思えません。画像の CDN URL は、インライン表示時にのみ使用され、ダウンロード時には使用されません。また、プライベート ACL を持つセキュリティ付きの画像や添付ファイルの場合、プレサインド URL を常に使用する必要があります。

「いいね!」 2

@martin 添付ファイルリンクについて、「常にダウンロードを強制する」ように設定する方法がわかりません。現在、画像以外のファイルをアップロードすると、レンダリングされたURLは ?dl=1 パラメータのない短縮URLになり、これは対応するアップロードの url 属性の値に解決されます(これはプリサインされたURLではなく、URLがS3のCDN_URLではなく、特定のS3プロバイダーでのみ機能する可能性がある構築されたものであるため、当社のケースでも失敗します)。

添付ファイルを常にダウンロード強制する方法はありますか、それとも現在の動作は実際にはバグですか?

「いいね!」 1

ここで詳しく教えていただけますか?Amazon S3を使用していますか、それとも別のプロバイダーですか?もしそうなら、どちらですか?

「いいね!」 1

はい、私は_サポートされていない_S3プロバイダー(OVH Object Storage)を使用しているようです。

エンドポイントURLはhttps://s3.de.ovh.cloud.netで、s3 cdn_urlはhttps://storage.de.ovh.cloud.net/v1/<some-unique-user-id>/<the-bucket-name>に設定されています。

ショートURLが解決されるとき、DiscourseはエンドポイントURLを使用して結果のURLを構築します(これは正しいOVHユーザーIDが含まれていないため失敗します。これはs3 cdn_urlの一部です)。

ただし、ショートURLにdl=1を強制すると、機能する署名付きURLが構築され、私にとっては問題ありません。

コンテナYAML内でこれらの(S3固有の)環境変数を設定しました。

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

このトピックの範囲外かもしれませんが、現在の動作が意図したものであれば、フロントエンドで short-url-rendering をオーバーライドするにはどうすればよいですか、またはどこで行えますか?投稿の cooking プロセスにフックして、attachment short-urls にクエリパラメータを追加することを考えています。js-plugins for Discourse の書き方はわかっていますが、ほとんどの場合、「reopen」するのに適切な Widget やオーバーライドする関数を見つけるのに苦労しています。

添付ファイルのMarkdownが生成される場所を見つけました(discourse/app/assets/javascripts/discourse/app/lib/uploads.js at v2.8.0.beta11 · discourse/discourse · GitHub

したがって、それらのURLに?dl=1パラメータを追加するという最初の考えは、間違った方法のようです。

解決されたショートURLのダウンロードを強制しないことに関して:S3バケットの公開ACLに対する議論(S3 CDN URL ignored when uploading into posts - #4 by timkelty

  1. S3からCDN経由でファイルを配信する(添付ファイルには実現不可能であると@martinが指摘したように、この場合、ダウンロードのためにファイル名を正しく設定できない可能性があります)
  2. S3オブジェクトのプリサインURLを作成する

しかし、現在の動作はどちらも行っておらず、S3バケットが公開ACLを持っていることを期待しています。これは、サポートされているS3プロバイダー(Amazonを含む)にも当てはまるようです。そのため、S3ストアのショートURLを解決する際に、Discourse.store.url_forforce_downloadオプションをデフォルトでtrueにしないのはなぜでしょうか(discourse/app/controllers/uploads_controller.rb at v2.8.0.beta11 · discourse/discourse · GitHub

「いいね!」 1

ここでも同じ問題が発生しています。期待しているのは、uploads/short-url の背後にあるファイルが S3 CDN URL を介してダウンロードされるか、リダイレクトされることです。

「いいね!」 2

Cloudflare R2 でも同様の問題が発生しています。署名付き URL なしで直接 S3 URL を使用できないようです。
また、R2 はバケットの ACL をサポートしていません。

Discourse が最近「すべてのアップロードに CDN URL を使用する」という機能を追加したようで、この問題が解決するようです。