#ifndef __app_websocket_frame_h__#define __app_websocket_frame_h__#include "MEMORY.HPP" class Buffer;struct Websocket_frame{websocket_frame (); ~websocket_frame (); static const unsigned int fix_min_len = 2;static Const unsigned int fix_masking_len = 4;static const unsigned int fix_126_len = 2;static const unsigned int fix_127_len = 8;bool Fin;bool Rsv1;bool rsv2;bool rsv3;unsigned Char opcode;bool mask;unsigned char payload_len; unsigned short payload_126_len; unsigned long long payload_127_len;unsigned char masking_key[4];shared_ptr<buffer> payload;unsigned int Get_head _len () const; unsigned int get_total_len () const; unsigned int get_payload_len () const;//Unpack int unpakcage (const SHARED_PT R<buffer> & BUF);//packaging unsigned int package_size ();shared_ptr<buffer> package ();p rotected:void set_ Masking_key (unsigned char * data, int offset), void Get_masking_key (unsigned char * data, int offset);}; #endif
#include "websocket_frame.hpp" #include "buffer_pool.hpp" #include <cstring> #include <glog/logging.h># Include <cstdlib>websocket_frame::websocket_frame (): Fin (False), RSV1 (false), Rsv2 (false), Rsv3 (false), mask ( false), opcode (0), Payload_len (0), Payload_126_len (0), Payload_127_len (0) {int rand_var = rand (); masking_key[0] = (rand_ var & 0xff000000) >>24;masking_key[1] = (Rand_var & 0x00ff0000) >> 16;masking_key[2] = (Rand_var & 0X0000FF00) >> 8;masking_key[3] = Rand_var & 0x000000ff;} Websocket_frame::~websocket_frame () {if (payload) {Recycle_buffer (payload);}} void Websocket_frame::set_masking_key (unsigned char * data, int offset) {masking_key[0] = data[0+offset];masking_key[1] = data[1+offset];masking_key[2] = data[2+offset];masking_key[3] = Data[3+offset];} void Websocket_frame:: Get_masking_key (unsigned char * data, int offset) {Data[0+offset] = masking_key[0]; Data[1+offset] = Masking_key[1]; Data[2+offset] = masking_key[2]; Data[3+offset] = MasKING_KEY[3];} unsigned int websocket_frame::get_head_len () const {return Get_total_len ()-Get_payload_len ();} unsigned int websocket_frame::get_total_len () const {if (mask) {if (Payload_len < 126) {return Payload_len + Fix_min_le n + fix_masking_len;} else if (Payload_len = = 126) {return Payload_126_len + Fix_min_len + Fix_masking_len + Fix_126_len;} else {return Payload_127_len +fix_min_len + Fix_masking_len + Fix_127_len;}} Else{if (Payload_len < 126) {return payload_len + Fix_min_len;} else if (Payload_len = = 126) {return Payload_126_len + Fix_min_len + Fix_126_len;} else {return Payload_127_len + Fix_min_len + Fix_127_len;}}} unsigned int websocket_frame::get_payload_len () const {if (Payload_len < 126) {return payload_len;} else if (Payload_len = = 126) {return payload_126_len;} else {return payload_127_len;}} int Websocket_frame::unpakcage (const shared_ptr<buffer> & buf) {if (buf->length () = = 0) {return 2;} unsigned char * data = Buf->data (); fin = data[0] & 0x80;RSV1 = data[0] & (0x40); rsv2 = data[0] & (0x20); rsv3 = data[0] & (0x10); opcode = (data[0] & 0x0f); Mas k = data[1] & 0x80;payload_len = data[1] & 0x7f;if (Payload_len < 126) {if (Buf->length () < Get_total_len ()) {return Get_total_len ()-Buf->length ();} Payload = Get_buffer (Get_payload_len ()) unsigned char * pdata = Payload->data (); if (mask) {Set_masking_key (data,2); int i;for (i = 0; i < Payload_len; i + +) {Pdata[i] = Data[6+i] ^ masking_key[i%4];}} else{memcpy (pdata, data+2, Get_payload_len ());} Payload->size (Get_payload_len ());} else if (Payload_len = = 126) {if (Buf->length () < 4) {return 4-buf->length ();} Payload_126_len = (data[2] << 8) | Data[3];if (Buf->length () < Get_total_len ()) {return Get_total_len ()-Buf->length ();} Payload = Get_buffer (Get_payload_len ()) unsigned char * pdata = Payload->data (); if (mask) {Set_masking_key (data,4); int i;for (i = 0; i < Payload_126_len; i + +) {Pdata[i] = Data[8+i] ^MASKING_KEY[I%4];}} else{memcpy (pdata, Data+4, Get_payload_len ());} Payload->size (Get_payload_len ());} else{//127LOG (FATAL) << "un support big frame for websocket.";} return 0;} unsigned int websocket_frame::p ackage_size () {if (Payload->length () < 126) {Payload_len = Payload->length ();} else if (Payload->length () < 0xFFFF) {Payload_len = 126;payload_126_len = Payload->length ();} Else{payload_len = 127;payload_127_len = Payload->length ();} return Get_total_len ();} Shared_ptr<buffer> websocket_frame::p ackage () {shared_ptr<buffer> buf = Get_buffer (Package_size ()); buf- >size (Package_size ()); unsigned char * data = Buf->data ();d ata[0] = 0;if (Fin) {data[0] |= 0x80;} if (RSV1) {data[0] |= 0x40;} if (RSV2) {data[0] |= 0x20;} if (rsv3) {data[0] |= 0x10;} Data[0] |= (opcode & 0x0f);d ata[1] = 0;if (mask) {data[1] |= 0x80;} Data[1] |= (Payload_len & 0x7f); unsigned char * pdata = Payload->data (); if (Payload_len < 126) {if (mask) {//get _masking_key (DAta,2);d ata[2] = masking_key[0];d ata[3] = masking_key[1];d ata[4] = masking_key[2];d ata[5] = Masking_key[3];int i = 0;for (i = 0; i < Payload_len; i + +) {Data[6+i] = Pdata[i] ^ masking_key[i%4];}} else{memcpy (data+2, Pdata,payload_len);}} else if (Payload_len = = 126) {Data[2] = (unsigned char) ((Payload_126_len & 0xff00) >> 8);d ata[3] = (unsigned char ) (Payload_126_len & 0X00FF); if (mask) {data[4] = masking_key[0];d ata[5] = masking_key[1];d ata[6] = masking_key[2];d A TA[7] = Masking_key[3];int i = 0;for (i = 0; i < Payload_126_len; i + +) {Data[8+i] = Pdata[i] ^ masking_key[i%4];}} else{memcpy (data+4, Pdata,payload_126_len);}} else if (Payload_len = = 127) {LOG (FATAL) << "No support 127 web socket frame.";} return BUF;}
The emphasis is on the Unpakcage method, which returns 0 when the unpacking succeeds, and returns how many bytes are required to parse a complete package if it fails.
In addition, for the time being, there is no calculation of the payload_len=127 situation, mainly in most of the environment does not need to be so large. When the Get_head_len, Get_total_len, Get_payload_len are called, the correct data can be returned, and if Unpackage returns greater than 0 o'clock, calling the function about Len is illegal.