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

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

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

「いいね!」 5

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

@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 を使用する」という機能を追加したようで、この問題が解決するようです。