On a recent IoT-Project I did, when working with the ESP32 and the associated WiFi-Chip, I found myself struggling to correctly decode and interpret the submitted URL, especially the URL-parameters. To make lives easier, I decided to write a quick post about how I decode and interpret URLs on an ESP32 in my projects.
First, we’ll define the header file and the API we want to expose:
// decode.h
#include <string.h>
#include <ctype.h>
void url_decode(char *source, char *target);
The caller has to allocate and provide both the source- and target-string. We also include ctype.h
and string.h
for functions we need later on. The function itself is pretty straight forward: We iterate over the source-string and start filling the target string with either the byte from the source-string or, if we encounter an encoded section, the correctly decoded byte.
// decode.c
#include "decode.h"
void url_decode(char *source, char *target)
{
while (*source)
{
if (*source == '%')
{
if (source[1] && source[2])
{
*target++ = from_hex(source[1]) << 4 | from_hex(source[2]);
source += 2;
}
}
else if (*source == '+')
{
*target++ = ' ';
}
else
{
*target++ = *source;
}
source++;
}
*target = '\0';
}
The from_hex
-function looks like this:
// decode.c
char from_hex(char ch)
{
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}
It returns the correct character based on the hex-byte it was given. If we encounter %23
in the source-string, from_hex
will first return 0b00000010
and then 0b00000011
, resulting in #
if put together (0b0010
+ 0b0011
).