是否有可能编写一个指令来匹配“任何其他查询参数”?

时间:2014-03-03 17:59:48

标签: scala spray spray-dsl

为确保人们不附加随机查询参数(例如附加&r=234522.123或类似内容)以避免命中我们的缓存,我希望有办法拒绝任何未明确处理的查询。我当然可以创建一个包含白名单的内容,但是必须单独维护,我讨厌维护需要保持同步的两件事。 (尽管如此,它有助于更​​快地失败。)喷涂路由是否可行?

3 个答案:

答案 0 :(得分:1)

我最终得到了这个:

// This contains a white-list of allowed query parameters. This is useful to
// ensure people don't try to use &r=234234 to bust your caches.
def allowedParameters(params: String*): Directive0 = parameterSeq.flatMap {
  case xs =>
    val illegal = xs.collect {
      case (k, _) if !params.contains(k) => k
    }
    if (illegal.nonEmpty)
      reject(ValidationRejection("Illegal query parameters: " + illegal.mkString("", ", ", "\nAllowed ones are: ") + params.mkString(", ")))
    else
      pass
}

如需使用,请查看单元测试:

val allowedRoute = {
  allowedParameters("foo", "bar") {
    complete("OK")
  }
}

"Allowed Parameter Directive" should "reject parameters not in its whitelist" in {
  Get("/?foo&bar&quux") ~> allowedRoute ~> check {
    handled should equal(false)
    rejection should be(ValidationRejection("Illegal query parameters: quux\nAllowed ones are: foo, bar"))
  }
}

it should "allow properly sorted parameters through" in {
  Get("/?bar&foo") ~> allowedRoute ~> check {
    handled should equal(true)
    responseAs[String] should equal("OK")
  }
}

答案 1 :(得分:1)

实际上,你有一个很好的解决方案,我只能建议一个小的重构:

def only(params: String*): Directive0 = {
  def check: Map[String, String] => Boolean = _.keySet diff params.toSet isEmpty
  parameterMap.require(check, rejection)
}

你可以把它写成一个单行,但它会更长

答案 2 :(得分:-2)

使用这样的路线:

val myRoute = {
  ...
  pathPrefix("test") {
    parameter("good") {
      good =>
        complete("GOOD")
    }
  } ~
 ...
}

Spray将要求第一个参数为good并具有值,即?good=value。不允许其他具有值的参数。