Web socket RFC6455 Frame package, unpack

Source: Internet
Author: User
Tags unpack

#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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.