URL de S3 CDN no se usa en cargas que no son de imágenes

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 Me gusta

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

5 Me gusta

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 Me gusta

@martin con respecto a los enlaces de archivos adjuntos, no veo cómo se pueden configurar para “forzar la descarga” siempre. En este momento, al cargar un archivo que no es una imagen, la URL renderizada resultante es una URL corta sin el parámetro ?dl=1 que se resuelve al valor del atributo url de la carga correspondiente (que no es una URL pre-firmada y también falla en nuestro caso, ya que la URL no es la URL CDN de S3, sino una construida que solo podría funcionar para ciertos proveedores de S3).

¿Hay alguna forma de forzar siempre la descarga de los archivos adjuntos, o el comportamiento actual es en realidad un error?

1 me gusta

¿Puedes ampliar aquí, estás usando Amazon S3 o un proveedor diferente? Si es así, ¿cuál?

1 me gusta

Sí, parece que estoy usando un proveedor S3 no compatible (OVH Object Storage)

Con una URL de punto final de https://s3.de.ovh.cloud.net y una s3 cdn_url configurada en https://storage.de.ovh.cloud.net/v1/<algun-id-de-usuario-unico>/<el-nombre-del-bucket>

Cuando se resuelven las URL cortas, Discourse utiliza la URL del punto final para construir la URL resultante (lo que falla ya que no incluye el ID de usuario de OVH correcto, la parte de la s3 cdn_url).

Sin embargo, forzar que las URL cortas tengan dl=1 construiría una presigned_url funcional que estaría bien para mí.

Configuré estas variables de entorno (específicas de S3) dentro del YAML del contenedor:

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/<algun-id-de-usuario-unico>/<el-nombre-del-bucket>
DISCOURSE_S3_UPLOAD_BUCKET: <el-nombre-del-bucket>
DISCOURSE_S3_INSTALL_CORS_RULE: false
1 me gusta

Quizás esto esté fuera del alcance de este tema, pero si el comportamiento actual es intencional, ¿cómo o dónde se podría anular la representación de URL cortas en el frontend? Estoy pensando en simplemente conectarme al proceso de cocción de las publicaciones y luego agregar el parámetro de consulta a las URL cortas de los archivos adjuntos. Soy consciente de cómo escribir complementos de JavaScript para Discourse, pero la mayoría de las veces me cuesta encontrar el Widget correcto para “reabrir” o la función para anular.

Ok, así que encontré el lugar donde se genera el Markdown para los archivos adjuntos y, por lo que entiendo de la API de plugins, uno no puede (fácilmente) anularlo (incluso creo que no debería hacerlo).

Así que mi idea inicial de agregar un parámetro ?dl=1 a esas URL parece ser la forma incorrecta de hacerlo.

Con respecto a no forzar descargas para URL cortas resueltas: si entiendo el argumento en contra de las ACL públicas en los buckets de S3 correctamente, uno debería:

  1. servir archivos desde S3 a través de una CDN (no factible para archivos adjuntos como señaló @martin, ya que es posible que no podamos configurar correctamente el nombre del archivo para la descarga en este caso)
  2. crear una URL pre-firmada para el objeto S3

Pero el comportamiento actual no hace ninguna de las dos cosas y espera que el bucket S3 tenga una ACL pública. Este también parece ser el caso de los proveedores S3 compatibles (incluido Amazon), así que me gustaría preguntar por qué no hacer que la opción force_download en Discourse.store.url_for sea verdadera por defecto al resolver URL cortas para tiendas S3.

1 me gusta

Tengo el mismo problema aquí, lo que espero es que el archivo detrás de uploads/short-url se descargue o redirija a la URL de S3 CDN.

2 Me gusta

Estamos enfrentando el mismo problema con Cloudflare R2, ya que no parece permitir el uso de la URL S3 directa sin una URL pre-firmada.
Y R2 no admite ACL para los buckets.

Parece que Discourse agregó recientemente una opción “s3 use cdn url for all uploads” que resuelve este problema.