- 1#include"webSocketProtocol.h"
- 2#include
- 3#include
- 4#include <string.h> 5#include 6#include"sha1.h"
- 7#include"base64.h"
- 8
- 9 const char* MAGIC_KEY ="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- 10
- 11 CWebSocketProtocol::CGrabo CWebSocketProtocol::m_grabo;
- 12CWebSocketProtocol * CWebSocketProtocol::m_inst =0;
- 13
- 14 CWebSocketProtocol::CWebSocketProtocol()
- 15 {
- 16 }
- 17
- 18
- 19CWebSocketProtocol::~CWebSocketProtocol()
- 20 {
- 21 }
- 22
- 23
- 24
- 25CWebSocketProtocol * CWebSocketProtocol::getInstance()
- 26 {
- 27 if(m_inst !=0)
- 28 {
- 29m_inst =new CWebSocketProtocol;
- 30 }
- 31
- 32 return m_inst;
- 33 }
- 34
- 35 intCWebSocketProtocol::getResponseHttp(string&request,string&response)
- 36 {
- 37 // 解析http请求头信息
- 38 intret = WS_STATUS_UNCONNECT;
- 39 std::istringstream stream(request.c_str());
- 40std::string reqType;
- 41 std::getline(stream, reqType);
- 42 if(reqType.substr(0,4) !="GET ")
- 43 {
- 44 return ret;
- 45 }
- 46
- 47std::string header;
- 48std::string::size_type pos =0;
- 49std::string websocketKey;
- 50 while(std::getline(stream, header) && header !="\r")
- 51 {
- 52header.erase(header.end() -1);
- 53pos = header.find(": ",0);
- 54 if(pos != std::string::npos)
- 55 {
- 56std::stringkey = header.substr(0, pos);
- 57std::stringvalue = header.substr(pos +2);
- 58 if(key =="Sec-WebSocket-Key")
- 59 {
- 60ret = WS_STATUS_CONNECT;
- 61websocketKey = value;
- 62 break;
- 63 }
- 64 }
- 65 }
- 66
- 67 if(ret != WS_STATUS_CONNECT)
- 68 {
- 69 return ret;
- 70 }
- 71
- 72 // 填充http响应头信息
- 73response ="HTTP/1.1 101 Switching Protocols\r\n";
- 74response +="Connection: upgrade\r\n";
- 75response +="Sec-WebSocket-Accept: ";
- 76
- 77std::stringserverKey = websocketKey + MAGIC_KEY;
- 78
- 79 SHA1 sha;
- 80unsignedintmessage_digest[5];
- 81 sha.Reset();
- 82sha << serverKey.c_str();
- 83
- 84 sha.Result(message_digest);
- 85 for(inti =0; i <5; i++) {
- 86message_digest[i] = htonl(message_digest[i]);
- 87 }
- 88serverKey = base64_encode(reinterpret_cast<constunsignedchar*>(message_digest),20);
- 89response += serverKey;
- 90response +="\r\n";
- 91response +="Upgrade: websocket\r\n\r\n";
- 92
- 93 return ret;
- 94 }
- 95
- 96 intCWebSocketProtocol::wsDecodeFrame(stringinFrame,string&outMessage)
- 97 {
- 98 intret = WS_OPENING_FRAME;
- 99 const char*frameData = inFrame.c_str();
- 100 const intframeLength = inFrame.size();
- 101 if(frameLength <2)
- 102 {
- 103ret = WS_ERROR_FRAME;
- 104 }
- 105
- 106 // 检查扩展位并忽略
- 107 if((frameData[0] &0x70) !=0x0)
- 108 {
- 109ret = WS_ERROR_FRAME;
- 110 }
- 111
- 112 // fin位: 为1表示已接收完整报文, 为0表示继续监听后续报文
- 113ret = (frameData[0] &0x80);
- 114 if((frameData[0] &0x80) !=0x80)
- 115 {
- 116ret = WS_ERROR_FRAME;
- 117 }
- 118
- 119 // mask位, 为1表示数据被加密
- 120 if((frameData[1] &0x80) !=0x80)
- 121 {
- 122ret = WS_ERROR_FRAME;
- 123 }
- 124
- 125 // 操作码
- 126uint16_t payloadLength =0;
- 127uint8_t payloadFieldExtraBytes =0;
- 128uint8_t opcode = static_cast(frameData[0] &0x0f);
- 129 if(opcode == WS_TEXT_FRAME)
- 130 {
- 131 // 处理utf-8编码的文本帧
- 132payloadLength = static_cast(frameData[1] &0x7f);
- 133 if(payloadLength ==0x7e)
- 134 {
- 135uint16_t payloadLength16b =0;
- 136payloadFieldExtraBytes =2;
- 137memcpy(&payloadLength16b, &frameData[2], payloadFieldExtraBytes);
- 138payloadLength = ntohs(payloadLength16b);
- 139 }
- 140 else if(payloadLength ==0x7f)
- 141 {
- 142 // 数据过长,暂不支持
- 143ret = WS_ERROR_FRAME;
- 144 }
- 145 }
- 146 else if(opcode == WS_BINARY_FRAME || opcode == WS_PING_FRAME || opcode == WS_PONG_FRAME)
- 147 {
- 148 // 二进制/ping/pong帧暂不处理
- 149 }
- 150 else if(opcode == WS_CLOSING_FRAME)
- 151 {
- 152ret = WS_CLOSING_FRAME;
- 153 }
- 154 else
- 155 {
- 156ret = WS_ERROR_FRAME;
- 157 }
- 158
- 159 // 数据解码
- 160 if((ret != WS_ERROR_FRAME) && (payloadLength >0))
- 161 {
- 162 // header: 2字节, masking key: 4字节
- 163 const char*maskingKey = &frameData[2+ payloadFieldExtraBytes];
- 164 char*payloadData =new char[payloadLength +1];
- 165memset(payloadData,0, payloadLength +1);
- 166memcpy(payloadData, &frameData[2+ payloadFieldExtraBytes +4], payloadLength);
- 167 for(inti =0; i < payloadLength; i++)
- 168 {
- 169payloadData[i] = payloadData[i] ^ maskingKey[i %4];
- 170 }
- 171
- 172outMessage = payloadData;
- 173 delete[] payloadData;
- 174 }
- 175
- 176 return ret;
- 177 }
- 178
- 179 intCWebSocketProtocol::wsEncodeFrame(stringinMessage,string&outFrame,enum WS_FrameType frameType)
- 180 {
- 181 intret = WS_EMPTY_FRAME;
- 182 constuint32_t messageLength = inMessage.size();
- 183 if(messageLength >32767)
- 184 {
- 185 // 暂不支持这么长的数据
- 186std::cout <<"暂不支持这么长的数据"<< std::endl;
- 187
- 188 return WS_ERROR_FRAME;
- 189 }
- 190
- 191uint8_t payloadFieldExtraBytes = (messageLength <=0x7d)0:2;
- 192 // header: 2字节, mask位设置为0(不加密), 则后面的masking key无须填写, 省略4字节
- 193uint8_t frameHeaderSize =2+ payloadFieldExtraBytes;
- 194uint8_t *frameHeader =new uint8_t[frameHeaderSize];
- 195memset(frameHeader,0, frameHeaderSize);
- 196 // fin位为1, 扩展位为0, 操作位为frameType
- 197frameHeader[0] = static_cast(0x80| frameType);
- 198
- 199 // 填充数据长度
- 200 if(messageLength <=0x7d)
- 201 {
- 202frameHeader[1] = static_cast(messageLength);
- 203 }
- 204 else
- 205 {
- 206frameHeader[1] =0x7e;
- 207uint16_t len = htons(messageLength);
- 208memcpy(&frameHeader[2], &len, payloadFieldExtraBytes);
- 209 }
- 210
- 211 // 填充数据
- 212uint32_t frameSize = frameHeaderSize + messageLength;
- 213 char*frame =new char[frameSize +1];
- 214 memcpy(frame, frameHeader, frameHeaderSize);
- 215memcpy(frame + frameHeaderSize, inMessage.c_str(), messageLength);
- 216frame[frameSize] ='\0';
- 217outFrame = frame;
- 218
- 219 delete[] frame;
- 220 delete[] frameHeader;
- 221 return ret;
- 222}
来源: http://www.bubuko.com/infodetail-1978178.html