org.http4s.Header Scala Examples
The following examples show how to use org.http4s.Header.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: HmacAuthMiddlewareSpec.scala From iotchain with MIT License | 5 votes |
package jbok.network.http.server.middleware import java.time.Instant import cats.Id import cats.effect.IO import cats.implicits._ import jbok.common.CommonSpec import jbok.network.http.server.authentication.HMAC import org.http4s.dsl.io._ import org.http4s.headers.Authorization import org.http4s.implicits._ import org.http4s.{AuthScheme, Credentials, Header, HttpRoutes, Request, Status, Uri} import scodec.bits.ByteVector import tsec.mac.jca.{HMACSHA256, MacSigningKey} import scala.concurrent.duration._ class HmacAuthMiddlewareSpec extends CommonSpec { "HmacAuthMiddleware" should { val key = HMACSHA256.buildKey[Id]( ByteVector.fromValidHex("70ea14ac30939a972b5a67cab952d6d7d474727b05fe7f9283abc1e505919e83").toArray ) def sign(url: String): (String, String) = { val datetime = Instant.now().toString val signature = HMAC.http.signForHeader("GET", url, datetime, key).unsafeRunSync() (signature, datetime) } val routes = HttpRoutes.of[IO] { case GET -> Root / "ping" => Ok("pong") } val service = routes.orNotFound val req = Request[IO](uri = Uri.uri("/ping")) service.run(req).unsafeRunSync().status shouldBe Status.Ok val authedService = HmacAuthMiddleware(key)(routes).orNotFound "403 if no Authorization header" in { val resp = authedService.run(req).unsafeRunSync() val text = resp.bodyAsText.compile.foldMonoid.unsafeRunSync() resp.status shouldBe Status.Forbidden text shouldBe HmacAuthError.NoAuthHeader.message } "403 if no X-Datetime header" in { val signature = HMAC.http.signForHeader("GET", "/ping", Instant.now().toString, key).unsafeRunSync() val req = Request[IO](uri = Uri.uri("/ping")).putHeaders(Authorization(Credentials.Token(AuthScheme.Bearer, signature))) val resp = authedService.run(req).unsafeRunSync() val text = resp.bodyAsText.compile.foldMonoid.unsafeRunSync() resp.status shouldBe Status.Forbidden text shouldBe HmacAuthError.NoDatetimeHeader.message } "403 if time window is closed" in { val authedService = HmacAuthMiddleware(key, 2.seconds)(routes).orNotFound val now = Instant.now() val signature = HMAC.http.signForHeader("GET", "/ping", now.toString, key).unsafeRunSync() val req = Request[IO](uri = Uri.uri("/ping")) .putHeaders( Authorization(Credentials.Token(AuthScheme.Bearer, signature)), Header("X-Datetime", now.toString) ) val resp = authedService.run(req).unsafeRunSync() resp.status shouldBe Status.Ok IO.sleep(3.seconds).unsafeRunSync() val resp2 = authedService.run(req).unsafeRunSync() val text = resp2.bodyAsText.compile.foldMonoid.unsafeRunSync() resp2.status shouldBe Status.Forbidden text shouldBe HmacAuthError.Timeout.message } "helper" in { val (sig, date) = sign("/v1/blocks") println(("Authorization", s"Bearer $sig")) println(("X-Datetime", date)) println(("Random key", ByteVector(MacSigningKey.toJavaKey[HMACSHA256](HMACSHA256.generateKey[Id]).getEncoded).toHex)) } } }
Example 2
Source File: MavenCentralClient.scala From zorechka-bot with MIT License | 5 votes |
package com.wix.zorechka.clients import com.wix.zorechka.Dep import org.http4s.{EntityDecoder, Header, Headers, Method, Request, Uri} import zio.{Task, ZIO} import zio.interop.catz._ import io.circe.generic.auto._ import org.http4s.circe.jsonOf import org.http4s.client.Client trait MavenCentralClient { val client: MavenCentralClient.Service } object MavenCentralClient { trait Service { def allVersions(dep: Dep): Task[List[Dep]] } trait Live extends MavenCentralClient { protected val httpClient: Client[Task] val client = new MavenCentralClient.Service { case class Response(response: InnerResponse) case class InnerResponse(docs: Seq[Document]) case class Document(v: String) implicit val decoder: EntityDecoder[Task, Response] = jsonOf[Task, Response] override def allVersions(dep: Dep): Task[List[Dep]] = { ZIO.accessM { client => val uri = Uri .unsafeFromString("http://search.maven.org/solrsearch/select") .withQueryParam("rows", "10") .withQueryParam("core", "gav") .withQueryParam("q", s""" g:"${dep.groupId}" AND a:"${dep.artifactId}" """) println(s"Maven search: ${uri.renderString}") val request = Request[Task](Method.GET, uri, headers = Headers.of(Header("Accept", "application/json"))) httpClient.fetch(request)(response => response.as[Response]).map { _.response.docs.map(_.v).map(v => Dep(dep.groupId, dep.artifactId, v)).toList } } } } } }
Example 3
Source File: TracingClient.scala From opencensus-scala with Apache License 2.0 | 5 votes |
package io.opencensus.scala.http4s import cats.effect.{Effect, Resource} import cats.implicits._ import io.opencensus.scala.Tracing import io.opencensus.scala.http.propagation.Propagation import io.opencensus.scala.http.{HttpAttributes => BaseHttpAttributes} import io.opencensus.scala.http4s.HttpAttributes._ import io.opencensus.scala.http4s.TracingUtils.recordResponse import io.opencensus.scala.http4s.propagation.Http4sFormatPropagation import io.opencensus.trace.{Span, Status} import org.http4s.client.Client import org.http4s.{Header, Request, Response} abstract class TracingClient[F[_]: Effect] { protected val tracing: Tracing protected val propagation: Propagation[Header, Request[F]] def trace(client: Client[F], parentSpan: Option[Span] = None): Client[F] = { val tracedOpen: Request[F] => Resource[F, Response[F]] = req => for { span <- Resource.liftF(startSpan(parentSpan, req)) enrichedReq = addTraceHeaders(req, span) res <- client .run(enrichedReq) .onError(traceError(span).andThen(x => Resource.liftF(x))) } yield recordResponse(span, tracing)(res) Client(tracedOpen) } private def traceError(span: Span): PartialFunction[Throwable, F[Unit]] = { case _ => recordException(span) } private def startSpan(parentSpan: Option[Span], req: Request[F]) = Effect[F].delay(startAndEnrichSpan(req, parentSpan)) private def startAndEnrichSpan( req: Request[F], parentSpan: Option[Span] ): Span = { val name = req.uri.path.toString val span = parentSpan.fold(tracing.startSpan(name))(span => tracing.startSpanWithParent(name, span) ) BaseHttpAttributes.setAttributesForRequest(span, req) span } private def addTraceHeaders(request: Request[F], span: Span): Request[F] = request.withHeaders( request.headers.put(propagation.headersWithTracingContext(span): _*) ) private def recordException(span: Span) = Effect[F].delay(tracing.endSpan(span, Status.INTERNAL)) } object TracingClient { def apply[F[_]: Effect]: TracingClient[F] = new TracingClient[F] { override protected val tracing: Tracing = Tracing override protected val propagation: Propagation[Header, Request[F]] = new Http4sFormatPropagation[F] {} } }
Example 4
Source File: Http4sAttributesSpec.scala From opencensus-scala with Apache License 2.0 | 5 votes |
package io.opencensus.scala.http4s import cats.Id import io.opencensus.scala.http.HttpAttributesSpec import org.http4s.{Header, Headers, Request, Response, Status, Uri} class Http4sAttributesSpec extends HttpAttributesSpec { import HttpAttributes._ "Http4s attributes extraction" should behave like httpAttributes( request, response ) def request: BuildRequest => Request[Id] = (request: BuildRequest) => Request[Id]( uri = Uri.unsafeFromString(request.host ++ request.path), headers = Headers( List(Header("User-Agent", request.userAgent)) ++ request.hostHeader .map(Header("Host", _)) ) ) def response: Int => Response[Id] = (code: Int) => Response[Id](Status(code)) }
Example 5
Source File: Github.scala From sonar-scala with GNU Lesser General Public License v3.0 | 5 votes |
package com.mwz.sonar.scala package pr package github import cats.effect.Sync import cats.syntax.flatMap._ import com.mwz.sonar.scala.pr.github.Codec._ import io.circe.generic.auto._ import mouse.boolean._ import org.http4s.client.Client import org.http4s.{Header, Headers, Method, Request, Uri} trait Github[F[_]] { def authenticatedUser: F[User] def pullRequest: F[PullRequest] def comments: F[List[Comment]] def createComment(comment: NewComment): F[Unit] def files: F[List[File]] def createStatus(sha: String, status: NewStatus): F[Unit] } object Github { def apply[F[_]: Sync](client: Client[F], pr: GlobalConfig.PullRequest): Github[F] = new Github[F] { val auth: Header = Header("Authorization", s"token ${pr.github.oauth}") val userUri: Uri = pr.github.apiuri / "user" val prUri: Uri = (pr.github.apiuri / "repos").addPath(pr.github.repository) / "pulls" / pr.prNumber val commentsUri: Uri = prUri / "comments" val filesUri: Uri = prUri / "files" def newStatusUri(sha: String): Uri = (pr.github.apiuri / "repos").addPath(pr.github.repository) / "statuses" / sha def request(uri: Uri): Request[F] = { Request[F]( uri = uri, headers = Headers.of(auth) ) } def authenticatedUser: F[User] = client.expect[User](request(userUri)) def pullRequest: F[PullRequest] = client.expect[PullRequest](request(prUri)) def comments: F[List[Comment]] = client.expect[List[Comment]](request(commentsUri)) def createComment(comment: NewComment): F[Unit] = { val request: F[Request[F]] = Sync[F].pure( Request(Method.POST, commentsUri, headers = Headers.of(auth)) .withEntity(comment) ) pr.dryRun.fold(Sync[F].unit, client.expect[Comment](request) >> Sync[F].unit) } def files: F[List[File]] = client.expect[List[File]](request(filesUri)) def createStatus(sha: String, status: NewStatus): F[Unit] = { val request: F[Request[F]] = Sync[F].pure( Request(Method.POST, newStatusUri(sha), headers = Headers.of(auth)) .withEntity(status) ) pr.dryRun.fold(Sync[F].unit, client.expect[Status](request) >> Sync[F].unit) } } }
Example 6
Source File: JdkHttpClient.scala From http4s-jdk-http-client with Apache License 2.0 | 5 votes |
package org.http4s.client.jdkhttpclient import java.net.URI import java.net.http.HttpRequest.BodyPublishers import java.net.http.HttpResponse.BodyHandlers import java.net.http.{HttpClient, HttpRequest, HttpResponse} import java.nio.ByteBuffer import java.util import java.util.concurrent.Flow import cats.ApplicativeError import cats.effect._ import cats.implicits._ import fs2.concurrent.SignallingRef import fs2.interop.reactivestreams._ import fs2.{Chunk, Stream} import org.http4s.client.Client import org.http4s.client.jdkhttpclient.compat.CollectionConverters._ import org.http4s.internal.fromCompletionStage import org.http4s.util.CaseInsensitiveString import org.http4s.{Header, Headers, HttpVersion, Request, Response, Status} import org.reactivestreams.FlowAdapters object JdkHttpClient { def simple[F[_]](implicit F: ConcurrentEffect[F], CS: ContextShift[F]): F[Client[F]] = F.delay(HttpClient.newHttpClient()).map(apply(_)) def convertHttpVersionFromHttp4s[F[_]]( version: HttpVersion )(implicit F: ApplicativeError[F, Throwable]): F[HttpClient.Version] = version match { case HttpVersion.`HTTP/1.1` => HttpClient.Version.HTTP_1_1.pure[F] case HttpVersion.`HTTP/2.0` => HttpClient.Version.HTTP_2.pure[F] case _ => F.raiseError(new IllegalArgumentException("invalid HTTP version")) } // see jdk.internal.net.http.common.Utils#DISALLOWED_HEADERS_SET private val restrictedHeaders = Set( "connection", "content-length", "date", "expect", "from", "host", "upgrade", "via", "warning" ).map(CaseInsensitiveString(_)) }
Example 7
Source File: package.scala From temperature-machine with Apache License 2.0 | 5 votes |
package bad.robot.temperature import cats.effect.IO import org.http4s.{Header, Response, Status} import org.specs2.matcher.{Expectable, MatchResult, Matcher} package object test { def haveStatus(status: Status) = new Matcher[Response[IO]] { def apply[S <: Response[IO]](e: Expectable[S]): MatchResult[S] = result( e.value.status == status, s"""Status of [${e.value.status}] | |is | |$status""".stripMargin, s"""Status of |[${e.value.status}] | |is not | |[$status] | |(${e.value.as[String]})""".stripMargin, e) } def containsHeader(name: String, value: String) = new Matcher[Response[IO]] { def apply[S <: Response[IO]](e: Expectable[S]): MatchResult[S] = result( e.value.headers.toList.map(_.toRaw) contains Header(name, value), s"""${e.value.headers} | |contains | |$name""".stripMargin, s"""The response headers '${e.value.headers.toList.mkString("\n")}' | |do not contain | |[$name: $value] |""".stripMargin, e) } }
Example 8
Source File: ResponseGenerator.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.restserver.http4s import cats.Applicative import cats.implicits._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityEncoder, Header, Response} trait ResponseGenerator[F[_]] { self: Http4sDsl[F] => implicit final class EitherResponses[A, B](e: Either[A, B]) { def toResponse(headers: Header*)(implicit F: Applicative[F], w0: EntityEncoder[F, A], w1: EntityEncoder[F, B] ): F[Response[F]] = e.fold( a => UnprocessableEntity(a), b => Ok(b) ).map(_.withHeaders(headers: _*)) } implicit final class OptionResponse[A](o: Option[A]) { def toResponse( headers: Header* )(implicit F: Applicative[F], w0: EntityEncoder[F, A]): F[Response[F]] = o.map(a => Ok(a)).getOrElse(NotFound()).map(_.withHeaders(headers: _*)) } } object ResponseGenerator {}
Example 9
Source File: Tracer.scala From http4s-tracer with Apache License 2.0 | 5 votes |
package dev.profunktor.tracer import cats.Applicative import cats.data.Kleisli import cats.effect.Sync import cats.syntax.all._ import org.http4s.syntax.StringSyntax import org.http4s.{Header, HttpApp, Request} object Tracer extends StringSyntax { private[tracer] val DefaultTraceIdHeader = "Trace-Id" final case class TraceId(value: String) extends AnyVal { override def toString = s"[Trace-Id] - [$value]" } def apply[F[_]](implicit ev: Tracer[F]): Tracer[F] = ev def create[F[_]](headerName: String = DefaultTraceIdHeader): Tracer[F] = new Tracer[F](headerName) } class Tracer[F[_]] private (headerName: String) { import Trace._, Tracer._ def middleware( http: HttpApp[F], logRequest: Boolean = false, logResponse: Boolean = false )(implicit F: Sync[F], L: TracerLog[Trace[F, ?]]): HttpApp[F] = Kleisli { req => val createId: F[(Request[F], TraceId)] = for { id <- GenUUID.make[F] tr <- F.delay(req.putHeaders(Header(headerName, id.value))) } yield (tr, id) for { mi <- getTraceId(req) (tr, id) <- mi.fold(createId)(id => (req, id).pure[F]) _ <- if (logRequest) L.info[Tracer[F]](s"$req").run(id) else F.unit rs <- http(tr).map(_.putHeaders(Header(headerName, id.value))) _ <- if (logResponse) L.info[Tracer[F]](s"$rs").run(id) else F.unit } yield rs } def loggingMiddleware( http: HttpApp[F] )(implicit F: Sync[F], L: TracerLog[Trace[F, ?]]): HttpApp[F] = middleware(http, logRequest = true, logResponse = true) def getTraceId(request: Request[F])(implicit F: Applicative[F]): F[Option[TraceId]] = F.pure(request.headers.get(headerName.ci).map(h => TraceId(h.value))) }
Example 10
Source File: TestRoutes.scala From scala-server-lambda with MIT License | 5 votes |
package io.github.howardjohn.lambda.http4s import cats.{Applicative, MonadError} import cats.effect.Sync import cats.implicits._ import io.github.howardjohn.lambda.LambdaHandlerBehavior import io.github.howardjohn.lambda.LambdaHandlerBehavior._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, Header, HttpRoutes} import org.http4s.circe._ import io.circe.generic.auto._ import io.circe.syntax._ import org.http4s.dsl.impl.OptionalQueryParamDecoderMatcher class TestRoutes[F[_]] { object TimesQueryMatcher extends OptionalQueryParamDecoderMatcher[Int]("times") val dsl = Http4sDsl[F] import dsl._ def routes(implicit sync: Sync[F], jsonDecoder: EntityDecoder[F, JsonBody], me: MonadError[F, Throwable], stringDecoder: EntityDecoder[F, String], ap: Applicative[F]): HttpRoutes[F] = HttpRoutes.of[F] { case GET -> Root / "hello" :? TimesQueryMatcher(times) => Ok { Seq .fill(times.getOrElse(1))("Hello World!") .mkString(" ") } case GET -> Root / "long" => Applicative[F].pure(Thread.sleep(1000)).flatMap(_ => Ok("Hello World!")) case GET -> Root / "exception" => throw RouteException() case GET -> Root / "error" => InternalServerError() case req@GET -> Root / "header" => val header = req.headers.find(h => h.name.value == inputHeader).map(_.value).getOrElse("Header Not Found") Ok(header, Header(outputHeader, outputHeaderValue)) case req@POST -> Root / "post" => req.as[String].flatMap(s => Ok(s)) case req@POST -> Root / "json" => req.as[JsonBody].flatMap(s => Ok(LambdaHandlerBehavior.jsonReturn.asJson)) } }
Example 11
Source File: Http4sFullTracerTest.scala From guardrail with MIT License | 5 votes |
package core.Http4s import _root_.tracer.client.{ http4s => cdefs } import _root_.tracer.server.http4s.addresses.{ AddressesHandler, AddressesResource, GetAddressResponse, GetAddressesResponse } import _root_.tracer.server.http4s.users.{ GetUserResponse, UsersHandler, UsersResource } import _root_.tracer.server.{ http4s => sdefs } import _root_.tracer.client.http4s.users.UsersClient import _root_.tracer.client.http4s.addresses.AddressesClient import _root_.tracer.server.http4s.Http4sImplicits.TraceBuilder import cats.effect.IO import org.http4s.{ Header, HttpRoutes, Request } import org.http4s.client.Client import org.http4s.implicits._ import org.http4s.syntax.StringSyntax import org.scalatest.{ EitherValues, FunSuite, Matchers } class Http4sFullTracerTest extends FunSuite with Matchers with EitherValues with StringSyntax { val traceHeaderKey = "tracer-label" def log(line: String): Unit = () def trace: String => Request[IO] => TraceBuilder[IO] = { name => request => // In a real environment, this would be where you could establish a new // tracing context and inject that fresh header value. log(s"Expecting all requests to have ${traceHeaderKey} header.") traceBuilder(request.headers.get(traceHeaderKey.ci).get.value) } def traceBuilder(parentValue: String): TraceBuilder[IO] = { name => httpClient => Client { req => httpClient.run(req.putHeaders(Header(traceHeaderKey, parentValue))) } } test("full tracer: passing headers through multiple levels") { // Establish the "Address" server val server2: HttpRoutes[IO] = new AddressesResource(trace).routes( new AddressesHandler[IO] { def getAddress(respond: GetAddressResponse.type)(id: String)(traceBuilder: TraceBuilder[IO]) = IO.pure(if (id == "addressId") { respond.Ok(sdefs.definitions.Address(Some("line1"), Some("line2"), Some("line3"))) } else sdefs.addresses.GetAddressResponse.NotFound) def getAddresses(respond: GetAddressesResponse.type)()(traceBuilder: TraceBuilder[IO]) = IO.pure(sdefs.addresses.GetAddressesResponse.NotFound) } ) // Establish the "User" server val server1: HttpRoutes[IO] = new UsersResource(trace).routes( new UsersHandler[IO] { // ... using the "Address" server explicitly in the addressesClient val addressesClient = AddressesClient.httpClient(Client.fromHttpApp(server2.orNotFound)) def getUser(respond: GetUserResponse.type)(id: String)(traceBuilder: TraceBuilder[IO]) = addressesClient .getAddress(traceBuilder, "addressId") .map { case cdefs.addresses.GetAddressResponse.Ok(address) => respond.Ok(sdefs.definitions.User("1234", sdefs.definitions.UserAddress(address.line1, address.line2, address.line3))) case cdefs.addresses.GetAddressResponse.NotFound => respond.NotFound } } ) // Build a UsersClient using the User server val usersClient = UsersClient.httpClient(Client.fromHttpApp(server1.orNotFound)) // As this is the entry point, we either have a tracing header from // somewhere else, or we generate one for top-level request. val testTrace = traceBuilder("top-level-request") // Make a request against the mock servers using a hard-coded user ID val retrieved: cdefs.users.GetUserResponse = usersClient.getUser(testTrace, "1234").attempt.unsafeRunSync().right.value retrieved shouldBe cdefs.users.GetUserResponse .Ok(cdefs.definitions.User("1234", cdefs.definitions.UserAddress(Some("line1"), Some("line2"), Some("line3")))) } }
Example 12
Source File: Paginate.scala From github with MIT License | 5 votes |
package io.chrisdavenport.github.endpoints.utils import org.http4s.{Header, Uri} import cats.implicits._ def paginate(uri: Uri, numPages: Int): Map[Int, Header] = { (1 to numPages).map { currentPage => currentPage -> Header( "Link", List( prevPage(uri, currentPage), nextPage(uri, numPages, currentPage), lastPage(uri, numPages, currentPage), firstPage(uri, currentPage) ) .flatten .map { case (uri, rel) => s""" <${uri.toString}>; rel="$rel"""" }. mkString(",") ) }.toMap } private def firstPage(uri: Uri, page: Int): Option[(Uri, String)] = Option(page) .filterNot(_ == 1) .as((uri.withQueryParam[String, String]("page", "1"), "first")) private def prevPage(uri: Uri, page: Int): Option[(Uri, String)] = Option(page) .filterNot(_ == 1) .map { p => (uri.withQueryParam[String, String]("page", (p - 1).toString), "prev") } private def nextPage(uri: Uri, numPages: Int, page: Int): Option[(Uri, String)] = Option(page) .filterNot(_ == numPages) .map { p => (uri.withQueryParam[String, String]("page", (p + 1).toString), "next") } private def lastPage(uri: Uri, numPages: Int, page: Int): Option[(Uri, String)] = Option(page) .filterNot(_ == numPages) .as((uri.withQueryParam[String, String]("page", numPages.toString), "last")) }
Example 13
Source File: CorrelationIdMiddleware.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server.middleware import java.util.UUID import cats.data.{Kleisli, OptionT} import cats.effect.Sync import cats.syntax.functor._ import com.avast.sst.http4s.server.middleware.CorrelationIdMiddleware.CorrelationId import io.chrisdavenport.vault.Key import org.http4s.util.CaseInsensitiveString import org.http4s.{Header, HttpRoutes, Request, Response} import org.slf4j.LoggerFactory class CorrelationIdMiddleware[F[_]: Sync]( correlationIdHeaderName: CaseInsensitiveString, attributeKey: Key[CorrelationId], generator: () => String ) { private val logger = LoggerFactory.getLogger(this.getClass) private val F = Sync[F] def wrap(routes: HttpRoutes[F]): HttpRoutes[F] = Kleisli[OptionT[F, *], Request[F], Response[F]] { request => request.headers.get(correlationIdHeaderName) match { case Some(header) => val requestWithAttribute = request.withAttribute(attributeKey, CorrelationId(header.value)) routes(requestWithAttribute).map(r => r.withHeaders(r.headers.put(header))) case None => for { newCorrelationId <- OptionT.liftF(F.delay(generator())) _ <- log(newCorrelationId) requestWithAttribute = request.withAttribute(attributeKey, CorrelationId(newCorrelationId)) response <- routes(requestWithAttribute) } yield response.withHeaders(response.headers.put(Header(correlationIdHeaderName.value, newCorrelationId))) } } def retrieveCorrelationId(request: Request[F]): Option[CorrelationId] = request.attributes.lookup(attributeKey) private def log(newCorrelationId: String) = { OptionT.liftF { F.delay { if (logger.isDebugEnabled()) { logger.debug(s"Generated new correlation ID: $newCorrelationId") } } } } } object CorrelationIdMiddleware { final case class CorrelationId(value: String) extends AnyVal @SuppressWarnings(Array("scalafix:Disable.toString")) def default[F[_]: Sync]: F[CorrelationIdMiddleware[F]] = { Key.newKey[F, CorrelationId].map { attributeKey => new CorrelationIdMiddleware(CaseInsensitiveString("Correlation-ID"), attributeKey, () => UUID.randomUUID().toString) } } }
Example 14
Source File: CorrelationIdMiddlewareTest.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server.middleware import java.net.InetSocketAddress import cats.effect.{ContextShift, IO, Resource, Timer} import com.avast.sst.http4s.server.Http4sRouting import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.dsl.Http4sDsl import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.util.CaseInsensitiveString import org.http4s.{Header, HttpRoutes, Request, Uri} import org.scalatest.funsuite.AsyncFunSuite import scala.concurrent.ExecutionContext @SuppressWarnings(Array("scalafix:Disable.get", "scalafix:Disable.toString", "scalafix:Disable.createUnresolved")) class CorrelationIdMiddlewareTest extends AsyncFunSuite with Http4sDsl[IO] { implicit private val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) implicit private val timer: Timer[IO] = IO.timer(ExecutionContext.global) test("CorrelationIdMiddleware fills Request attributes and HTTP response header") { val test = for { middleware <- Resource.liftF(CorrelationIdMiddleware.default[IO]) routes = Http4sRouting.make { middleware.wrap { HttpRoutes.of[IO] { case req @ GET -> Root / "test" => val id = middleware.retrieveCorrelationId(req) Ok("test").map(_.withHeaders(Header("Attribute-Value", id.toString))) } } } server <- BlazeServerBuilder[IO](ExecutionContext.global) .bindSocketAddress(InetSocketAddress.createUnresolved("127.0.0.1", 0)) .withHttpApp(routes) .resource client <- BlazeClientBuilder[IO](ExecutionContext.global).resource } yield (server, client) test .use { case (server, client) => client .run( Request[IO](uri = Uri.unsafeFromString(s"http://${server.address.getHostString}:${server.address.getPort}/test")) .withHeaders(Header("Correlation-Id", "test-value")) ) .use { response => IO.delay { assert(response.headers.get(CaseInsensitiveString("Correlation-Id")).get.value === "test-value") assert(response.headers.get(CaseInsensitiveString("Attribute-Value")).get.value === "Some(CorrelationId(test-value))") } } } .unsafeToFuture() } }
Example 15
Source File: KmsCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.kms import cats.effect.Effect import cats.implicits._ import io.circe.{Decoder, Json} import org.aws4s.core.ExtraEntityDecoderInstances._ import org.aws4s._ import org.aws4s.core.{Command, CommandPayload, RenderedParam, ServiceName} import org.http4s.circe._ import org.http4s.headers.{Host, `Content-Type`} import org.http4s.{Header, Headers, MediaType, Method, Request, Uri} private[kms] abstract class KmsCommand[F[_]: Effect, R: Decoder] extends Command[F, Json, R] { override def serviceName: ServiceName = ServiceName.Kms override def payloadSigning: PayloadSigning = PayloadSigning.Signed def action: String override final val requestGenerator: List[RenderedParam[Json]] => F[Request[F]] = { params => val host = s"kms.${region.name}.amazonaws.com" val payload: Json = CommandPayload.jsonObject(params) Request[F]( Method.POST, Uri.unsafeFromString(s"https://$host/"), headers = Headers(Header("X-Amz-Target", s"TrentService.$action"), Host(host)) ).withBody(payload).map(_.withContentType(`Content-Type`.apply(MediaType.fromKey(("application", "x-amz-json-1.1"))))) } }
Example 16
Source File: DynamoDbCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.dynamodb import cats.effect.Effect import io.circe.{Decoder, Json} import org.aws4s.PayloadSigning import org.http4s.headers.{Host, `Content-Type`} import org.http4s.{Header, Headers, MediaType, Method, Request, Uri} import org.http4s.circe._ import cats.implicits._ import org.aws4s.core.ExtraEntityDecoderInstances._ import org.aws4s.core.{Command, CommandPayload, RenderedParam, ServiceName} private[dynamodb] abstract class DynamoDbCommand[F[_]: Effect, R: Decoder] extends Command[F, Json, R] { override def serviceName: ServiceName = ServiceName.DynamoDb override def payloadSigning: PayloadSigning = PayloadSigning.Signed def action: String override final val requestGenerator: List[RenderedParam[Json]] => F[Request[F]] = params => { val host = s"dynamodb.${region.name}.amazonaws.com" val payload: Json = CommandPayload.jsonObject(params) Request[F]( Method.POST, Uri.unsafeFromString(s"https://$host/"), headers = Headers(Header("X-Amz-Target", s"DynamoDB_20120810.$action"), Host(host)) ).withBody(payload).map(_.withContentType(`Content-Type`.apply(MediaType.fromKey(("application", "x-amz-json-1.0"))))) } }