Skip to content

Commit

Permalink
NR-325525: Extract HTTP response in Http4s-Blaze server
Browse files Browse the repository at this point in the history
  • Loading branch information
IshikaDawda committed Oct 21, 2024
1 parent 3a24ea8 commit d239f0f
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -117,5 +118,39 @@ object RequestProcessor {
})
}

private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -118,5 +119,40 @@ object RequestProcessor {
})
}

private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -118,5 +119,40 @@ object RequestProcessor {
})
}

private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -117,5 +118,40 @@ object RequestProcessor {
})
}

private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -117,6 +118,40 @@ object RequestProcessor {
securityRequest.getHeaders.put(headerKey.toLowerCase, headerValue)
})
}
private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ object RequestProcessor {
_ => for {
_ <- preprocessHttpRequest(request)
resp <- httpApp(request)
_ <- postProcessSecurityHook(resp)
} yield resp
)
result
Expand Down Expand Up @@ -118,5 +119,40 @@ object RequestProcessor {
})
}

private def postProcessSecurityHook[F[_]: Sync](response: Response[F]): F[Unit] = construct {
try {
if (NewRelicSecurity.isHookProcessingActive) {
val securityResponse = NewRelicSecurity.getAgent.getSecurityMetaData.getResponse
securityResponse.setResponseCode(response.status.code)
processResponseHeaders(response.headers, securityResponse)
securityResponse.setResponseContentType(BlazeUtils.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)
NewRelicSecurity.getAgent.registerOperation(rxssOperation)
}
}
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP_4S_EMBER_SERVER_2_12_0_23, e.getMessage), e, this.getClass.getName)
}
}

private def processResponseHeaders(headers: Headers, securityResp: HttpResponse): Unit = {
headers.foreach(header => {
if (header.name != null && header.name.isEmpty) {
securityResp.getHeaders.put(header.name.toString.toLowerCase, header.value)
}
})
}

private def construct[F[_]: Sync, T](t: => T): F[T] = Sync[F].delay(t)
}

0 comments on commit d239f0f

Please sign in to comment.