How to match specific accept headers in a route?

2019-05-07 05:08发布

问题:

I want to create a route that matches only if the client sends a specific Accept header. I use Spray 1.2-20130822.

I'd like to get the route working:

def receive = runRoute {
    get {
      path("") {
        accept("application/json") {
           complete(...)
        }
      }
    }
  }

Here I found a spec using an accept() function, but I can't figure out what to import in my Spray-Handler to make it work as directive. Also, I did not find other doc on header directives but these stubs.

回答1:

I would do this way:

def acceptOnly(mr: MediaRange*): Directive0 =
  extract(_.request.headers).flatMap[HNil] {
    case headers if headers.contains(Accept(mr)) ⇒ pass
    case _                                       ⇒ reject(MalformedHeaderRejection("Accept", s"Only the following media types are supported: ${mr.mkString(", ")}"))
  } & cancelAllRejections(ofType[MalformedHeaderRejection])

Then just wrap your root:

path("") {
  get {
    acceptOnly(`application/json`) {
      session { creds ⇒
        complete(html.page(creds))
      }
    }
  }
}

And by the way the latest spray 1.2 nightly is 1.2-20130928 if you can, update it



回答2:

There is no pre-defined directive called accept directive. You can see the full list of available directives here.

However, you can use the headerValueByName directive to make a custom directive that does what you desire:

def accept(required: String) = headerValueByName("Accept").flatMap {
  case actual if actual.split(",").contains(required) => pass
  case _ => reject(MalformedHeaderRejection("Accept", "Accept must be equal to " + required))
}

Put this code in scope of your spray Route, then just use as you have shown in your question.



标签: scala spray