in core/controller/src/main/scala/org/apache/openwhisk/core/controller/WebActions.scala [477:554]
private def handleMatch(namespaceSegment: String,
pkgSegment: String,
actionNameWithExtension: String,
onBehalfOf: Option[Identity])(implicit transid: TransactionId) = {
def fullyQualifiedActionName(actionName: String) = {
val namespace = EntityName(namespaceSegment)
val pkgName = if (pkgSegment == "default") None else Some(EntityName(pkgSegment))
namespace.addPath(pkgName).addPath(EntityName(actionName)).toFullyQualifiedEntityName
}
provide(WhiskWebActionsApi.mediaTranscoderForName(actionNameWithExtension, webApiDirectives.enforceExtension)) {
case (actionName, Some(extension)) =>
// extract request context, checks for overrides of reserved properties, and constructs action arguments
// as the context body which may be the incoming request when the content type is JSON or formdata, or
// the raw body as __ow_body (and query parameters as __ow_query) otherwise
extract(_.request.entity) { e =>
requestMethodParamsAndPath { context =>
provide(fullyQualifiedActionName(actionName)) { fullActionName =>
onComplete(verifyWebAction(fullActionName)) {
case Success((actionOwnerIdentity, action)) =>
validateSize(isWhithinRange(actionOwnerIdentity.limits, e.contentLengthOption.getOrElse(0)))(
transid,
jsonPrettyPrinter) {
val actionDelegatesCors =
!action.annotations.getAs[Boolean](Annotations.WebCustomOptionsAnnotationName).getOrElse(false)
if (actionDelegatesCors) {
respondWithHeaders(defaultCorsResponse(context.headers)) {
if (context.method == OPTIONS) {
complete(OK, HttpEntity.Empty)
} else {
extractEntityAndProcessRequest(
confirmAuthenticated(action.annotations, context.headers, onBehalfOf).getOrElse(true),
actionOwnerIdentity,
action,
extension,
onBehalfOf,
context,
e)
}
}
} else {
val allowedToProceed = if (context.method != OPTIONS) {
confirmAuthenticated(action.annotations, context.headers, onBehalfOf).getOrElse(true)
} else {
// invoke the action for OPTIONS even if user is not authorized
// so that action can respond to option request
true
}
extractEntityAndProcessRequest(
allowedToProceed,
actionOwnerIdentity,
action,
extension,
onBehalfOf,
context,
e)
}
}
case Failure(t: RejectRequest) =>
terminate(t.code, t.message)
case Failure(t) =>
logging.error(this, s"exception in handleMatch: $t")
terminate(InternalServerError)
}
}
}
}
case (_, None) =>
terminate(NotAcceptable, Messages.contentTypeExtensionNotSupported(WhiskWebActionsApi.allowedExtensions))
}
}