aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mbuland@penny-arcade.com>2019-07-29 07:37:10 -0700
committerMike Buland <mbuland@penny-arcade.com>2019-07-29 07:37:10 -0700
commitaf4bc8816eb4b4cb4821b24706f55b518a43968d (patch)
tree23d599d050a6483cf4132f6a763c6222f69e36f9
parent76649ebc55a243882ba6ac981f41c1d007b6f63a (diff)
downloadlibbu++-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.cpp49
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
24Bu::ProtocolWebSocket::ProtocolWebSocket() : 26Bu::ProtocolWebSocket::ProtocolWebSocket() :
25 eStatus( stProtoId ) 27 eStatus( stProtoId )
26{ 28{
@@ -67,7 +69,7 @@ void Bu::ProtocolWebSocket::onNewData( Bu::Client * /*pClient*/ )
67void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, 69void 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
150bool Bu::ProtocolWebSocket::stateHandshake() 152bool 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
248bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::String &sValue ) 252bool 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
262bool Bu::ProtocolWebSocket::parseMessage() 267bool 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