Skip to content

Commit

Permalink
fix #2020
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieuancelin committed Nov 6, 2024
1 parent e9008fa commit 1027a55
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 28 deletions.
37 changes: 24 additions & 13 deletions otoroshi/app/wasm/proxywasm/api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.otoroshi.wasm4s.scaladsl.WasmVmData
import org.extism.sdk.{ExtismCurrentPlugin, HostUserData}
import org.extism.sdk.wasmotoroshi._
import otoroshi.env.Env
import otoroshi.next.models.NgRoute
import otoroshi.next.plugins.api.NgPluginHttpResponse
import otoroshi.utils.TypedMap
import otoroshi.utils.http.RequestImplicits._
Expand All @@ -23,10 +24,12 @@ object VmData {
tickPeriod = -1,
respRef = new AtomicReference[mvc.Result](null),
bodyInRef = new AtomicReference[ByteString](null),
bodyOutRef = new AtomicReference[ByteString](null)
bodyOutRef = new AtomicReference[ByteString](null),
requestRef = None,
routeRef = None,
)
def withRules(rules: JsValue): VmData = VmData.empty().copy(configuration = rules.stringify)
def from(request: RequestHeader, attrs: TypedMap)(implicit env: Env): VmData = {
def from(request: RequestHeader, route: Option[NgRoute], attrs: TypedMap)(implicit env: Env): VmData = {
val remote = request.headers
.get("remote-address")
.getOrElse(s"${request.connection.remoteAddress.toString.substring(1)}:${1234}")
Expand All @@ -35,6 +38,8 @@ object VmData {
respRef = new AtomicReference[play.api.mvc.Result](null),
bodyInRef = new AtomicReference[ByteString](null),
bodyOutRef = new AtomicReference[ByteString](null),
requestRef = Some(request),
routeRef = route,
tickPeriod = -1,
properties = Map(
"plugin_name" -> "foo".bytes,
Expand Down Expand Up @@ -83,23 +88,25 @@ object VmData {
}

case class VmData(
configuration: String,
properties: Map[String, Array[Byte]],
tickPeriod: Int = -1,
respRef: AtomicReference[play.api.mvc.Result],
bodyInRef: AtomicReference[ByteString],
bodyOutRef: AtomicReference[ByteString]
configuration: String,
properties: Map[String, Array[Byte]],
tickPeriod: Int = -1,
respRef: AtomicReference[play.api.mvc.Result],
bodyInRef: AtomicReference[ByteString],
bodyOutRef: AtomicReference[ByteString],
requestRef: Option[RequestHeader],
routeRef: Option[NgRoute],
) extends HostUserData
with WasmVmData {
def withRequest(request: RequestHeader, attrs: TypedMap)(implicit env: Env): VmData = {
def withRequest(request: RequestHeader, route: Option[NgRoute], attrs: TypedMap)(implicit env: Env): VmData = {
VmData
.from(request, attrs)
.from(request, route, attrs)
.copy(
configuration = configuration,
tickPeriod = tickPeriod,
respRef = respRef,
bodyInRef = bodyInRef,
bodyOutRef = bodyOutRef
bodyOutRef = bodyOutRef,
)
}
def withResponse(response: NgPluginHttpResponse, attrs: TypedMap, body_bytes: Option[ByteString])(implicit
Expand Down Expand Up @@ -129,17 +136,21 @@ case class VmData(
tickPeriod = tickPeriod,
respRef = respRef,
bodyInRef = bodyInRef,
bodyOutRef = bodyOutRef
bodyOutRef = bodyOutRef,
requestRef = requestRef,
routeRef = routeRef,
)
}
def httpResponse: Option[play.api.mvc.Result] = Option(respRef.get())
def bodyIn: Option[ByteString] = Option(bodyInRef.get())
def bodyOut: Option[ByteString] = Option(bodyOutRef.get())
def request: Option[RequestHeader] = requestRef
def route: Option[NgRoute] = routeRef
}

trait Api {

def proxyLog(plugin: ExtismCurrentPlugin, logLevel: Int, messageData: Int, messageSize: Int): Result
def proxyLog(plugin: ExtismCurrentPlugin, logLevel: Int, messageData: Int, messageSize: Int, data: VmData): Result

def proxyResumeStream(plugin: ExtismCurrentPlugin, streamType: StreamType): Result

Expand Down
18 changes: 11 additions & 7 deletions otoroshi/app/wasm/proxywasm/coraza.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import otoroshi.env.Env
import otoroshi.events.AnalyticEvent
import otoroshi.models.{EntityLocation, EntityLocationSupport}
import otoroshi.next.extensions._
import otoroshi.next.models.NgRoute
import otoroshi.next.plugins.api._
import otoroshi.next.utils.JsonHelpers
import otoroshi.security.IdGenerator
import otoroshi.storage.{BasicStore, RedisLike, RedisLikeStore}
import otoroshi.utils.{ReplaceAllWith, TypedMap}
Expand Down Expand Up @@ -79,11 +81,11 @@ class CorazaPlugin(wasm: WasmConfig, val config: CorazaWafConfig, key: String, e
private lazy val pluginConfigurationSize = rules.stringify.byteString.length
private lazy val contextId = new AtomicInteger(0)
private lazy val state =
new ProxyWasmState(CorazaPlugin.rootContextIds.incrementAndGet(), contextId, Some((l, m) => logCallback(l, m)), env)
new ProxyWasmState(CorazaPlugin.rootContextIds.incrementAndGet(), contextId, Some((l, m, vmd) => logCallback(l, m, vmd)), env)
private lazy val pool: WasmVmPool = WasmVmPool.forConfigurationWithId(key, wasm)(env.wasmIntegration.context)

def logCallback(level: org.slf4j.event.Level, msg: String): Unit = {
CorazaTrailEvent(level, msg).toAnalytics()
def logCallback(level: org.slf4j.event.Level, msg: String, data: VmData): Unit = {
CorazaTrailEvent(level, msg, data.request, data.route).debug(evt => evt.toJson.prettify.debugPrintln).toAnalytics()
}

def isStarted(): Boolean = started.get()
Expand Down Expand Up @@ -217,7 +219,7 @@ class CorazaPlugin(wasm: WasmConfig, val config: CorazaWafConfig, key: String, e
attrs: TypedMap
): Future[Either[play.api.mvc.Result, Unit]] = {
val vm = attrs.get(otoroshi.wasm.proxywasm.CorazaPluginKeys.CorazaWasmVmKey).get
val data = VmData.empty().withRequest(request, attrs)(env)
val data = VmData.empty().withRequest(request, attrs.get(otoroshi.next.plugins.Keys.RouteKey), attrs)(env)
val endOfStream = 1
val sizeHeaders = 0
val prs = new Parameters(3).pushInts(contextId, sizeHeaders, endOfStream)
Expand Down Expand Up @@ -249,7 +251,7 @@ class CorazaPlugin(wasm: WasmConfig, val config: CorazaWafConfig, key: String, e
attrs: TypedMap
): Future[Either[play.api.mvc.Result, Unit]] = {
val vm = attrs.get(otoroshi.wasm.proxywasm.CorazaPluginKeys.CorazaWasmVmKey).get
val data = VmData.empty().withRequest(request, attrs)(env)
val data = VmData.empty().withRequest(request, attrs.get(otoroshi.next.plugins.Keys.RouteKey), attrs)(env)
data.bodyInRef.set(body_bytes)
val endOfStream = 1
val sizeBody = body_bytes.size.bytes.length
Expand Down Expand Up @@ -760,7 +762,7 @@ class CorazaWafAdminExtension(val env: Env) extends AdminExtension {
}
}

case class CorazaTrailEvent(level: org.slf4j.event.Level, msg: String) extends AnalyticEvent {
case class CorazaTrailEvent(level: org.slf4j.event.Level, msg: String, request: Option[RequestHeader], route: Option[NgRoute]) extends AnalyticEvent {

override def `@service`: String = "--"
override def `@serviceId`: String = "--"
Expand Down Expand Up @@ -799,7 +801,9 @@ case class CorazaTrailEvent(level: org.slf4j.event.Level, msg: String) extends A
"level" -> level.name(),
"raw" -> msg,
"msg" -> txt,
"fields" -> JsObject(fields.mapValues(JsString.apply))
"fields" -> JsObject(fields.mapValues(JsString.apply)),
"route" -> route.map(_.json).getOrElse(JsNull).asValue,
"request" -> request.map(JsonHelpers.requestToJson).getOrElse(JsNull).asValue,
)
}
}
2 changes: 1 addition & 1 deletion otoroshi/app/wasm/proxywasm/functions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ object ProxyWasmFunctions {
params: Array[LibExtism.ExtismVal],
returns: Array[LibExtism.ExtismVal],
data: Optional[EnvUserData]
) => state.proxyLog(plugin, params(0).v.i32, params(1).v.i32, params(2).v.i32),
) => state.proxyLog(plugin, params(0).v.i32, params(1).v.i32, params(2).v.i32, getCurrentVmData()),
Optional.empty[EnvUserData]()
).withNamespace("env"),
new HostFunction[EnvUserData](
Expand Down
14 changes: 7 additions & 7 deletions otoroshi/app/wasm/proxywasm/state.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicInteger
class ProxyWasmState(
val rootContextId: Int,
val contextId: AtomicInteger,
logCallback: Option[Function2[org.slf4j.event.Level, String, Unit]],
logCallback: Option[Function3[org.slf4j.event.Level, String, VmData, Unit]],
env: Env
) extends Api {

Expand All @@ -32,7 +32,7 @@ class ProxyWasmState(
throw new NotImplementedError(s"proxy state method '${name}' is not implemented")
}

override def proxyLog(plugin: ExtismCurrentPlugin, logLevel: Int, messageData: Int, messageSize: Int): Result = {
override def proxyLog(plugin: ExtismCurrentPlugin, logLevel: Int, messageData: Int, messageSize: Int, data: VmData): Result = {
// println(s"proxyLog: $logLevel - $messageData - $messageSize")
getMemory(plugin, messageData, messageSize)
.fold(
Expand All @@ -42,19 +42,19 @@ class ProxyWasmState(
logLevel match {
case 0 =>
logger.trace(message)
logCallback.foreach(_.apply(org.slf4j.event.Level.TRACE, message))
logCallback.foreach(_.apply(org.slf4j.event.Level.TRACE, message, data))
case 1 =>
logger.debug(message)
logCallback.foreach(_.apply(org.slf4j.event.Level.DEBUG, message))
logCallback.foreach(_.apply(org.slf4j.event.Level.DEBUG, message, data))
case 2 =>
logger.info(message)
logCallback.foreach(_.apply(org.slf4j.event.Level.INFO, message))
logCallback.foreach(_.apply(org.slf4j.event.Level.INFO, message, data))
case 3 =>
logger.warn(message)
logCallback.foreach(_.apply(org.slf4j.event.Level.WARN, message))
logCallback.foreach(_.apply(org.slf4j.event.Level.WARN, message, data))
case _ =>
logger.error(message)
logCallback.foreach(_.apply(org.slf4j.event.Level.ERROR, message))
logCallback.foreach(_.apply(org.slf4j.event.Level.ERROR, message, data))
}
ResultOk
}
Expand Down

0 comments on commit 1027a55

Please sign in to comment.