Skip to content

Commit

Permalink
Try and fix websocket on firefox. Almost certainly not perfect.
Browse files Browse the repository at this point in the history
  • Loading branch information
bryce-anderson committed Jun 6, 2014
1 parent dee6f09 commit f9d0738
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ object ServerHandshaker {
def handshakeHeaders(headers: TraversableOnce[(String, String)]): Either[(Int, String), Seq[(String, String)]] = {
if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Host")}) {
Left(-1, "Missing Host Header")
} else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Connection") && v.equalsIgnoreCase("Upgrade")}) {
} else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Connection") && valueContains("Upgrade", v)}) {
Left(-1, "Bad Connection header")
}else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Upgrade") && v.equalsIgnoreCase("websocket") }) {
} else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Upgrade") && v.equalsIgnoreCase("websocket") }) {
Left(-1, "Bad Upgrade header")
} else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Sec-WebSocket-Version") && v == "13" }) {
} else if (!headers.exists { case (k, v) => k.equalsIgnoreCase("Sec-WebSocket-Version") && valueContains("13", v) }) {
Left(-1, "Bad Websocket Version header")
} else headers.find{case (k, v) =>
} // we are past most of the 'just need them' headers
else headers.find{case (k, v) =>
k.equalsIgnoreCase("Sec-WebSocket-Key") && keyLength(v) == 16
}.map { case (_, v) =>
Right(Seq(("Upgrade", "websocket"),("Connection", "Upgrade"),("Sec-WebSocket-Accept", genAcceptKey(v))))
val respHeaders = Seq(("Upgrade", "websocket"),
("Connection", "Upgrade"),
("Sec-WebSocket-Accept", genAcceptKey(v)))

Right(respHeaders)
}.getOrElse(Left(-1, "Bad Sec-WebSocket-Key header"))
}

Expand All @@ -41,5 +46,16 @@ object ServerHandshaker {
printBase64Binary(bytes)
}

private[websocket] def valueContains(key: String, value: String): Boolean = {
val parts = value.split(",").map(_.trim)
parts.foldLeft(false)( (b,s) => b || {
s.equalsIgnoreCase(key) ||
s.length > 1 &&
s.startsWith("\"") &&
s.endsWith("\"") &&
s.substring(1, s.length - 1).equalsIgnoreCase(key)
})
}

private[ServerHandshaker] val magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(US_ASCII)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.http4s.blaze.http.websocket

import org.specs2.mutable.Specification

/**
* Created by Bryce Anderson on 6/5/14.
*/
class WebsocketHandshakeSpec extends Specification {

"WebsocketHandshake" should {

"Be able to split multi value header keys" in {
val totalValue = "keep-alive, Upgrade"
val values = List("upgrade", "Upgrade", "keep-alive", "Keep-alive")
values.foldLeft(true){ (b, v) =>
b && ServerHandshaker.valueContains(v, totalValue)
} should_== true
}

}

}

0 comments on commit f9d0738

Please sign in to comment.