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
commit 1e99b7edda161ce17d9ddcd8f5abf9897cb2cd63 Author: Benoit Tellier <[email protected]> AuthorDate: Thu Oct 28 14:19:55 2021 +0700 JAMES-3539 WebPush client should allow specifying ContentCoding --- .../apache/james/jmap/pushsubscription/PushRequest.scala | 11 +++++++++++ .../james/jmap/pushsubscription/WebPushClient.scala | 6 ++++-- .../james/jmap/pushsubscription/PushServerExtension.scala | 1 + .../jmap/pushsubscription/WebPushClientContract.scala | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala index e7d9ab7..3a45216 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala @@ -91,7 +91,18 @@ case class PushTopicConstraint() case class PushTTLConstraint() +// Follows https://datatracker.ietf.org/doc/html/rfc8188 +// Encrypted Content-Encoding for HTTP +trait ContentCodingType { + def value: String +} +case object Aes128gcm extends ContentCodingType { + val value: String = "aes128gcm" +} +case class ContentCoding(`type`: ContentCodingType) + case class PushRequest(ttl: PushTTL, + contentCoding: Option[ContentCodingType] = None, topic: Option[PushTopic] = None, urgency: Option[PushUrgency] = None, payload: Array[Byte]) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/WebPushClient.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/WebPushClient.scala index 7c5ab59..eaa709b 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/WebPushClient.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/WebPushClient.scala @@ -26,8 +26,8 @@ import java.time.temporal.ChronoUnit import io.netty.buffer.Unpooled import io.netty.handler.codec.http.HttpResponseStatus import org.apache.james.jmap.api.model.PushSubscriptionServerURL -import org.apache.james.jmap.pushsubscription.DefaultWebPushClient.buildHttpClient -import org.apache.james.jmap.pushsubscription.WebPushClientHeader.{DEFAULT_TIMEOUT, MESSAGE_URGENCY, TIME_TO_LIVE, TOPIC} +import org.apache.james.jmap.pushsubscription.DefaultWebPushClient.{PUSH_SERVER_ERROR_RESPONSE_MAX_LENGTH, buildHttpClient} +import org.apache.james.jmap.pushsubscription.WebPushClientHeader.{CONTENT_ENCODING, DEFAULT_TIMEOUT, MESSAGE_URGENCY, TIME_TO_LIVE, TOPIC} import org.reactivestreams.Publisher import reactor.core.publisher.Mono import reactor.core.scala.publisher.SMono @@ -47,6 +47,7 @@ case class PushClientConfiguration(maxTimeoutSeconds: Option[Int], object WebPushClientHeader { val TIME_TO_LIVE: String = "TTL" + val CONTENT_ENCODING: String = "Content-Encoding" val MESSAGE_URGENCY: String = "Urgency" val TOPIC: String = "Topic" val DEFAULT_TIMEOUT: Duration = Duration.of(30, ChronoUnit.SECONDS) @@ -88,6 +89,7 @@ class DefaultWebPushClient(configuration: PushClientConfiguration) extends WebPu builder.add(TIME_TO_LIVE, request.ttl.value) builder.add(MESSAGE_URGENCY, request.urgency.getOrElse(PushUrgency.default).value) request.topic.foreach(t => builder.add(TOPIC, t.value)) + request.contentCoding.foreach(f => builder.add(CONTENT_ENCODING, f.value)) }) .post() .uri(pushServerUrl.value.toString) diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushServerExtension.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushServerExtension.scala index 5b18a11..13b0022 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushServerExtension.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushServerExtension.scala @@ -71,6 +71,7 @@ object MockPushServer { .withMethod("POST") .withHeader(string("Content-type"), string("application/json charset=utf-8")) .withHeader(string("Urgency")) + .withHeader(string("Content-Encoding")) .withHeader(string("Topic")) .withHeader(string("TTL"))) .respond(response diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/WebPushClientContract.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/WebPushClientContract.scala index 258fc58..6d4e616 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/WebPushClientContract.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/WebPushClientContract.scala @@ -79,6 +79,21 @@ trait WebPushClientContract { VerificationTimes.atLeast(1)) } + @Test + def pushShouldSpecifyContentCoding(pushServer: ClientAndServer): Unit = { + SMono.fromPublisher(testee.push(getPushSubscriptionServerURL, PushRequest( + ttl = PushTTL.validate(15).toOption.get, + contentCoding = Some(Aes128gcm), + payload = "Content123".getBytes(StandardCharsets.UTF_8)))) + .block() + pushServer.verify(request() + .withPath("/push") + .withHeader("TTL", "15") + .withHeader("Content-Encoding", "aes128gcm") + .withBody(new String(PUSH_REQUEST_SAMPLE.payload, StandardCharsets.UTF_8)), + VerificationTimes.atLeast(1)) + } + @ParameterizedTest @ValueSource(ints = Array(500, 501, 502, 503, 504)) def pushRequestShouldThrowWhenPushServerReturnFailHTTPStatus(httpErrorCode: Int, pushServer: ClientAndServer): Unit = { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
