2017-03-02 169 views
1

不添加远程地址根据阿卡-HTTP extractClientIPDocumentation阿卡-HTTP的请求头

的阿卡http服务器引擎将自动添加远程地址头球每个 请求,如果相应的设置为 akka.http.server.remote-address-header设置为on。默认情况下,它是 设置为关闭。

的application.conf已设定相应

akka { 
    http { 
    server { 
     remote-address-header = on 
    } 
    } 
} 

下面的测试失败,以从请求中提取报头Remote-Address

import akka.http.scaladsl.server.Route 
import akka.http.scaladsl.client.RequestBuilding 
import akka.http.scaladsl.model._ 
import akka.http.scaladsl.testkit.ScalatestRouteTest 

"Remote-Address added to request header by akka-http" in { 
    val request = RequestBuilding.Get("/").withHeaders(`User-Agent`(this.getClass.getSimpleName)) 
    val miniRoute: Route = { ctx => ctx.complete("Always Succeed") } 

    request ~> miniRoute ~> check { 
    assert(responseAs[String] == "Always Succeed") 
    } 

    //confirm akka config setting is correct 
    assert(ConfigFactory.load().getString("akka.http.server.remote-address-header") == "on", "FAILED: please set application.conf: akka.http.server.remote-address-header = on") 

    val remoteIP: Option[HttpHeader] = request.headers.find(_.name == "Remote-Address") 
    assert(remoteIP.nonEmpty, "FAILED: Remote-Address missing in Request Headers") 
} 

问题应该阿卡-HTTP注入自动Remote-Address在请求标头中?另外,我会很感激,如果你能展示如何重写这个测试的akka.http.server.remote-address-header配置可以编程设置。

回答

1

您正面临此问题,因为testkit的ScalatestRouteTest不会自动添加Remote-Address。它只发生在Http()对象级别(有关更多详细信息,请参见source)。

如果你想看到它在行动,你可以旋转起来在运行

object Tmp extends App { 
    implicit val sys = ActorSystem("tmp") 
    implicit val mat = ActorMaterializer() 

    val route = headerValueByName("Remote-Address") { complete(_) } 

    Http().bindAndHandle(route, "localhost", 8080) 
} 

,并根据您的配置(这是正确的在你的问题),你应该得到一个服务器或者200 OK(如果设置为on )或400 Bad Request(如果设置为off)。

0

按照你的意见,我做了下面的测试,按预期工作。希望这对其他人有用。

import akka.http.scaladsl.Http 
import akka.stream.ActorMaterializer 
import akka.http.scaladsl.server.directives.{HeaderDirectives, RouteDirectives} 
import com.typesafe.config.ConfigFactory 

/** Verify that akka-http engine injects the "Remote-Address" header in the request headers 
    * if the config key "akka.http.server.remote-address-header = on" 
    * 
    * TESTING (set config on/off via command line argument) 
    * 1. Run the mini web server 
    * sbt "runMain blabla.AkkaRemoteAddressTest on" 
    * 
    * 2. Open Git-Bash and type: 
    * $ curl -s http://localhost:2017 
    *  (console output) Remote-Address = 127.0.0.1:58208 (Thursday, 02 Mar 2017 - 18:54:55) 
    * $ curl -s http://$COMPUTERNAME:2017 
    *  (console output) Remote-Address = 10.5.34.101:58285 (Thursday, 02 Mar 2017 - 18:57:30) 
    */ 
object AkkaRemoteAddressTest { 
    def main(args: Array[String]): Unit = { 
    val configValue = 
     if (args.isEmpty) "on" 
     else if (args(0).toLowerCase != "on" && args(0).toLowerCase != "off") "on" 
     else args(0) 

    val miniConfig = ConfigFactory.parseString(
     s""" 
     |akka.http.server.remote-address-header = $configValue 
     """.stripMargin) 

    implicit val sys = ActorSystem("AkkaRemoteAddressTest", miniConfig) 
    implicit val mat = ActorMaterializer() 

    val sdfmt = new java.text.SimpleDateFormat("EEEE, dd MMM yyyy - HH:mm:ss") 

    val route = HeaderDirectives.headerValueByName("Remote-Address") { 
     remaddr => RouteDirectives.complete(s"Remote-Address = $remaddr (${sdfmt.format(java.util.Calendar.getInstance.getTime)})") 
    } 

    Http().bindAndHandle(route, "0.0.0.0", 2017) 
    } 
}