diff options
author | Mike Buland <mbuland@penny-arcade.com> | 2019-07-29 07:37:10 -0700 |
---|---|---|
committer | Mike Buland <mbuland@penny-arcade.com> | 2019-07-29 07:37:10 -0700 |
commit | af4bc8816eb4b4cb4821b24706f55b518a43968d (patch) | |
tree | 23d599d050a6483cf4132f6a763c6222f69e36f9 | |
parent | 76649ebc55a243882ba6ac981f41c1d007b6f63a (diff) | |
download | libbu++-af4bc8816eb4b4cb4821b24706f55b518a43968d.tar.gz libbu++-af4bc8816eb4b4cb4821b24706f55b518a43968d.tar.bz2 libbu++-af4bc8816eb4b4cb4821b24706f55b518a43968d.tar.xz libbu++-af4bc8816eb4b4cb4821b24706f55b518a43968d.zip |
ProtocolWebSocket checked headers case sensitive.
In theory that should be fine, the standard stipulates case, but headers
should be case insensitive in most cases, so now we're more compatible.
Amusingly, browsers and other clients did it correctly, apache doesn't.
-rw-r--r-- | src/unstable/protocolwebsocket.cpp | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/src/unstable/protocolwebsocket.cpp b/src/unstable/protocolwebsocket.cpp index 30997a9..8d4a124 100644 --- a/src/unstable/protocolwebsocket.cpp +++ b/src/unstable/protocolwebsocket.cpp | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | 23 | ||
24 | #define DEBUG( X ) { } (void)0 | ||
25 | |||
24 | Bu::ProtocolWebSocket::ProtocolWebSocket() : | 26 | Bu::ProtocolWebSocket::ProtocolWebSocket() : |
25 | eStatus( stProtoId ) | 27 | eStatus( stProtoId ) |
26 | { | 28 | { |
@@ -67,7 +69,7 @@ void Bu::ProtocolWebSocket::onNewData( Bu::Client * /*pClient*/ ) | |||
67 | void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, | 69 | void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, |
68 | Bu::ProtocolWebSocket::Operation eOp ) | 70 | Bu::ProtocolWebSocket::Operation eOp ) |
69 | { | 71 | { |
70 | //Bu::println("websocket: Writing message, %1 bytes").arg( sData.getSize() ); | 72 | DEBUG( Bu::println("websocket: Writing message, %1 bytes").arg( sData.getSize() ) ); |
71 | uint8_t cHeader[32]; | 73 | uint8_t cHeader[32]; |
72 | //uint8_t *cMask; | 74 | //uint8_t *cMask; |
73 | memset( cHeader, 0, 32 ); | 75 | memset( cHeader, 0, 32 ); |
@@ -79,12 +81,12 @@ void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, | |||
79 | uint64_t iLen = sData.getSize(); | 81 | uint64_t iLen = sData.getSize(); |
80 | if( iLen < 126 ) | 82 | if( iLen < 126 ) |
81 | { | 83 | { |
82 | //Bu::println("websocket: --> Tiny header"); | 84 | DEBUG( Bu::println("websocket: --> Tiny header") ); |
83 | cHeader[1] = ((uint8_t)iLen); | 85 | cHeader[1] = ((uint8_t)iLen); |
84 | } | 86 | } |
85 | else if( iLen < 65536 ) | 87 | else if( iLen < 65536 ) |
86 | { | 88 | { |
87 | //Bu::println("websocket: --> Mid header"); | 89 | DEBUG( Bu::println("websocket: --> Mid header") ); |
88 | cHeader[1] = ((uint8_t)126); | 90 | cHeader[1] = ((uint8_t)126); |
89 | uint16_t uLen = iLen; | 91 | uint16_t uLen = iLen; |
90 | uLen = htobe16( uLen ); | 92 | uLen = htobe16( uLen ); |
@@ -93,20 +95,20 @@ void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, | |||
93 | } | 95 | } |
94 | else | 96 | else |
95 | { | 97 | { |
96 | // Bu::println("websocket: --> Big header?"); | 98 | DEBUG( Bu::println("websocket: --> Big header?") ); |
97 | cHeader[1] = ((uint8_t)127); | 99 | cHeader[1] = ((uint8_t)127); |
98 | uint64_t iTmp = htobe64( iLen ); | 100 | uint64_t iTmp = htobe64( iLen ); |
99 | memcpy( cHeader+idx, &iTmp, 8 ); | 101 | memcpy( cHeader+idx, &iTmp, 8 ); |
100 | idx += 8; | 102 | idx += 8; |
101 | } | 103 | } |
102 | /* | 104 | |
103 | Bu::println("Message size: %1 (%2)").arg( iLen ).arg( iLen, Bu::Fmt::bin(4) ); | 105 | DEBUG( Bu::println("Message size: %1 (%2)").arg( iLen ).arg( iLen, Bu::Fmt::bin(4) ) ); |
104 | for( int j = 0; j < idx; j++ ) | 106 | for( int j = 0; j < idx; j++ ) |
105 | { | 107 | { |
106 | Bu::print(" %1").arg( cHeader[j], Bu::Fmt::bin(8) ); | 108 | DEBUG( Bu::print(" %1").arg( cHeader[j], Bu::Fmt::bin(8) ) ); |
107 | } | 109 | } |
108 | Bu::println(""); | 110 | DEBUG( Bu::println("") ); |
109 | */ | 111 | |
110 | Bu::MutexLocker l( mClient ); | 112 | Bu::MutexLocker l( mClient ); |
111 | if( pClient == NULL ) | 113 | if( pClient == NULL ) |
112 | return; | 114 | return; |
@@ -149,7 +151,7 @@ bool Bu::ProtocolWebSocket::stateProtoId() | |||
149 | 151 | ||
150 | bool Bu::ProtocolWebSocket::stateHandshake() | 152 | bool Bu::ProtocolWebSocket::stateHandshake() |
151 | { | 153 | { |
152 | //Bu::println("websocket: Begining handshake."); | 154 | DEBUG( Bu::println("websocket: Begining handshake.") ); |
153 | 155 | ||
154 | Bu::String sLine; | 156 | Bu::String sLine; |
155 | if( !readHttpHdrLine( sLine ) ) | 157 | if( !readHttpHdrLine( sLine ) ) |
@@ -174,14 +176,16 @@ bool Bu::ProtocolWebSocket::stateHandshake() | |||
174 | Bu::String sKey( sLine, iPos ); | 176 | Bu::String sKey( sLine, iPos ); |
175 | Bu::String sValue( sLine.getSubStrIdx( iPos+2 ) ); | 177 | Bu::String sValue( sLine.getSubStrIdx( iPos+2 ) ); |
176 | 178 | ||
179 | sKey = sKey.toLower(); | ||
180 | |||
177 | if( !hHeader.has( sKey ) ) | 181 | if( !hHeader.has( sKey ) ) |
178 | { | 182 | { |
179 | hHeader.insert( sKey, Bu::StringList() ); | 183 | hHeader.insert( sKey, Bu::StringList() ); |
180 | } | 184 | } |
181 | hHeader.get( sKey ).append( sValue ); | 185 | hHeader.get( sKey ).append( sValue ); |
182 | 186 | ||
183 | // Bu::println("Hdr: >>%1<<").arg( sLine ); | 187 | DEBUG( Bu::println("Hdr: >>%1<<").arg( sLine ) ); |
184 | // Bu::println("%1 = %2").arg( sKey ).arg( sValue ); | 188 | DEBUG( Bu::println("%1 = %2").arg( sKey ).arg( sValue ) ); |
185 | 189 | ||
186 | return true; | 190 | return true; |
187 | } | 191 | } |
@@ -214,13 +218,13 @@ bool Bu::ProtocolWebSocket::processHeaders() | |||
214 | } | 218 | } |
215 | 219 | ||
216 | Bu::String sNonce; | 220 | Bu::String sNonce; |
217 | if( !hHeader.has("Sec-WebSocket-Key") ) | 221 | if( !hHeader.has("sec-websocket-key") ) // "Sec-WebSocket-Key" |
218 | { | 222 | { |
219 | pClient->disconnect(); | 223 | pClient->disconnect(); |
220 | return false; | 224 | return false; |
221 | } | 225 | } |
222 | 226 | ||
223 | sNonce = hHeader.get("Sec-WebSocket-Key").first(); | 227 | sNonce = hHeader.get("sec-websocket-key").first(); // "Sec-WebSocket-Key" |
224 | 228 | ||
225 | Bu::String sGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | 229 | Bu::String sGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; |
226 | 230 | ||
@@ -231,7 +235,7 @@ bool Bu::ProtocolWebSocket::processHeaders() | |||
231 | sum.writeResult( bOut ); | 235 | sum.writeResult( bOut ); |
232 | bOut.stop(); | 236 | bOut.stop(); |
233 | 237 | ||
234 | // Bu::println("accept: %1").arg( mbOut.getString() ); | 238 | DEBUG( Bu::println("accept: %1").arg( mbOut.getString() ) ); |
235 | 239 | ||
236 | pClient->write("HTTP/1.1 101 Switching Protocols\r\n" | 240 | pClient->write("HTTP/1.1 101 Switching Protocols\r\n" |
237 | "Upgrade: websocket\r\n" | 241 | "Upgrade: websocket\r\n" |
@@ -240,19 +244,20 @@ bool Bu::ProtocolWebSocket::processHeaders() | |||
240 | "\r\n" | 244 | "\r\n" |
241 | ); | 245 | ); |
242 | 246 | ||
243 | //Bu::println("websocket: Switching protocols."); | 247 | DEBUG( Bu::println("websocket: Switching protocols.") ); |
244 | 248 | ||
245 | return true; | 249 | return true; |
246 | } | 250 | } |
247 | 251 | ||
248 | bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::String &sValue ) | 252 | bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::String &sValue ) |
249 | { | 253 | { |
250 | if( !hHeader.has( sKey ) ) | 254 | Bu::String sKeyLow = sKey.toLower(); |
255 | if( !hHeader.has( sKeyLow ) ) | ||
251 | return false; | 256 | return false; |
252 | 257 | ||
253 | for( Bu::StringList::iterator i = hHeader.get( sKey ).begin(); i; i++ ) | 258 | for( Bu::StringList::iterator i = hHeader.get( sKeyLow ).begin(); i; i++ ) |
254 | { | 259 | { |
255 | if( *i == sValue ) | 260 | if( !strcasecmp((*i).getStr(), sValue.getStr()) ) |
256 | return true; | 261 | return true; |
257 | } | 262 | } |
258 | 263 | ||
@@ -261,7 +266,7 @@ bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::Strin | |||
261 | 266 | ||
262 | bool Bu::ProtocolWebSocket::parseMessage() | 267 | bool Bu::ProtocolWebSocket::parseMessage() |
263 | { | 268 | { |
264 | //Bu::println("websocket: Recieved message, input available: %1").arg( pClient->getInputSize() ); | 269 | DEBUG( Bu::println("websocket: Recieved message, input available: %1").arg( pClient->getInputSize() ) ); |
265 | 270 | ||
266 | if( pClient->getInputSize() < 2 ) | 271 | if( pClient->getInputSize() < 2 ) |
267 | return false; | 272 | return false; |
@@ -316,8 +321,8 @@ bool Bu::ProtocolWebSocket::parseMessage() | |||
316 | } | 321 | } |
317 | } | 322 | } |
318 | 323 | ||
319 | // Bu::println(""); | 324 | DEBUG( Bu::println("") ); |
320 | // Bu::println("Data: >>%1<<").arg( sData ); | 325 | DEBUG( Bu::println("Data: >>%1<<").arg( sData ) ); |
321 | 326 | ||
322 | onNewMessage( sData, eOp ); | 327 | onNewMessage( sData, eOp ); |
323 | 328 | ||