diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index a4622dc6e..cf800774c 100644 --- a/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.12_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -8,7 +8,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -29,16 +28,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -48,8 +47,13 @@ object RequestProcessor { securityRequest.setMethod(request.method.name) securityRequest.setServerPort(request.serverPort.toInt) - securityRequest.setClientIP(request.remoteAddr.get) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + securityRequest.setClientIP(request.remoteAddr.get.toString) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -58,8 +62,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -70,24 +74,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY - if (header.name != null && header.name.isEmpty) { + var headerKey = StringUtils.EMPTY + if (header.name != null && !header.name.isEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -118,15 +125,16 @@ object RequestProcessor { }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body + ServletHelper.executeBeforeExitingTransaction() if (!ServletHelper.isResponseContentTypeExcluded(NewRelicSecurity.getAgent.getSecurityMetaData.getResponse.getResponseContentType)) { val rxssOperation = new RXSSOperation(NewRelicSecurity.getAgent.getSecurityMetaData.getRequest, NewRelicSecurity.getAgent.getSecurityMetaData.getResponse, this.getClass.getName, METHOD_WITH_HTTP_APP) @@ -152,5 +160,14 @@ object RequestProcessor { }) } + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) } diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index 4a333e8a4..ab091964c 100644 --- a/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.12_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -9,7 +9,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -30,16 +29,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -50,7 +49,12 @@ object RequestProcessor { securityRequest.setMethod(request.method.name) securityRequest.setServerPort((request.serverPort).get.asInstanceOf[Port].value) securityRequest.setClientIP(request.remoteAddr.get.toString) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -59,8 +63,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -71,24 +75,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY + var headerKey = StringUtils.EMPTY if (header.name != null && header.name.nonEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -119,13 +126,13 @@ object RequestProcessor { }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body @@ -154,5 +161,14 @@ object RequestProcessor { }) } + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) } diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index e028790b4..fbbb71849 100644 --- a/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.12_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -9,7 +9,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -30,16 +29,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -50,7 +49,12 @@ object RequestProcessor { securityRequest.setMethod(request.method.name) securityRequest.setServerPort((request.serverPort).get.asInstanceOf[Port].value) securityRequest.setClientIP(request.remoteAddr.get.toString) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -59,8 +63,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -71,24 +75,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY + var headerKey = StringUtils.EMPTY if (header.name != null && header.name.nonEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -119,13 +126,13 @@ object RequestProcessor { }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body @@ -154,5 +161,14 @@ object RequestProcessor { }) } + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) } diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index 74b226dc5..70443d5fd 100644 --- a/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.13_0.21/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -8,7 +8,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -29,16 +28,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -47,9 +46,14 @@ object RequestProcessor { val securityAgentMetaData: AgentMetaData = securityMetaData.getMetaData securityRequest.setMethod(request.method.name) - securityRequest.setServerPort((request.serverPort).longValue().toInt) - securityRequest.setClientIP(request.remoteAddr.get) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + securityRequest.setServerPort(request.serverPort.toInt) + securityRequest.setClientIP(request.remoteAddr.get.toString) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -58,8 +62,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -70,24 +74,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY - if (header.name != null && header.name.isEmpty) { + var headerKey = StringUtils.EMPTY + if (header.name != null && !header.name.isEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -118,13 +125,13 @@ object RequestProcessor { }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body @@ -153,5 +160,14 @@ object RequestProcessor { }) } + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) } diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index 7bf9ffcce..d19d2aa49 100644 --- a/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.13_0.22/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -9,7 +9,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -30,16 +29,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -50,7 +49,12 @@ object RequestProcessor { securityRequest.setMethod(request.method.name) securityRequest.setServerPort((request.serverPort).get.asInstanceOf[Port].value) securityRequest.setClientIP(request.remoteAddr.get.toString) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -59,8 +63,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -71,24 +75,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY + var headerKey = StringUtils.EMPTY if (header.name != null && header.name.nonEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -118,13 +125,14 @@ object RequestProcessor { securityRequest.getHeaders.put(headerKey.toLowerCase, headerValue) }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body @@ -153,5 +161,14 @@ object RequestProcessor { }) } + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) } diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java b/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java deleted file mode 100644 index 262a24583..000000000 --- a/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/BlazeUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.newrelic.agent.security.http4s.blaze.server; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.StringUtils; - -import java.util.Map; - -public class BlazeUtils { - - public static String getContentType(Map headers) { - String contentType = StringUtils.EMPTY; - if (headers.containsKey("content-type")){ - contentType = headers.get("content-type"); - } - return contentType; - } - - public static String getTraceHeader(Map headers) { - String data = StringUtils.EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - - public static String getProtocol(boolean isSecure) { - if (isSecure) { - return "https"; - } - return "http"; - } - - - private static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} - } - - private static String getNrSecCustomAttribName() { - return "HTTP4S-EMBER-REQUEST_LOCK" + Thread.currentThread().getId(); - } -} diff --git a/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala b/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala index 482f04462..e502cb9e4 100644 --- a/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala +++ b/instrumentation-security/http4s-blaze-server-2.13_0.23/src/main/scala/com/newrelic/agent/security/http4s/blaze/server/RequestProcessor.scala @@ -9,7 +9,6 @@ import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, I import com.newrelic.api.agent.security.schema._ import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException import com.newrelic.api.agent.security.schema.operation.RXSSOperation -import com.newrelic.api.agent.security.schema.policy.AgentPolicy import com.newrelic.api.agent.security.utils.logging.LogLevel import org.http4s.{Headers, Request, Response} @@ -30,16 +29,16 @@ object RequestProcessor { val result = construct((): Unit) .redeemWith(_ => httpApp(request), _ => for { - _ <- preprocessHttpRequest(request) + isLockAcquired <- preprocessHttpRequest(request) resp <- httpApp(request) - _ <- postProcessSecurityHook(resp) + _ <- postProcessSecurityHook(isLockAcquired, resp) } yield resp ) result } - private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Unit] = construct { - val isLockAcquired = BlazeUtils.acquireLockIfPossible() + private def preprocessHttpRequest[F[_]: Sync](request: Request[F]): F[Boolean] = construct { + val isLockAcquired = GenericHelper.acquireLockIfPossible("HTTP4S-BLAZE-REQUEST_LOCK") try { if (NewRelicSecurity.isHookProcessingActive && isLockAcquired && !NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isRequestParsed){ @@ -50,7 +49,12 @@ object RequestProcessor { securityRequest.setMethod(request.method.name) securityRequest.setServerPort((request.serverPort).get.asInstanceOf[Port].value) securityRequest.setClientIP(request.remoteAddr.get.toString) - securityRequest.setProtocol(BlazeUtils.getProtocol(request.isSecure.get)) + + securityRequest.setProtocol("http") + if (request.isSecure.get) { + securityRequest.setProtocol("https") + } + securityRequest.setUrl(request.uri.toString) if (securityRequest.getClientIP != null && securityRequest.getClientIP.trim.nonEmpty) { @@ -59,8 +63,8 @@ object RequestProcessor { } processRequestHeaders(request.headers, securityRequest) - securityMetaData.setTracingHeaderValue(BlazeUtils.getTraceHeader(securityRequest.getHeaders)) - securityRequest.setContentType(BlazeUtils.getContentType(securityRequest.getHeaders)) + securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders)) + securityRequest.setContentType(getContentType(securityRequest.getHeaders)) // TODO extract request body & user class detection @@ -71,24 +75,27 @@ object RequestProcessor { } catch { case e: Throwable => NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.ERROR_GENERATING_HTTP_REQUEST, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName) - } finally { - if (isLockAcquired) { - BlazeUtils.releaseLock() - } } + isLockAcquired + } + + private def getContentType(headers: util.Map[String, String]): String = { + var contentType = StringUtils.EMPTY + if (headers.containsKey("content-type")) contentType = headers.get("content-type") + contentType } private def processRequestHeaders(headers: Headers, securityRequest: HttpRequest): Unit = { headers.foreach(header => { var takeNextValue = false - var headerKey: String = StringUtils.EMPTY + var headerKey = StringUtils.EMPTY if (header.name != null && header.name.nonEmpty) { headerKey = header.name.toString } - val headerValue: String = header.value + val headerValue = header.value - val agentPolicy: AgentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy - val agentMetaData: AgentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData + val agentPolicy = NewRelicSecurity.getAgent.getCurrentPolicy + val agentMetaData = NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData if (agentPolicy != null && agentPolicy.getProtectionMode.getEnabled() && agentPolicy.getProtectionMode.getIpBlocking.getEnabled() @@ -119,13 +126,13 @@ object RequestProcessor { }) } - private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct { + private def postProcessSecurityHook[F[_]: Sync](isLockAcquired:Boolean, response: Response[F]): F[Unit] = construct { try { - if (NewRelicSecurity.isHookProcessingActive) { + if (NewRelicSecurity.isHookProcessingActive && isLockAcquired) { val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse securityResponse.setResponseCode(response.status.code) processResponseHeaders(response.headers, securityResponse) - securityResponse.setResponseContentType(BlazeUtils.getContentType(securityResponse.getHeaders)) + securityResponse.setResponseContentType(getContentType(securityResponse.getHeaders)) // TODO extract response body @@ -154,5 +161,14 @@ object RequestProcessor { }) } - private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t) + private def getTraceHeader(headers: util.Map[String, String]): String = { + var data = StringUtils.EMPTY + if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase)) { + data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) + if (data == null || data.trim.isEmpty) data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase) + } + data + } + + private def construct[F[_] : Sync, T](t: => T): F[T] = Sync[F].delay(t) }