From af4bc8816eb4b4cb4821b24706f55b518a43968d Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 29 Jul 2019 07:37:10 -0700 Subject: 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. --- src/unstable/protocolwebsocket.cpp | 49 +++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src') 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 @@ #include +#define DEBUG( X ) { } (void)0 + Bu::ProtocolWebSocket::ProtocolWebSocket() : eStatus( stProtoId ) { @@ -67,7 +69,7 @@ void Bu::ProtocolWebSocket::onNewData( Bu::Client * /*pClient*/ ) void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, Bu::ProtocolWebSocket::Operation eOp ) { - //Bu::println("websocket: Writing message, %1 bytes").arg( sData.getSize() ); + DEBUG( Bu::println("websocket: Writing message, %1 bytes").arg( sData.getSize() ) ); uint8_t cHeader[32]; //uint8_t *cMask; memset( cHeader, 0, 32 ); @@ -79,12 +81,12 @@ void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, uint64_t iLen = sData.getSize(); if( iLen < 126 ) { - //Bu::println("websocket: --> Tiny header"); + DEBUG( Bu::println("websocket: --> Tiny header") ); cHeader[1] = ((uint8_t)iLen); } else if( iLen < 65536 ) { - //Bu::println("websocket: --> Mid header"); + DEBUG( Bu::println("websocket: --> Mid header") ); cHeader[1] = ((uint8_t)126); uint16_t uLen = iLen; uLen = htobe16( uLen ); @@ -93,20 +95,20 @@ void Bu::ProtocolWebSocket::writeMessage( const Bu::String &sData, } else { -// Bu::println("websocket: --> Big header?"); + DEBUG( Bu::println("websocket: --> Big header?") ); cHeader[1] = ((uint8_t)127); uint64_t iTmp = htobe64( iLen ); memcpy( cHeader+idx, &iTmp, 8 ); idx += 8; } -/* - Bu::println("Message size: %1 (%2)").arg( iLen ).arg( iLen, Bu::Fmt::bin(4) ); + + DEBUG( Bu::println("Message size: %1 (%2)").arg( iLen ).arg( iLen, Bu::Fmt::bin(4) ) ); for( int j = 0; j < idx; j++ ) { - Bu::print(" %1").arg( cHeader[j], Bu::Fmt::bin(8) ); + DEBUG( Bu::print(" %1").arg( cHeader[j], Bu::Fmt::bin(8) ) ); } - Bu::println(""); -*/ + DEBUG( Bu::println("") ); + Bu::MutexLocker l( mClient ); if( pClient == NULL ) return; @@ -149,7 +151,7 @@ bool Bu::ProtocolWebSocket::stateProtoId() bool Bu::ProtocolWebSocket::stateHandshake() { - //Bu::println("websocket: Begining handshake."); + DEBUG( Bu::println("websocket: Begining handshake.") ); Bu::String sLine; if( !readHttpHdrLine( sLine ) ) @@ -174,14 +176,16 @@ bool Bu::ProtocolWebSocket::stateHandshake() Bu::String sKey( sLine, iPos ); Bu::String sValue( sLine.getSubStrIdx( iPos+2 ) ); + sKey = sKey.toLower(); + if( !hHeader.has( sKey ) ) { hHeader.insert( sKey, Bu::StringList() ); } hHeader.get( sKey ).append( sValue ); -// Bu::println("Hdr: >>%1<<").arg( sLine ); -// Bu::println("%1 = %2").arg( sKey ).arg( sValue ); + DEBUG( Bu::println("Hdr: >>%1<<").arg( sLine ) ); + DEBUG( Bu::println("%1 = %2").arg( sKey ).arg( sValue ) ); return true; } @@ -214,13 +218,13 @@ bool Bu::ProtocolWebSocket::processHeaders() } Bu::String sNonce; - if( !hHeader.has("Sec-WebSocket-Key") ) + if( !hHeader.has("sec-websocket-key") ) // "Sec-WebSocket-Key" { pClient->disconnect(); return false; } - sNonce = hHeader.get("Sec-WebSocket-Key").first(); + sNonce = hHeader.get("sec-websocket-key").first(); // "Sec-WebSocket-Key" Bu::String sGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -231,7 +235,7 @@ bool Bu::ProtocolWebSocket::processHeaders() sum.writeResult( bOut ); bOut.stop(); -// Bu::println("accept: %1").arg( mbOut.getString() ); + DEBUG( Bu::println("accept: %1").arg( mbOut.getString() ) ); pClient->write("HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" @@ -240,19 +244,20 @@ bool Bu::ProtocolWebSocket::processHeaders() "\r\n" ); - //Bu::println("websocket: Switching protocols."); + DEBUG( Bu::println("websocket: Switching protocols.") ); return true; } bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::String &sValue ) { - if( !hHeader.has( sKey ) ) + Bu::String sKeyLow = sKey.toLower(); + if( !hHeader.has( sKeyLow ) ) return false; - for( Bu::StringList::iterator i = hHeader.get( sKey ).begin(); i; i++ ) + for( Bu::StringList::iterator i = hHeader.get( sKeyLow ).begin(); i; i++ ) { - if( *i == sValue ) + if( !strcasecmp((*i).getStr(), sValue.getStr()) ) return true; } @@ -261,7 +266,7 @@ bool Bu::ProtocolWebSocket::headerMatch( const Bu::String &sKey, const Bu::Strin bool Bu::ProtocolWebSocket::parseMessage() { - //Bu::println("websocket: Recieved message, input available: %1").arg( pClient->getInputSize() ); + DEBUG( Bu::println("websocket: Recieved message, input available: %1").arg( pClient->getInputSize() ) ); if( pClient->getInputSize() < 2 ) return false; @@ -316,8 +321,8 @@ bool Bu::ProtocolWebSocket::parseMessage() } } -// Bu::println(""); -// Bu::println("Data: >>%1<<").arg( sData ); + DEBUG( Bu::println("") ); + DEBUG( Bu::println("Data: >>%1<<").arg( sData ) ); onNewMessage( sData, eOp ); -- cgit v1.2.3