Annotation of parser3/src/include/pa_websocket.h, revision 1.1

1.1     ! moko        1: /** @file
        !             2:        Parser: WebSocket (RFC 6455) support: handshake and frames.
        !             3: 
        !             4:        Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
        !             5:        Authors: Konstantin Morshnev <moko@design.ru>
        !             6: */
        !             7: 
        !             8: #ifndef PA_WEBSOCKET_H
        !             9: #define PA_WEBSOCKET_H
        !            10: 
        !            11: #define IDENT_PA_WEBSOCKET_H "$Id$"
        !            12: 
        !            13: #include "pa_http.h"
        !            14: 
        !            15: /// checks the request of the handshake, returns the value of the Sec-WebSocket-Accept header, throws websocket.handshake
        !            16: const char* pa_websocket_accept_key(const char* method, const char* upgrade, const char* connection, const char* key, const char* version);
        !            17: 
        !            18: /// messages are received and sent one at a time
        !            19: class WebSocket : public PA_Allocated {
        !            20: public:
        !            21: 
        !            22:        enum Opcode {
        !            23:                TEXT=0x1,
        !            24:                BINARY=0x2,
        !            25:                CLOSE=0x8,
        !            26:                PING=0x9,
        !            27:                PONG=0xA
        !            28:        };
        !            29: 
        !            30:        /// the status codes of the Close frame
        !            31:        enum Status {
        !            32:                NORMAL=1000,
        !            33:                PROTOCOL_ERROR=1002,
        !            34:                NO_STATUS=1005,
        !            35:                ABNORMAL=1006,
        !            36:                INVALID_DATA=1007,
        !            37:                TOO_BIG=1009,
        !            38:                INTERNAL_ERROR=1011
        !            39:        };
        !            40: 
        !            41:        struct Message {
        !            42:                Opcode opcode;
        !            43:                const char *data;       /// the payload (the reason for CLOSE), valid until the next call
        !            44:                size_t size;
        !            45:                int code;               /// the status of CLOSE
        !            46: 
        !            47:                void set(Opcode aopcode, const char *adata, size_t asize, int acode=0);
        !            48:        };
        !            49: 
        !            50:        /// the status codes that can be sent in Close
        !            51:        static bool valid_status(int code);
        !            52: 
        !            53:        /// the handshake is done
        !            54:        bool accepted;
        !            55:        /// the closing handshake is over: nothing can be received or sent
        !            56:        bool closed;
        !            57: 
        !            58:        WebSocket(HTTPD_Connection &aconnection);
        !            59:        /// sends Close with INTERNAL_ERROR if the connection is not closed: the request has ended with an exception
        !            60:        ~WebSocket();
        !            61: 
        !            62:        /// the handshake response is sent, messages up to max_message_size are received
        !            63:        void start(size_t amax_message_size);
        !            64: 
        !            65:        /// waits up to timeout_ms for the next message, false on timeout; the pings are answered here, the broken connection is the CLOSE message
        !            66:        bool receive(int timeout_ms, Message &message);
        !            67: 
        !            68:        void send(Opcode opcode, const char *data, size_t size);
        !            69: 
        !            70:        /// sends Close and waits for the answer
        !            71:        void close(int code=NORMAL, const char *reason="", size_t reason_size=0);
        !            72: 
        !            73: private:
        !            74: 
        !            75:        struct Frame {
        !            76:                bool fin;
        !            77:                int opcode;
        !            78:                char *payload;
        !            79:                size_t size;
        !            80:        };
        !            81: 
        !            82:        enum Parsed { INCOMPLETE, PARSED, INVALID };
        !            83: 
        !            84:        /// the growing array of bytes, data[pos..size) are not processed yet
        !            85:        struct Buffer {
        !            86:                char *data;
        !            87:                size_t pos, size, allocated;
        !            88: 
        !            89:                Buffer(): data(0), pos(0), size(0), allocated(0) {}
        !            90: 
        !            91:                size_t unread() const { return size-pos; }
        !            92:                void fit(size_t room);
        !            93:                void append(const char *bytes, size_t length);
        !            94:        };
        !            95: 
        !            96:        HTTPD_Connection &connection;
        !            97:        size_t max_message_size;
        !            98: 
        !            99:        Buffer rbuf;                    /// received bytes
        !           100:        size_t need;                    /// bytes of the incomplete frame
        !           101:        bool eof;
        !           102: 
        !           103:        Buffer msg;                     /// the fragments of the message
        !           104:        int msg_opcode;                 /// 0 if there is no fragmented message
        !           105: 
        !           106:        bool close_sent;
        !           107:        int error_code;
        !           108:        const char *error_reason;
        !           109: 
        !           110:        bool fill(int timeout_ms);
        !           111:        Parsed parse(Frame &frame);
        !           112:        Parsed invalid(int code, const char *reason);
        !           113:        bool failed(int code, const char *reason, bool notify, Message &message);
        !           114:        void write_frame(int opcode, const char *data, size_t size);
        !           115:        void send_close(int code, const char *reason, size_t size);
        !           116: };
        !           117: 
        !           118: #endif

E-mail: