A princípio, pensei que tivesse perdido alguma configuração, mas é reproduzível aqui no meta: https://meta.discourse.org/uploads/short-url/dw1U4hctATusBlHsUmWQXeme66j.csv (upload aqui) é um redirecionamento 302 para //assets-meta-cdck-prod-meta.s3.dualstack.us-west-1.amazonaws.com/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv
Não deveria redirecionar para https://d11a6trkgmumsb.cloudfront.net/original/3X/5/e/5ebb2cfb8cc907e8e8f7c6559a72d2f4a8ba2f8f.csv em vez disso?
Isso é um pouco complicado, acabei de dar uma olhada nisso. Basicamente, sempre fazemos o download do S3 usando uma URL assinada quando realizamos um “download forçado”, que é o que ocorre ao clicar no link do anexo ou no botão Download em uma imagem. Isso é necessário para que os cabeçalhos content-disposition apropriados sejam adicionados:
Acho que não é possível fazer com que a URL da CDN se comporte dessa forma? A URL da CDN para imagens é usada apenas na exibição inline, não durante o download. Além disso, no caso de imagens e anexos seguros que possuem ACL privada, a URL assinada deve sempre ser utilizada.
@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.