Code Monkey home page Code Monkey logo

websocket-parser's Introduction

WebSocket frame parser and builder

This is a parser and builder for WebSocket messages (see RFC6455) written in C.

Table of Contents

Features

  • Fast parsing and building of websocket messages
  • No dependencies
  • No internal buffering
  • No need to buffer the whole frame โ€” works with chunks of a data
  • No syscalls
  • No allocations
  • It can be interrupted at anytime

Tested as part of PHP-ION extension.

Inspired by http-parser by Ryan Dahl and multipart-parser by Igor Afonov.

Status

Production ready.

Usage

Use http-parser for parsing headers. This library parse only websocket frames.

This parser library works with several callbacks, which the user may set up at application initialization time.

websocket_parser_settings settings;

websocket_parser_settings_init(&settings);

settings.on_frame_header = websocket_frame_header;
settings.on_frame_body = websocket_frame_body;
settings.on_frame_end = websocket_frame_end;

These functions must match the signatures defined in the websocket-parser header file.

Returning a value other than 0 from the callbacks will abort message processing.

One websocket_parser object is used per TCP connection. Initialize websocket_parser struct using websocket_parser_init() and set callbacks:

websocket_parser_settings settings;

websocket_parser_settings_init(&settings);

settings.on_frame_header = websocket_frame_header;
settings.on_frame_body   = websocket_frame_body;
settings.on_frame_end    = websocket_frame_end;

parser = malloc(sizeof(websocket_parser));
websocket_parser_init(parser);
// Attention! Sets your <data> after websocket_parser_init
parser->data = my_frame_struct;

Basically, callback looks like that:

int websocket_frame_header(websocket_parser * parser) {
    parser->data->opcode = parser->flags & WS_OP_MASK; // gets opcode
    parser->data->is_final = parser->flags & WS_FIN;   // checks is final frame
    if(parser->length) {
        parser->data->body = malloc(parser->length);   // allocate memory for frame body, if body exists
    }
    return 0;
}

int ion_websocket_frame_body(websocket_parser * parser, const char *at, size_t size) {
    if(parser->flags & WS_HAS_MASK) {
        // if frame has mask, we have to copy and decode data via websocket_parser_copy_masked function
        websocket_parser_decode(&parser->data->body[parser->offset], at, length, parser);
    } else {
        memcpy(&parser->data->body[parser->offset], at, length);
    }
    return 0;
}

int websocket_frame_end(websocket_parser * parser) {
    my_app_push_frame(parser->data); // use parsed frame
}

When data is received execute the parser and check for errors.

size_t nread;
// .. init settitngs and parser ... 

nread = websocket_parser_execute(parser, &settings, data, data_len);
if(nread != data_len) {
    // some callback return a value other than 0
}

// ...
free(parser);

Frame builder

To calculate how many bytes to allocate for a frame, use the websocket_calc_frame_size function:

size_t frame_len = websocket_calc_frame_size(WS_OP_TEXT | WS_FINAL_FRAME | WS_HAS_MASK, data_len);
char * frame = malloc(sizeof(char) * frame_len);

After that you can build a frame

websocket_build_frame(frame, WS_OP_TEXT | WS_FINAL_FRAME | WS_HAS_MASK, mask, data, data_len);

and send binary string to the socket

write(sock, frame, frame_len);

UUID

Macros WEBSOCKET_UUID contains unique ID for handshake

#define WEBSOCKET_UUID   "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

Frame example

There is binary websocket frame example:

  • Raw frame: \x81\x8Amask\x0B\x13\x12\x06\x08\x41\x17\x0A\x19\x00
  • Has mask: yes
  • Mask: mask
  • Payload: frame data
  • Fin: yes
  • Opcode: WS_OP_TEXT

websocket-parser's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

websocket-parser's Issues

Size issue

frame[1] |= 127;

On 32bit systems (most MCUs out there), size_t is usually 32bits wide. The referenced code could produce unexpected results. I suggest explicitly setting the variable's [data_len] length to 64bits wide.

Package for Conan Center

We use Conan internally at work and it would be nice to have this available as a package we can include.

I plan to contribute a patch to the Conan Center Index repository; I'll mention this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.