openwhisk-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rab...@apache.org
Subject [incubator-openwhisk] branch master updated: Support "+json" content-types as WebAction input. (#3609)
Date Tue, 08 May 2018 15:29:33 GMT
This is an automated email from the ASF dual-hosted git repository.

rabbah pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 68c3fd5  Support "+json" content-types as WebAction input. (#3609)
68c3fd5 is described below

commit 68c3fd598d819f4e1795acbf9fb5c9686d1917e7
Author: Markus Thömmes <markusthoemmes@me.com>
AuthorDate: Tue May 8 17:29:30 2018 +0200

    Support "+json" content-types as WebAction input. (#3609)
    
    WebActions support various different input formats (like FormData). Only allowing application/json
to be parsed and handled as JSON is an unnecessary limitation since there are many "+json"
custom formats out there which boil down to JSON as well.
---
 .../scala/whisk/http/LenientSprayJsonSupport.scala | 29 ++++++++++++++++++++++
 .../scala/whisk/core/controller/WebActions.scala   | 10 +++-----
 .../core/controller/test/WebActionsApiTests.scala  | 18 ++++++++++++++
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/common/scala/src/main/scala/whisk/http/LenientSprayJsonSupport.scala b/common/scala/src/main/scala/whisk/http/LenientSprayJsonSupport.scala
new file mode 100644
index 0000000..596058b
--- /dev/null
+++ b/common/scala/src/main/scala/whisk/http/LenientSprayJsonSupport.scala
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package whisk.http
+
+import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
+import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
+import spray.json.JsValue
+
+object LenientSprayJsonSupport extends SprayJsonSupport {
+  // Removes the mandatory application/json content-type for unmarshalling
+  override implicit def sprayJsValueUnmarshaller: FromEntityUnmarshaller[JsValue] =
+    Unmarshaller.byteStringUnmarshaller
+      .andThen(sprayJsValueByteStringUnmarshaller)
+}
diff --git a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
index 708ad71..d74815c 100644
--- a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
@@ -21,7 +21,6 @@ import java.util.Base64
 
 import scala.concurrent.Future
 import scala.util.{Failure, Success, Try}
-
 import akka.http.scaladsl.model.HttpEntity.Empty
 import akka.http.scaladsl.server.Directives
 import akka.http.scaladsl.model.HttpMethod
@@ -36,7 +35,6 @@ import akka.http.scaladsl.model.headers._
 import akka.http.scaladsl.model.Uri.Query
 import akka.http.scaladsl.model.HttpEntity
 import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
 import akka.http.scaladsl.model.headers.`Content-Type`
 import akka.http.scaladsl.model.headers.`Timeout-Access`
 import akka.http.scaladsl.model.ContentType
@@ -45,13 +43,10 @@ import akka.http.scaladsl.model.FormData
 import akka.http.scaladsl.model.HttpMethods.{DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT}
 import akka.http.scaladsl.model.HttpCharsets
 import akka.http.scaladsl.model.HttpResponse
-
 import spray.json._
 import spray.json.DefaultJsonProtocol._
-
 import WhiskWebActionsApi.MediaExtension
 import RestApiCommons.{jsonPrettyResponsePrinter => jsonPrettyPrinter}
-
 import whisk.common.TransactionId
 import whisk.core.controller.actions.PostActionActivation
 import whisk.core.database._
@@ -59,6 +54,7 @@ import whisk.core.entity._
 import whisk.core.entity.types._
 import whisk.http.ErrorResponse.terminate
 import whisk.http.Messages
+import whisk.http.LenientSprayJsonSupport._
 import whisk.utils.JsHelpers._
 
 protected[controller] sealed class WebApiDirectives(prefix: String = "__ow_") {
@@ -290,7 +286,7 @@ protected[core] object WhiskWebActionsApi extends Directives {
     }
   }
 
-  private def isJsonFamily(mt: MediaType) = {
+  def isJsonFamily(mt: MediaType): Boolean = {
     mt == `application/json` || mt.value.endsWith("+json")
   }
 
@@ -574,7 +570,7 @@ trait WhiskWebActionsApi extends Directives with ValidateRequestSize with
PostAc
         case Empty =>
           process(None, isRawHttpAction)
 
-        case HttpEntity.Strict(ContentTypes.`application/json`, json) if !isRawHttpAction
=>
+        case HttpEntity.Strict(ct, json) if WhiskWebActionsApi.isJsonFamily(ct.mediaType)
&& !isRawHttpAction =>
           if (json.nonEmpty) {
             entity(as[JsValue]) { body =>
               process(Some(body), isRawHttpAction)
diff --git a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
index 0dd5848..7f8cde0 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -41,6 +41,7 @@ import akka.http.scaladsl.model.HttpMethods
 import akka.http.scaladsl.model.headers.{`Access-Control-Request-Headers`, `Content-Type`,
RawHeader}
 import akka.http.scaladsl.model.ContentTypes
 import akka.http.scaladsl.model.ContentType
+import akka.http.scaladsl.model.MediaType
 import spray.json._
 import spray.json.DefaultJsonProtocol._
 import whisk.common.TransactionId
@@ -1726,6 +1727,23 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
         status should be(BadRequest)
       }
     }
+
+    it should s"support json (including +json subtypes) (auth? ${creds.isDefined})" in {
+      implicit val tid = transid()
+
+      val path = s"$systemId/proxy/export_c.text/content/field1"
+      val entity = JsObject("field1" -> "value1".toJson)
+
+      Seq(
+        ContentType(MediaType.applicationWithFixedCharset("cloudevents+json", HttpCharsets.`UTF-8`)),
+        ContentTypes.`application/json`).foreach { ct =>
+        invocationsAllowed += 1
+        Post(s"$testRoutePath/$path", HttpEntity(ct, entity.compactPrint)) ~> Route.seal(routes(creds))
~> check {
+          status should be(OK)
+          responseAs[String] shouldBe "value1"
+        }
+      }
+    }
   }
 
   class TestingEntitlementProvider(config: WhiskConfig, loadBalancer: LoadBalancer)

-- 
To stop receiving notification emails like this one, please contact
rabbah@apache.org.

Mime
View raw message