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?
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:
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.
@martin em relação a links de anexos, não consigo ver como eles podem ser definidos para sempre “forçar download”. No momento, ao carregar um arquivo que não seja de imagem, a URL renderizada resultante é uma URL curta sem o parâmetro ?dl=1, que é resolvida para o valor do atributo url do upload correspondente (que não é uma URL pré-assinada e também falha em nosso caso, pois a URL não é a cdn_url do S3, mas uma construída que pode funcionar apenas para certos provedores S3).
Existe alguma maneira de forçar sempre o download de anexos, ou o comportamento atual é realmente um bug?
Sim, parece que estou usando um provedor S3 não suportado (OVH Object Storage)
Com uma URL de endpoint de https://s3.de.ovh.cloud.net e uma s3 cdn_url configurada para https://storage.de.ovh.cloud.net/v1/<algum-id-de-usuário-único>/<o-nome-do-bucket>
Quando URLs curtas são resolvidas, o Discourse usa a URL do endpoint para construir a URL resultante (o que falha, pois não inclui o ID de usuário OVH correto - a parte na s3 cdn_url).
Forçar URLs curtas a terem dl=1 construiria uma presigned_url funcional, o que seria bom para mim.
Eu defini essas variáveis de ambiente (específicas de S3) dentro do YAML do contêiner:
Talvez isso esteja fora do escopo deste tópico, mas se o comportamento atual for intencional, como ou onde se poderia substituir a renderização de URLs curtas no frontend? Estou pensando em simplesmente me conectar ao processo de cozimento de posts e, em seguida, anexar o parâmetro de consulta aos URLs curtos de anexos. Estou ciente de como escrever plugins js para o Discourse, mas na maioria das vezes tenho dificuldade em encontrar o Widget certo para “reabrir” ou a função para substituir.
Ok, então encontrei o local onde o Markdown para anexos é gerado e, pelo que entendi da API do plugin, não se pode (facilmente) substituí-lo (até acho que não se deveria fazer isso).
Então, meu pensamento inicial de adicionar um parâmetro ?dl=1 a esses URLs parece ser a maneira errada de fazer isso.
Servir arquivos do S3 via CDN (inviável para anexos, como @martin apontou, pois podemos não conseguir definir corretamente o nome do arquivo para download neste caso)
Criar uma URL pré-assinada para o objeto S3
Mas o comportamento atual não faz nem um nem outro e espera que o bucket S3 tenha uma ACL pública. Este também parece ser o caso para provedores S3 suportados (incluindo a Amazon), então eu perguntaria por que não tornar a opção force_download em Discourse.store.url_for o padrão como true ao resolver short-urls para stores S3?
Estamos enfrentando o mesmo problema com o Cloudflare R2, pois ele não parece permitir o uso da URL S3 direta sem uma URL pré-assinada.
E o R2 não suporta ACL para buckets.