gpt4 book ai didi

scala - Akka-http中获取客户端IP

转载 作者:行者123 更新时间:2023-12-04 18:02:56 27 4
gpt4 key购买 nike

我正在尝试编写一个 Akka HTTP 微服务(akka 版本 2.4.11,Scala 版本 2.11.8,在撰写本文时都是最新版本),它知道客户端服务的 IP(即远程地址),但我无法得到这个上类。

我可以创建并运行一个显示“你好!”的服务使用这样的路线:

    val routeHello: Route = path("SayHello") {
get {
entity(as[String]) {
body => complete {
HttpResponse(entity = HttpEntity("Hello!"))
}
}
}
}

我已经构建了一个与上面类似的路由,它被扩展以便知道客户端的 IP 地址。

我注意到我需要编辑 application.conf 文件并设置 'remote-address-header = on' 以启用添加 Remote-Address包含客户端(远程)IP 地址的 header 。我已经这样做了,以防万一。

这是路线:
    val routeHelloIp: Route = path("SayHelloIp") {
get {
// extractClientIp appears to be working as a filter
// instead of an extractor - why?
extractClientIp {
clientIp => {
entity(as[String]) {
body => complete {
HttpResponse(entity = HttpEntity("Hello!"))
}
}
}
}
}
}

但是,当我运行这条路线时,我收到一条消息“找不到请求的资源。”。

看起来我在上面的例子中弄错了 Akka-http DSL 语法糖。如果您能让我走上正确的道路,我将不胜感激!

编辑:

我已经尝试了以下程序来响应 Ramon 的有用回答。不幸的是它不能编译,我看不出我需要做什么才能编译它。
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.IncomingConnection
import java.net.InetSocketAddress
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import akka.http.scaladsl.server.Directives._
import java.net.InetSocketAddress


object TestHttp {
def main(args: Array[String]) {

implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()

// allow connections from any IP
val interface = "0.0.0.0"

//from the question
def createRoute(address: InetSocketAddress) = path("SayHelloIp") {
get {
extractRequestEntity { entity =>
entity(as[String]) { body =>
complete(entity = s"Hello ${address.getAddress().getHostAddress()}")
}
}
}
}

Http().bind(interface).runWith(Sink foreach { conn =>
val address = conn.remoteAddress
conn.handleWithAsyncHandler(createRoute(address))
})
}
}

我有以下 build.sbt 以确保使用最新版本的 Scala 和 akka-http:
import sbt.Keys._

name := "Find my IP"

version := "1.0"

scalaVersion := "2.11.8"

resolvers ++= Seq(
"Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
)

libraryDependencies ++= {
Seq(
"com.typesafe.akka" %% "akka-actor" % "2.4.11",
"com.typesafe.akka" %% "akka-stream" % "2.4.11",
"com.typesafe.akka" %% "akka-http-experimental" % "2.4.11",
"com.typesafe.akka" %% "akka-http-core" % "2.4.11"
)
}

我收到以下编译时错误:
[error] /Users/tilopa/temp/akka-test/src/main/scala/Test.scala:24: akka.http.scaladsl.model.RequestEntity does not take parameters
[error] entity(as[String]) { body =>
[error] ^
[error] /Users/tilopa/temp/akka-test/src/main/scala/Test.scala:25: reassignment to val
[error] complete(entity = s"Hello ${address.getAddress().getHostAddress()}")
[error] ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed

最佳答案

使用 extractClientIp
extractClientIp对您不起作用,因为发件人未指定必需的 header 字段之一。来自 documentation :

Provides the value of X-Forwarded-For, Remote-Address, or X-Real-IP headers as an instance of RemoteAddress.



您只需要在发件人中打开正确的设置:

The akka-http server engine adds the Remote-Address header to every request automatically if the respective setting akka.http.server.remote-address-header is set to on. Per default it is set to off.



通用解决方案

如果您希望它适用于任何 HttpRequest,而不仅仅是具有正确 header 设置的那些,那么您必须使用 bind HttpExt 上的方法而不是 bindAndHandle :
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.IncomingConnection

import java.net.InetSocketAddress

implicit val actorSystem : ActorSystem = ???
implicit val actorMat = ActorMaterializer()


//alow connections from any IP
val interface = "0.0.0.0"

//from the question
def createRoute(address : InetSocketAddress) = path("SayHelloIp") {
get {
extractRequestEntity { entity =>
entity(as[String]) { body =>
complete(entity = s"Hello ${address.getAddress().getHostAddress()}")
}
}
}
}

Http().bind(interface).runWith(Sink foreach { conn =>
val address = conn.remoteAddress

conn.handleWithAsyncHandler(createRoute(address))
})

编辑

如评论中所述:自 akka 10.0.13使用 conn.handleWith .

关于scala - Akka-http中获取客户端IP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40132262/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com