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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]