libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit da0585902ce08aacf97f7711b85343d4d45c80fe
parent 2de4ad4cafbe0a017b3494ada2cc430be30fbbf4
Author: silvioprog <silvioprog@gmail.com>
Date:   Wed,  8 Apr 2020 14:10:43 -0300

Improved base64-encoder function of the websocket example.

Diffstat:
Msrc/examples/websocket_threaded_example.c | 111+++++++++++++++++++++++++++++++++++--------------------------------------------
1 file changed, 49 insertions(+), 62 deletions(-)

diff --git a/src/examples/websocket_threaded_example.c b/src/examples/websocket_threaded_example.c @@ -343,74 +343,60 @@ SHA1Input (struct SHA1Context *context, const uint8_t *message_array, /********** begin Base64 **********/ -static const unsigned char BASE64_TABLE[65] - = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static unsigned char * -BASE64Encode (const unsigned char *src, size_t len, size_t *out_len) +ssize_t +BASE64Encode (const void *in, size_t len, unsigned char **output) { - const unsigned char *end; - const unsigned char *in; - unsigned char *out; - unsigned char *pos; - size_t olen; - int line_len; - olen = len * 4 / 3 + 4; - olen += olen / 72; - olen++; - if (olen < len) - { - return NULL; - } - out = malloc (olen); - if (NULL == out) - { - return NULL; - } - end = src + len; - in = src; - pos = out; - line_len = 0; - while (end - in >= 3) - { - *pos++ = BASE64_TABLE[in[0] >> 2]; - *pos++ = BASE64_TABLE[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = BASE64_TABLE[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; - *pos++ = BASE64_TABLE[in[2] & 0x3f]; - in += 3; - line_len += 4; - if (line_len >= 72) - { - *pos++ = '\n'; - line_len = 0; - } +#define FILLCHAR '=' + const unsigned char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + const unsigned char *data = in; + unsigned char *opt; + ssize_t ret; + ssize_t i; + char c; + ret = 0; + opt = malloc (2 + (len * 4 / 3) + 8); + if (NULL == opt) + { + return -1; } - if (end - in) + for (i = 0; i < len; ++i) { - *pos++ = BASE64_TABLE[in[0] >> 2]; - if (end - in == 1) + c = (data[i] >> 2) & 0x3F; + opt[ret++] = cvt[(unsigned int) c]; + c = (data[i] << 4) & 0x3F; + if (++i < len) + { + c |= (data[i] >> 4) & 0x0F; + } + opt[ret++] = cvt[(unsigned int) c]; + if (i < len) { - *pos++ = BASE64_TABLE[(in[0] & 0x03) << 4]; - *pos++ = '='; + c = (data[i] << 2) & 0x3F; + if (++i < len) + { + c |= (data[i] >> 6) & 0x03; + } + opt[ret++] = cvt[(unsigned int) c]; } else { - *pos++ = BASE64_TABLE[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = BASE64_TABLE[(in[1] & 0x0f) << 2]; + ++i; + opt[ret++] = FILLCHAR; + } + if (i < len) + { + c = data[i] & 0x3F; + opt[ret++] = cvt[(unsigned int) c]; + } + else + { + opt[ret++] = FILLCHAR; } - *pos++ = '='; - line_len += 4; - } - if (line_len) - { - *pos++ = '\n'; - } - *pos = '\0'; - if (out_len) - { - *out_len = pos - out; } - return out; + *output = opt; + return ret; } @@ -477,6 +463,7 @@ ws_get_accept_value (char *key, unsigned char **val) struct SHA1Context ctx; unsigned char hash[SHA1HashSize]; char *str; + ssize_t len; if (NULL == key) { return MHD_NO; @@ -492,12 +479,12 @@ ws_get_accept_value (char *key, unsigned char **val) SHA1Input (&ctx, (const uint8_t *) str, WS_KEY_GUID_LEN); SHA1Result (&ctx, hash); free (str); - *val = BASE64Encode (hash, SHA1HashSize, NULL); - if (NULL == *val) + len = BASE64Encode (hash, SHA1HashSize, val); + if (-1 == len) { return MHD_NO; } - *(*val + strlen ((const char *) *val) - 1) = '\0'; + (*val)[len] = '\0'; return MHD_YES; }