Sirikata
|
00001 namespace Sirikata { namespace Network { 00002 class CheckWebSocketHeader { 00003 00004 00005 class CaseInsensitive { 00006 public: 00007 bool operator() (const uint8 &left, const uint8 &right) { 00008 return std::toupper(left) == std::toupper(right); 00009 } 00010 }; 00011 const Array<uint8,TCPStream::MaxWebSocketHeaderSize> *mArray; 00012 typedef boost::system::error_code ErrorCode; 00013 uint32 mTotal; 00014 bool mClient; 00015 public: 00016 CheckWebSocketHeader(const Array<uint8,TCPStream::MaxWebSocketHeaderSize>*array, bool client) { 00017 mArray=array; 00018 mTotal = 0; 00019 mClient=client; 00020 } 00021 size_t operator() (const ErrorCode& error, size_t bytes_transferred) { 00022 if (error) return 0; 00023 uint8 target[]="\r\n\r\n"; 00024 const uint8 *version=mClient?(const uint8*)"sec-websocket-accept":(const uint8*)"sec-websocket-version"; 00025 const uint8 * arrayEnd= mArray->begin()+bytes_transferred; 00026 const uint8 * where = std::search (mArray->begin(),arrayEnd,target,target+4); 00027 if (where==arrayEnd) 00028 return TCPStream::MaxWebSocketHeaderSize-bytes_transferred; 00029 mTotal += bytes_transferred; 00030 00031 // Newer handshakes do not have data in the body. 00032 // We need to allow these to complete *before* data is received. 00033 00034 // We check case-insensitive for Sec-WebSocket-Version: 13 00035 // Dumbed down due to lack of cross-platform case-insensitive 00036 // string functions 00037 00038 const uint8 *whereVersion = std::search(mArray->begin(),arrayEnd, version,version+strlen((const char*)version),CaseInsensitive()); 00039 if (whereVersion == arrayEnd) { 00040 size_t bytesAfterNewlines = mClient?16:8; 00041 return where+4+bytesAfterNewlines<=arrayEnd?0:TCPStream::MaxWebSocketHeaderSize-bytes_transferred; 00042 } 00043 return 0; 00044 } 00045 }; 00046 }}