Implement URL encoding and decoding.

This commit is contained in:
Jordan Bancino 2022-09-06 20:48:27 -04:00
parent 2ba2656e4a
commit c607ba05a9
4 changed files with 157 additions and 2 deletions

View file

@ -494,7 +494,7 @@ can get involved.
<li><s>Implement a simple HTTP server</s>
<ul>
<li>Implement param parser</li>
<li>Properly decode paths</li>
<li><s>URL encoder/decoder</s></li>
</ul>
</li>
<li>

View file

@ -23,6 +23,8 @@
*/
#include <Http.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *
@ -211,3 +213,150 @@ HttpStatusToString(const HttpStatus status)
return NULL;
}
}
char *
HttpUrlEncode(char *str)
{
size_t size;
size_t len;
char *encoded;
if (!str)
{
return NULL;
}
size = 16;
len = 0;
encoded = malloc(size);
if (!encoded)
{
return NULL;
}
while (*str)
{
char c = *str;
if (len >= size - 4)
{
char *tmp;
size *= 2;
tmp = realloc(encoded, size);
if (!tmp)
{
free(encoded);
return NULL;
}
encoded = tmp;
}
/* Control characters and extended characters */
if (c <= 0x1F || c >= 0x7F)
{
goto percentEncode;
}
/* Reserved and unsafe characters */
switch (c)
{
case '$':
case '&':
case '+':
case ',':
case '/':
case ':':
case ';':
case '=':
case '?':
case '@':
case ' ':
case '"':
case '<':
case '>':
case '#':
case '%':
case '{':
case '}':
case '|':
case '\\':
case '^':
case '~':
case '[':
case ']':
case '`':
goto percentEncode;
break;
default:
encoded[len] = c;
len++;
str++;
continue;
}
percentEncode:
encoded[len] = '%';
len++;
snprintf(encoded + len, 3, "%2X", c);
len += 2;
str++;
}
encoded[len] = '\0';
return encoded;
}
char *
HttpUrlDecode(char *str)
{
size_t i;
size_t inputLen;
char *decoded;
if (!str)
{
return NULL;
}
i = 0;
inputLen = strlen(str);
decoded = malloc(inputLen);
if (!decoded)
{
return NULL;
}
while (*str)
{
char c = *str;
if (c == '%')
{
if (sscanf(str + 1, "%2X", (unsigned int *) &c) != 1)
{
/* Decoding error */
free(decoded);
return NULL;
}
str += 2;
if (!c)
{
/* Null character given, don't put that in the string. */
str++;
continue;
}
}
decoded[i] = c;
i++;
str++;
}
return decoded;
}

View file

@ -102,7 +102,7 @@ HttpServerContextCreate(HttpRequestMethod requestMethod,
c->requestMethod = requestMethod;
c->requestPath = requestPath;
c->stream = stream;
c->responseStatus = HTTP_OK;
c->responseStatus = HTTP_OK;
return c;
}

View file

@ -109,4 +109,10 @@ extern HttpRequestMethod
extern const char *
HttpRequestMethodToString(const HttpRequestMethod);
extern char *
HttpUrlEncode(char *);
extern char *
HttpUrlDecode(char *);
#endif