Skip to content

Commit 9f87f15

Browse files
committed
Accept non-standard status codes.
1 parent 0cdfdb3 commit 9f87f15

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import akka.http.scaladsl.model.MediaType
2929
import akka.http.scaladsl.model.MediaTypes
3030
import akka.http.scaladsl.model.MediaTypes._
3131
import akka.http.scaladsl.model.StatusCodes._
32+
import akka.http.scaladsl.model.StatusCodes
3233
import akka.http.scaladsl.model.StatusCode
3334
import akka.http.scaladsl.model.headers.RawHeader
3435
import akka.http.scaladsl.model.headers._
@@ -40,7 +41,7 @@ import akka.http.scaladsl.model.headers.`Timeout-Access`
4041
import akka.http.scaladsl.model.ContentType
4142
import akka.http.scaladsl.model.ContentTypes
4243
import akka.http.scaladsl.model.FormData
43-
import akka.http.scaladsl.model.HttpMethods.{OPTIONS}
44+
import akka.http.scaladsl.model.HttpMethods.OPTIONS
4445
import akka.http.scaladsl.model.HttpCharsets
4546
import akka.http.scaladsl.model.HttpResponse
4647
import spray.json._
@@ -248,18 +249,19 @@ protected[core] object WhiskWebActionsApi extends Directives {
248249

249250
val body = fields.get("body")
250251

251-
val code = fields.get(rp.statusCode).map {
252-
case JsNumber(c) =>
253-
// the following throws an exception if the code is not a whole number or a valid code
254-
StatusCode.int2StatusCode(c.toIntExact)
255-
case JsString(c) =>
256-
// parse the string to an Int (not a BigInt) matching JsNumber case match above
257-
// c.toInt could throw an exception if the string isn't an integer
258-
StatusCode.int2StatusCode(c.toInt)
252+
val intCode = fields.get(rp.statusCode).map {
253+
// the following throws an exception if the code is not a whole number or a valid code
254+
case JsNumber(c) => c.toIntExact
255+
256+
// parse the string to an Int (not a BigInt) matching JsNumber case match above
257+
// c.toInt could throw an exception if the string isn't an integer
258+
case JsString(c) => c.toInt
259259

260260
case _ => throw new Throwable("Illegal status code")
261261
}
262262

263+
val code: Option[StatusCode] = intCode.map(c => StatusCodes.getForKey(c).getOrElse(StatusCodes.custom(c, "")))
264+
263265
body.collect {
264266
case JsString(str) if str.nonEmpty => interpretHttpResponse(code.getOrElse(OK), headers, str, transid)
265267
case JsString(str) /* str.isEmpty */ => respondWithEmptyEntity(code.getOrElse(NoContent), headers)
@@ -268,7 +270,7 @@ protected[core] object WhiskWebActionsApi extends Directives {
268270

269271
} getOrElse {
270272
// either the result was not a JsObject or there was an exception validating the
271-
// response as an http result
273+
// response as an http result (including an invalid status code)
272274
terminate(BadRequest, Messages.invalidMedia(`message/http`))(transid, jsonPrettyPrinter)
273275
}
274276
}

tests/src/test/scala/org/apache/openwhisk/core/controller/test/WebActionsApiTests.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
2929
import akka.http.scaladsl.model.FormData
3030
import akka.http.scaladsl.model.HttpEntity
3131
import akka.http.scaladsl.model.MediaTypes
32+
import akka.http.scaladsl.model.StatusCodes
3233
import akka.http.scaladsl.model.StatusCodes._
3334
import akka.http.scaladsl.model.HttpCharsets
3435
import akka.http.scaladsl.model.HttpHeader
@@ -914,6 +915,21 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
914915
}
915916
}
916917

918+
it should s"use non-standard action status code to terminate an http response (auth? ${creds.isDefined})" in {
919+
implicit val tid = transid()
920+
921+
Seq(s"$systemId/proxy/export_c.http").foreach { path =>
922+
allowedMethods.foreach { m =>
923+
actionResult = Some(JsObject(webApiDirectives.statusCode -> JsNumber(444)))
924+
invocationsAllowed += 1
925+
926+
m(s"$testRoutePath/$path") ~> Route.seal(routes(creds)) ~> check {
927+
status should be(StatusCodes.custom(444, ""))
928+
}
929+
}
930+
}
931+
}
932+
917933
it should s"use default field projection for extension (auth? ${creds.isDefined})" in {
918934
implicit val tid = transid()
919935

@@ -1957,13 +1973,18 @@ trait WebActionsApiBaseTests extends ControllerTestCommon with BeforeAndAfterEac
19571973

19581974
it should s"allowed string based status code (auth? ${creds.isDefined})" in {
19591975
implicit val tid = transid()
1960-
invocationsAllowed += 2
1976+
invocationsAllowed += 3
19611977

19621978
actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("200")))
19631979
Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
19641980
status should be(OK)
19651981
}
19661982

1983+
actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("444")))
1984+
Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
1985+
status should be(StatusCodes.custom(444, ""))
1986+
}
1987+
19671988
actionResult = Some(JsObject(webApiDirectives.statusCode -> JsString("xyz")))
19681989
Head(s"$testRoutePath/$systemId/proxy/export_c.http") ~> Route.seal(routes(creds)) ~> check {
19691990
status should be(BadRequest)

0 commit comments

Comments
 (0)