This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push: new be970eef5c [PERF] Allow browsers to cache download blobs be970eef5c is described below commit be970eef5c70d94ed8f12e18d17b572bc6fc1088 Author: Quan Tran <hqt...@linagora.com> AuthorDate: Tue Jan 14 11:57:48 2025 +0700 [PERF] Allow browsers to cache download blobs Recommended by JMAP RFC: https://jmap.io/spec-core.html#downloading-binary-data --- .../org/apache/james/jmap/rfc8621/contract/DownloadContract.scala | 1 + .../main/scala/org/apache/james/jmap/routes/DownloadRoutes.scala | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DownloadContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DownloadContract.scala index 6bbd8b2143..68f9fec1fb 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DownloadContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DownloadContract.scala @@ -81,6 +81,7 @@ trait DownloadContract { .`then` .statusCode(SC_OK) .contentType("message/rfc822") + .header("cache-control", "private, immutable, max-age=31536000") .extract .body .asString diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/DownloadRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/DownloadRoutes.scala index ea4aba7f8b..997957f3ba 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/DownloadRoutes.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/DownloadRoutes.scala @@ -31,7 +31,7 @@ import eu.timepit.refined.refineV import io.netty.buffer.Unpooled import io.netty.handler.codec.http.HttpHeaderNames.{CONTENT_LENGTH, CONTENT_TYPE} import io.netty.handler.codec.http.HttpResponseStatus._ -import io.netty.handler.codec.http.{HttpHeaderValidationUtil, HttpMethod, QueryStringDecoder} +import io.netty.handler.codec.http.{HttpHeaderNames, HttpHeaderValidationUtil, HttpMethod, QueryStringDecoder} import jakarta.inject.{Inject, Named} import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream import org.apache.james.jmap.HttpConstants.JSON_CONTENT_TYPE @@ -315,6 +315,7 @@ class DownloadRoutes @Inject()(@Named(InjectionKeys.RFC_8621) val authenticator: val resourceSupplier: Callable[InputStream] = () => blob.content val sourceSupplier: java.util.function.Function[InputStream, Mono[Void]] = stream => SMono(addContentDispositionHeader(optionalName) .compose(addContentLengthHeader(blob.size)) + .compose(addCacheControlHeader()) .apply(response) .header(CONTENT_TYPE, sanitizeHeaderValue(blobContentType.asString)) .status(OK) @@ -346,6 +347,9 @@ class DownloadRoutes @Inject()(@Named(InjectionKeys.RFC_8621) val authenticator: .map(size => resp.header("Content-Length", size.value.toString)) .getOrElse(resp) + private def addCacheControlHeader(): HttpServerResponse => HttpServerResponse = + resp => resp.header(HttpHeaderNames.CACHE_CONTROL, "private, immutable, max-age=31536000") + private def addContentDispositionHeaderRegardingEncoding(name: String, resp: HttpServerResponse): HttpServerResponse = if (CharMatcher.ascii.matchesAllOf(name)) { Try(resp.header("Content-Disposition", "attachment; filename=\"" + name + "\"")) --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org