You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ra...@apache.org on 2021/08/23 01:16:04 UTC

[openwhisk] branch master updated: Accept non-standard status codes. (#5149)

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/openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 7e1caaa  Accept non-standard status codes. (#5149)
7e1caaa is described below

commit 7e1caaa42fb485cefea799ed6835adada1461d7f
Author: rodric rabbah <ro...@gmail.com>
AuthorDate: Sun Aug 22 21:15:50 2021 -0400

    Accept non-standard status codes. (#5149)
---
 .../openwhisk/core/controller/WebActions.scala     | 22 +++++++++++----------
 .../core/controller/test/WebActionsApiTests.scala  | 23 +++++++++++++++++++++-
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala b/core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala
index 4cf7496..c4d7d44 100644
--- a/core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala
+++ b/core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala
@@ -29,6 +29,7 @@ import akka.http.scaladsl.model.MediaType
 import akka.http.scaladsl.model.MediaTypes
 import akka.http.scaladsl.model.MediaTypes._
 import akka.http.scaladsl.model.StatusCodes._
+import akka.http.scaladsl.model.StatusCodes
 import akka.http.scaladsl.model.StatusCode
 import akka.http.scaladsl.model.headers.RawHeader
 import akka.http.scaladsl.model.headers._
@@ -40,7 +41,7 @@ import akka.http.scaladsl.model.headers.`Timeout-Access`
 import akka.http.scaladsl.model.ContentType
 import akka.http.scaladsl.model.ContentTypes
 import akka.http.scaladsl.model.FormData
-import akka.http.scaladsl.model.HttpMethods.{OPTIONS}
+import akka.http.scaladsl.model.HttpMethods.OPTIONS
 import akka.http.scaladsl.model.HttpCharsets
 import akka.http.scaladsl.model.HttpResponse
 import spray.json._
@@ -248,18 +249,19 @@ protected[core] object WhiskWebActionsApi extends Directives {
 
       val body = fields.get("body")
 
-      val code = fields.get(rp.statusCode).map {
-        case JsNumber(c) =>
-          // the following throws an exception if the code is not a whole number or a valid code
-          StatusCode.int2StatusCode(c.toIntExact)
-        case JsString(c) =>
-          // parse the string to an Int (not a BigInt) matching JsNumber case match above
-          // c.toInt could throw an exception if the string isn't an integer
-          StatusCode.int2StatusCode(c.toInt)
+      val intCode = fields.get(rp.statusCode).map {
+        // the following throws an exception if the code is not a whole number or a valid code
+        case JsNumber(c) => c.toIntExact
+
+        // parse the string to an Int (not a BigInt) matching JsNumber case match above
+        // c.toInt could throw an exception if the string isn't an integer
+        case JsString(c) => c.toInt
 
         case _ => throw new Throwable("Illegal status code")
       }
 
+      val code: Option[StatusCode] = intCode.map(c => StatusCodes.getForKey(c).getOrElse(StatusCodes.custom(c, "")))
+
       body.collect {
         case JsString(str) if str.nonEmpty   => interpretHttpResponse(code.getOrElse(OK), headers, str, transid)
         case JsString(str) /* str.isEmpty */ => respondWithEmptyEntity(code.getOrElse(NoContent), headers)
@@ -268,7 +270,7 @@ protected[core] object WhiskWebActionsApi extends Directives {
 
     } getOrElse {
       // either the result was not a JsObject or there was an exception validating the
-      // response as an http result
+      // response as an http result (including an invalid status code)
       terminate(BadRequest, Messages.invalidMedia(`message/http`))(transid, jsonPrettyPrinter)
     }
   }
diff --git a/tests/src/test/scala/org/apache/openwhisk/core/controller/test/WebActionsApiTests.scala b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/WebActionsApiTests.scala
index a1b67ec..ddf7e38 100644
--- a/tests/src/test/scala/org/apache/openwhisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/WebActionsApiTests.scala
@@ -29,6 +29,7 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
 import akka.http.scaladsl.model.FormData
 import akka.http.scaladsl.model.HttpEntity
 import akka.http.scaladsl.model.MediaTypes
+import akka.http.scaladsl.model.StatusCodes
 import akka.http.scaladsl.model.StatusCodes._
 import akka.http.scaladsl.model.HttpCharsets
 import akka.http.scaladsl.model.HttpHeader
@@ -914,6 +915,21 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
       }
     }
 
+    it should s"use non-standard action status code to terminate an http response (auth? ${creds.isDefined})" in {
+      implicit val tid = transid()
+
+      Seq(s"$systemId/proxy/export_c.http").foreach { path =>
+        allowedMethods.foreach { m =>
+          actionResult = Some(JsObject(webApiDirectives.statusCode -> JsNumber(444)))
+          invocationsAllowed += 1
+
+          m(s"$testRoutePath/$path") ~> Route.seal(routes(creds)) ~> check {
+            status should be(StatusCodes.custom(444, ""))
+          }
+        }
+      }
+    }
+
     it should s"use default field projection for extension (auth? ${creds.isDefined})" in {
       implicit val tid = transid()
 
@@ -1957,13 +1973,18 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
 
     it should s"allowed string based status code (auth? ${creds.isDefined})" in {
       implicit val tid = transid()
-      invocationsAllowed += 2
+      invocationsAllowed += 3
 
       actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("200")))
       Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
         status should be(OK)
       }
 
+      actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("444")))
+      Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
+        status should be(StatusCodes.custom(444, ""))
+      }
+
       actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("xyz")))
       Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
         status should be(BadRequest)