=htc simplify content negotiation
This commit is contained in:
parent
d5d8c21091
commit
a1d7c33663
1 changed files with 16 additions and 21 deletions
|
|
@ -43,32 +43,27 @@ class Marshal[A](val value: A) {
|
|||
def qValueCS(charset: HttpCharset) = request.qValueForCharset(charset, charsetRanges)
|
||||
|
||||
m(value).fast.map { marshallings ⇒
|
||||
def weight(mt: MediaType, cs: HttpCharset): Float = math.min(qValueMT(mt), qValueCS(cs))
|
||||
val defaultMarshallingWeight: MarshallingWeight =
|
||||
new MarshallingWeight(0f, { () ⇒
|
||||
val supportedContentTypes = marshallings collect {
|
||||
case Marshalling.WithFixedCharset(mt, cs, _) ⇒ ContentType(mt, cs)
|
||||
case Marshalling.WithOpenCharset(mt, _) ⇒ ContentType(mt)
|
||||
}
|
||||
throw UnacceptableResponseContentTypeException(supportedContentTypes.toSet)
|
||||
})
|
||||
val defaultMarshallingWeight = new MarshallingWeight(0f, { () ⇒
|
||||
val supportedContentTypes = marshallings collect {
|
||||
case Marshalling.WithFixedCharset(mt, cs, _) ⇒ ContentType(mt, cs)
|
||||
case Marshalling.WithOpenCharset(mt, _) ⇒ ContentType(mt)
|
||||
}
|
||||
throw UnacceptableResponseContentTypeException(supportedContentTypes.toSet)
|
||||
})
|
||||
def choose(acc: MarshallingWeight, mt: MediaType, cs: HttpCharset, marshal: () ⇒ HttpResponse) = {
|
||||
val weight = math.min(qValueMT(mt), qValueCS(cs))
|
||||
if (weight > acc.weight) new MarshallingWeight(weight, marshal) else acc
|
||||
}
|
||||
val best = marshallings.foldLeft(defaultMarshallingWeight) {
|
||||
case (acc, Marshalling.WithFixedCharset(mt, cs, marshal)) ⇒
|
||||
val w = weight(mt, cs)
|
||||
if (w > acc.weight) new MarshallingWeight(w, marshal) else acc
|
||||
|
||||
choose(acc, mt, cs, marshal)
|
||||
case (acc, Marshalling.WithOpenCharset(mt, marshal)) ⇒
|
||||
def withCharset(cs: HttpCharset) = {
|
||||
val w = weight(mt, cs)
|
||||
if (w > acc.weight) new MarshallingWeight(w, () ⇒ marshal(cs)) else acc
|
||||
}
|
||||
def withCharset(cs: HttpCharset) = choose(acc, mt, cs, () ⇒ marshal(cs))
|
||||
// logic for choosing the charset adapted from http://tools.ietf.org/html/rfc7231#section-5.3.3
|
||||
if (qValueCS(`UTF-8`) == 1f) withCharset(`UTF-8`) // prefer UTF-8 if fully accepted
|
||||
else charsetRanges match { // ranges are sorted by descending q-value,
|
||||
case (HttpCharsetRange.One(cs, qValue)) :: _ ⇒ // so we only need to look at the first one
|
||||
if (qValue == 1f) withCharset(cs) // if the client has high preference for this charset, pick it
|
||||
else if (qValue > 0f) withCharset(cs) // ok, simply choose the first one if the client doesn't reject it
|
||||
else acc
|
||||
else charsetRanges match {
|
||||
// pick the charset which the highest q-value (head of charsetRanges) if it isn't explicitly rejected
|
||||
case (HttpCharsetRange.One(cs, qValue)) :: _ if qValue > 0f ⇒ withCharset(cs)
|
||||
case _ ⇒ acc
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue