akka.http.scaladsl.model.HttpHeader.ParsingResult Scala Examples
The following examples show how to use akka.http.scaladsl.model.HttpHeader.ParsingResult.
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: HttpRequestConversionSupport.scala From rokku with Apache License 2.0 | 5 votes |
package com.ing.wbaa.rokku.proxy.persistence.serializers import java.net.InetAddress import akka.http.scaladsl.model.HttpHeader.ParsingResult import akka.http.scaladsl.model.{ HttpEntity, HttpHeader, HttpMethod, HttpMethods, HttpProtocol, HttpRequest, RemoteAddress, Uri } import com.ing.wbaa.rokku.proxy.data.{ UserAssumeRole, UserRawJson } import spray.json.DefaultJsonProtocol import scala.collection.immutable trait HttpRequestConversionSupport extends DefaultJsonProtocol { case class SimplifiedRemoteAddress(host: String) { def toRemoteAddr: RemoteAddress = { val a = host.split(":") RemoteAddress(InetAddress.getByName(a(0)), Some(a(1).toInt)) } } case class SimplifiedHttpRequest(method: String, uri: String, headers: List[String], entity: String, httpProtocol: String) implicit val httpRequestF = jsonFormat5(SimplifiedHttpRequest) implicit val userRoleF = jsonFormat1(UserAssumeRole) implicit val userSTSF = jsonFormat5(UserRawJson) implicit val remoteAddressF = jsonFormat1(SimplifiedRemoteAddress) private[persistence] def convertAkkaHeadersToStrings(headers: Seq[HttpHeader]): List[String] = headers.map(h => s"${h.name()}=${h.value()}").toList private def convertStringsToAkkaHeaders(headers: List[String]): immutable.Seq[HttpHeader] = headers.map { p => val kv = p.split("=") HttpHeader.parse(kv(0), kv(1)) match { case ParsingResult.Ok(header, _) => header case ParsingResult.Error(error) => throw new Exception(s"Unable to convert to HttpHeader: ${error.summary}") } } private def httpMethodFrom(m: String): HttpMethod = m match { case "GET" => HttpMethods.GET case "HEAD" => HttpMethods.HEAD case "PUT" => HttpMethods.PUT case "POST" => HttpMethods.POST case "DELETE" => HttpMethods.DELETE } private[persistence] def toAkkaHttpRequest(s: SimplifiedHttpRequest): HttpRequest = HttpRequest( httpMethodFrom(s.method), Uri(s.uri), convertStringsToAkkaHeaders(s.headers), HttpEntity(s.entity), HttpProtocol(s.httpProtocol) ) }
Example 2
Source File: HttpRequestRecorderSpec.scala From rokku with Apache License 2.0 | 5 votes |
package com.ing.wbaa.rokku.proxy.persistence import java.net.InetAddress import akka.actor.{ ActorSystem, PoisonPill, Props } import akka.http.scaladsl.model.HttpHeader.ParsingResult import akka.http.scaladsl.model._ import akka.testkit.{ ImplicitSender, TestKit } import com.ing.wbaa.rokku.proxy.data._ import com.ing.wbaa.rokku.proxy.persistence.HttpRequestRecorder.{ ExecutedRequestCmd, LatestRequests, LatestRequestsResult } import org.scalatest.BeforeAndAfterAll import org.scalatest.diagrams.Diagrams import org.scalatest.wordspec.AnyWordSpecLike import scala.collection.immutable class HttpRequestRecorderSpec extends TestKit(ActorSystem("RequestRecorderTest")) with ImplicitSender with AnyWordSpecLike with Diagrams with BeforeAndAfterAll { override def afterAll: Unit = { TestKit.shutdownActorSystem(system) } private def convertStringsToAkkaHeaders(headers: List[String]): immutable.Seq[HttpHeader] = headers.map { p => val kv = p.split("=") HttpHeader.parse(kv(0), kv(1)) match { case ParsingResult.Ok(header, _) => header case ParsingResult.Error(error) => throw new Exception(s"Unable to convert to HttpHeader: ${error.summary}") } } val requestRecorder = system.actorOf(Props(classOf[HttpRequestRecorder]), "localhost-1") val headers = List("Remote-Address=0:0:0:0:0:0:0:1:58170", "Host=localhost:8987", "X-Amz-Content-SHA256=02502914aca52472205417e4c418ee499ba39ca1b283d99da26e295df2eccf32", "User-Agent=aws-cli/1.16.30 Python/2.7.5 Linux/3.10.0-862.14.4.el7.x86_64 botocore/1.12.20", "Content-MD5=Wf7l+rCPsVw8eqc34kVJ1g==", "Authorization=AWS4-HMAC-SHA256 Credential=6r24619bHVWvrxR5AMHNkGZ6vNRXoGCP/20190704/us-east-1/s3/aws4_request", "SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date;x-amz-security-token", "Signature=271dda503da6fcf04cc058cb514b28a6d522a9b712ab553bfb88fb7814ab082f") val httpRequest = HttpRequest( HttpMethods.PUT, Uri("http://127.0.0.1:8010/home/testuser/file34"), convertStringsToAkkaHeaders(headers), HttpEntity.Empty.withContentType(ContentTypes.`application/octet-stream`).toString(), HttpProtocols.`HTTP/1.1` ) val userSTS = User(UserName("okUser"), Set(UserGroup("okGroup")), AwsAccessKey("accesskey"), AwsSecretKey("secretkey"), UserAssumeRole("")) val clientIPAddress = RemoteAddress(InetAddress.getByName("localhost"), Some(1234)) "RequestRecorder" should { "persist Http request event" in { requestRecorder ! ExecutedRequestCmd(httpRequest, userSTS, clientIPAddress) requestRecorder ! LatestRequests(1) expectMsg(LatestRequestsResult(List(ExecutedRequestEvt(httpRequest, userSTS, clientIPAddress)))) requestRecorder ! PoisonPill val requestRecorder1 = system.actorOf(Props(classOf[HttpRequestRecorder]), "localhost-2") requestRecorder1 ! LatestRequests(1) expectMsg(LatestRequestsResult(List(ExecutedRequestEvt(httpRequest, userSTS, clientIPAddress)))) } } }
Example 3
Source File: AkkaHttpLambdaHandler.scala From scala-server-lambda with MIT License | 5 votes |
package io.github.howardjohn.lambda.akka import akka.actor.ActorSystem import akka.http.scaladsl.model.HttpHeader.ParsingResult import akka.http.scaladsl.model._ import akka.http.scaladsl.server.Route import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.ActorMaterializer import akka.stream.scaladsl.{Keep, Sink, Source} import io.github.howardjohn.lambda.ProxyEncoding._ import io.github.howardjohn.lambda.{LambdaHandler, ProxyEncoding} import scala.concurrent.duration.Duration import scala.concurrent.{Await, ExecutionContext, Future} class AkkaHttpLambdaHandler(route: Route)( implicit system: ActorSystem, materializer: ActorMaterializer, ec: ExecutionContext ) extends LambdaHandler { import AkkaHttpLambdaHandler._ override def handleRequest(request: ProxyRequest): ProxyResponse = Await.result(runRequest(proxyToAkkaRequest(request)), Duration.Inf) private def runRequest(request: HttpRequest): Future[ProxyResponse] = { val source = Source.single(request) val sink = Sink.head[HttpResponse] source .via(route) .toMat(sink)(Keep.right) .run() .flatMap(asProxyResponse) } private def proxyToAkkaRequest(request: ProxyRequest): HttpRequest = new HttpRequest( method = parseHttpMethod(request.httpMethod), uri = Uri(ProxyEncoding.reconstructPath(request)), headers = parseRequestHeaders(request.headers.getOrElse(Map.empty)), entity = parseEntity(request.headers.getOrElse(Map.empty), request.body), protocol = HttpProtocols.`HTTP/1.1` ) private def parseEntity(headers: Map[String, String], body: Option[String]): MessageEntity = { val defaultContentType = ContentTypes.`text/plain(UTF-8)` val contentType = ContentType .parse(headers.getOrElse("Content-Type", defaultContentType.value)) .getOrElse(defaultContentType) body match { case Some(b) => HttpEntity(contentType, b.getBytes) case None => HttpEntity.empty(contentType) } } private def asProxyResponse(resp: HttpResponse): Future[ProxyResponse] = Unmarshal(resp.entity) .to[String] .map { body => ProxyResponse( resp.status.intValue(), resp.headers.map(h => h.name -> h.value).toMap, body ) } } private object AkkaHttpLambdaHandler { private def parseRequestHeaders(headers: Map[String, String]): List[HttpHeader] = headers.map { case (k, v) => HttpHeader.parse(k, v) match { case ParsingResult.Ok(header, _) => header case ParsingResult.Error(err) => throw new RuntimeException(s"Failed to parse header $k:$v with error $err.") } }.toList private def parseHttpMethod(method: String) = method.toUpperCase match { case "CONNECT" => HttpMethods.CONNECT case "DELETE" => HttpMethods.DELETE case "GET" => HttpMethods.GET case "HEAD" => HttpMethods.HEAD case "OPTIONS" => HttpMethods.OPTIONS case "PATCH" => HttpMethods.PATCH case "POST" => HttpMethods.POST case "PUT" => HttpMethods.PUT case "TRACE" => HttpMethods.TRACE case other => HttpMethod.custom(other) } }
Example 4
Source File: AkkaHttpClient.scala From graphql-gateway with Apache License 2.0 | 5 votes |
package sangria.gateway.http.client import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.HttpHeader.ParsingResult import akka.http.scaladsl.model._ import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model.headers.Location import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import akka.util.ByteString import sangria.gateway.util.Logging import scala.concurrent.{ExecutionContext, Future} class AkkaHttpClient(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext) extends HttpClient with Logging { import AkkaHttpClient._ import HttpClient._ override def request(method: Method.Value, url: String, queryParams: Seq[(String, String)] = Seq.empty, headers: Seq[(String, String)] = Seq.empty, body: Option[(String, String)] = None) = { val m = mapMethod(method) val query = Query(queryParams: _*) val hs = headers.map(header) val uri = Uri(url).withQuery(query) val entity = body.fold(HttpEntity.Empty){case (tpe, content) ⇒ HttpEntity(contentType(tpe), ByteString(content))} val request = HttpRequest(m, uri, hs.toVector, entity) val client = Http().singleRequest(_: HttpRequest) val richClient = RichHttpClient.httpClientWithRedirect(client) logger.debug(s"Http request: ${m.value} $url") richClient(request).map(AkkaHttpResponse(m, url, _)) } override def oauthClientCredentials(url: String, clientId: String, clientSecret: String, scopes: Seq[String]): Future[HttpResponse] = throw new IllegalStateException("Not yet implemented, please use play implementation.") private def contentType(str: String) = ContentType.parse(str).fold( errors ⇒ throw ClientError(s"Invalid content type '$str'", errors.map(_.detail)), identity) private def header(nameValue: (String, String)) = HttpHeader.parse(nameValue._1, nameValue._2) match { case ParsingResult.Ok(_, errors) if errors.nonEmpty ⇒ throw ClientError(s"Invalid header '${nameValue._1}'", errors.map(_.detail)) case ParsingResult.Error(error) ⇒ throw ClientError(s"Invalid header '${nameValue._1}'", Seq(error.detail)) case ParsingResult.Ok(h, _) ⇒ h } def mapMethod(method: Method.Value) = method match { case Method.Get ⇒ HttpMethods.GET case Method.Post ⇒ HttpMethods.POST } object RichHttpClient { import akka.http.scaladsl.model.HttpResponse type HttpClient = HttpRequest ⇒ Future[HttpResponse] def redirectOrResult(client: HttpClient)(response: HttpResponse): Future[HttpResponse] = response.status match { case StatusCodes.Found | StatusCodes.MovedPermanently | StatusCodes.SeeOther ⇒ val newUri = response.header[Location].get.uri // Always make sure you consume the response entity streams (of type Source[ByteString,Unit]) by for example connecting it to a Sink (for example response.discardEntityBytes() if you don’t care about the response entity), since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection! response.discardEntityBytes() logger.debug(s"Http redirect: ${HttpMethods.GET.value} $newUri") client(HttpRequest(method = HttpMethods.GET, uri = newUri)) case _ ⇒ Future.successful(response) } def httpClientWithRedirect(client: HttpClient): HttpClient = { lazy val redirectingClient: HttpClient = req ⇒ client(req).flatMap(redirectOrResult(redirectingClient)) // recurse to support multiple redirects redirectingClient } } case class ClientError(message: String, errors: Seq[String]) extends Exception(message + ":\n" + errors.map(" * " + _).mkString("\n")) } object AkkaHttpClient { case class AkkaHttpResponse(method: HttpMethod, url: String, response: HttpResponse)(implicit mat: Materializer) extends HttpClient.HttpResponse { def asString = Unmarshal(response).to[String] def statusCode = response.status.intValue() def isSuccessful = response.status.isSuccess() def debugInfo = s"${method.value} $url" } }