diff options
author | silvioprog <silvioprog@gmail.com> | 2020-04-08 14:10:43 -0300 |
---|---|---|
committer | silvioprog <silvioprog@gmail.com> | 2020-04-08 14:10:43 -0300 |
commit | da0585902ce08aacf97f7711b85343d4d45c80fe (patch) | |
tree | f8c5b3f45c6b87e5194d1d8c0cb46e193482f9c1 | |
parent | 2de4ad4cafbe0a017b3494ada2cc430be30fbbf4 (diff) | |
download | libmicrohttpd-da0585902ce08aacf97f7711b85343d4d45c80fe.tar.gz libmicrohttpd-da0585902ce08aacf97f7711b85343d4d45c80fe.zip |
Improved base64-encoder function of the websocket example.
-rw-r--r-- | src/examples/websocket_threaded_example.c | 111 |
1 files changed, 49 insertions, 62 deletions
diff --git a/src/examples/websocket_threaded_example.c b/src/examples/websocket_threaded_example.c index 9133190f..69abb0f3 100644 --- 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, | |||
343 | 343 | ||
344 | /********** begin Base64 **********/ | 344 | /********** begin Base64 **********/ |
345 | 345 | ||
346 | static const unsigned char BASE64_TABLE[65] | 346 | ssize_t |
347 | = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 347 | BASE64Encode (const void *in, size_t len, unsigned char **output) |
348 | |||
349 | static unsigned char * | ||
350 | BASE64Encode (const unsigned char *src, size_t len, size_t *out_len) | ||
351 | { | 348 | { |
352 | const unsigned char *end; | 349 | #define FILLCHAR '=' |
353 | const unsigned char *in; | 350 | const unsigned char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
354 | unsigned char *out; | 351 | "abcdefghijklmnopqrstuvwxyz" |
355 | unsigned char *pos; | 352 | "0123456789+/"; |
356 | size_t olen; | 353 | const unsigned char *data = in; |
357 | int line_len; | 354 | unsigned char *opt; |
358 | olen = len * 4 / 3 + 4; | 355 | ssize_t ret; |
359 | olen += olen / 72; | 356 | ssize_t i; |
360 | olen++; | 357 | char c; |
361 | if (olen < len) | 358 | ret = 0; |
362 | { | 359 | opt = malloc (2 + (len * 4 / 3) + 8); |
363 | return NULL; | 360 | if (NULL == opt) |
364 | } | 361 | { |
365 | out = malloc (olen); | 362 | return -1; |
366 | if (NULL == out) | ||
367 | { | ||
368 | return NULL; | ||
369 | } | ||
370 | end = src + len; | ||
371 | in = src; | ||
372 | pos = out; | ||
373 | line_len = 0; | ||
374 | while (end - in >= 3) | ||
375 | { | ||
376 | *pos++ = BASE64_TABLE[in[0] >> 2]; | ||
377 | *pos++ = BASE64_TABLE[((in[0] & 0x03) << 4) | (in[1] >> 4)]; | ||
378 | *pos++ = BASE64_TABLE[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; | ||
379 | *pos++ = BASE64_TABLE[in[2] & 0x3f]; | ||
380 | in += 3; | ||
381 | line_len += 4; | ||
382 | if (line_len >= 72) | ||
383 | { | ||
384 | *pos++ = '\n'; | ||
385 | line_len = 0; | ||
386 | } | ||
387 | } | 363 | } |
388 | if (end - in) | 364 | for (i = 0; i < len; ++i) |
389 | { | 365 | { |
390 | *pos++ = BASE64_TABLE[in[0] >> 2]; | 366 | c = (data[i] >> 2) & 0x3F; |
391 | if (end - in == 1) | 367 | opt[ret++] = cvt[(unsigned int) c]; |
368 | c = (data[i] << 4) & 0x3F; | ||
369 | if (++i < len) | ||
370 | { | ||
371 | c |= (data[i] >> 4) & 0x0F; | ||
372 | } | ||
373 | opt[ret++] = cvt[(unsigned int) c]; | ||
374 | if (i < len) | ||
392 | { | 375 | { |
393 | *pos++ = BASE64_TABLE[(in[0] & 0x03) << 4]; | 376 | c = (data[i] << 2) & 0x3F; |
394 | *pos++ = '='; | 377 | if (++i < len) |
378 | { | ||
379 | c |= (data[i] >> 6) & 0x03; | ||
380 | } | ||
381 | opt[ret++] = cvt[(unsigned int) c]; | ||
395 | } | 382 | } |
396 | else | 383 | else |
397 | { | 384 | { |
398 | *pos++ = BASE64_TABLE[((in[0] & 0x03) << 4) | (in[1] >> 4)]; | 385 | ++i; |
399 | *pos++ = BASE64_TABLE[(in[1] & 0x0f) << 2]; | 386 | opt[ret++] = FILLCHAR; |
387 | } | ||
388 | if (i < len) | ||
389 | { | ||
390 | c = data[i] & 0x3F; | ||
391 | opt[ret++] = cvt[(unsigned int) c]; | ||
392 | } | ||
393 | else | ||
394 | { | ||
395 | opt[ret++] = FILLCHAR; | ||
400 | } | 396 | } |
401 | *pos++ = '='; | ||
402 | line_len += 4; | ||
403 | } | ||
404 | if (line_len) | ||
405 | { | ||
406 | *pos++ = '\n'; | ||
407 | } | ||
408 | *pos = '\0'; | ||
409 | if (out_len) | ||
410 | { | ||
411 | *out_len = pos - out; | ||
412 | } | 397 | } |
413 | return out; | 398 | *output = opt; |
399 | return ret; | ||
414 | } | 400 | } |
415 | 401 | ||
416 | 402 | ||
@@ -477,6 +463,7 @@ ws_get_accept_value (char *key, unsigned char **val) | |||
477 | struct SHA1Context ctx; | 463 | struct SHA1Context ctx; |
478 | unsigned char hash[SHA1HashSize]; | 464 | unsigned char hash[SHA1HashSize]; |
479 | char *str; | 465 | char *str; |
466 | ssize_t len; | ||
480 | if (NULL == key) | 467 | if (NULL == key) |
481 | { | 468 | { |
482 | return MHD_NO; | 469 | return MHD_NO; |
@@ -492,12 +479,12 @@ ws_get_accept_value (char *key, unsigned char **val) | |||
492 | SHA1Input (&ctx, (const uint8_t *) str, WS_KEY_GUID_LEN); | 479 | SHA1Input (&ctx, (const uint8_t *) str, WS_KEY_GUID_LEN); |
493 | SHA1Result (&ctx, hash); | 480 | SHA1Result (&ctx, hash); |
494 | free (str); | 481 | free (str); |
495 | *val = BASE64Encode (hash, SHA1HashSize, NULL); | 482 | len = BASE64Encode (hash, SHA1HashSize, val); |
496 | if (NULL == *val) | 483 | if (-1 == len) |
497 | { | 484 | { |
498 | return MHD_NO; | 485 | return MHD_NO; |
499 | } | 486 | } |
500 | *(*val + strlen ((const char *) *val) - 1) = '\0'; | 487 | (*val)[len] = '\0'; |
501 | return MHD_YES; | 488 | return MHD_YES; |
502 | } | 489 | } |
503 | 490 | ||