agoo_ws_decode(char *buf, size_t mlen) {
    uint8_t	*b = (uint8_t*)buf;
    bool	is_masked;
    uint8_t	*payload;
    uint64_t	plen;

    b++; // op
    is_masked = 0x80 & *b;
    plen = 0x7F & *b;
    b++;
    if (126 == plen) {
	plen = *b++;
	plen = (plen << 8) | *b++;
    } else if (127 == plen) {
	plen = *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
    }
    if (is_masked) {
	uint8_t		mask[4];
	uint64_t	i;

	for (i = 0; i < 4; i++, b++) {
	    mask[i] = *b;
	}
	payload = b;
	for (i = 0; i < plen; i++, b++) {
	    *b = *b ^ mask[i % 4];
	}
    } else {
	payload = b;
	b += plen;
    }
    memmove(buf, payload, plen);
    buf[plen] = '\0';

    return plen;
}
agoo_ws_decode(char *buf, size_t mlen) {
    uint8_t	*b = (uint8_t*)buf;
    bool	is_masked;
    uint8_t	*payload;
    uint64_t	plen;

    b++;  
    is_masked = 0x80 & *b;
    plen = 0x7F & *b;
    b++;
    if (126 == plen) {
	plen = *b++;
	plen = (plen << 8) | *b++;
    } else if (127 == plen) {
	plen = *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
	plen = (plen << 8) | *b++;
    }
    if (is_masked) {
	uint8_t		mask[4];
	uint64_t	i;

	for (i = 0; i < 4; i++, b++) {
	    mask[i] = *b;
	}
	payload = b;
	for (i = 0; i < plen; i++, b++) {
	    *b = *b ^ mask[i % 4];
	}
    } else {
	payload = b;
	b += plen;
    }
    memmove(buf, payload, plen);
    buf[plen] = '\0';

    return plen;
}