From c607ba05a99e4542ac8781039079a04dda8d5432 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Tue, 6 Sep 2022 20:48:27 -0400 Subject: [PATCH] Implement URL encoding and decoding. --- site/index.html | 2 +- src/Http.c | 149 +++++++++++++++++++++++++++++++++++++++++++++ src/HttpServer.c | 2 +- src/include/Http.h | 6 ++ 4 files changed, 157 insertions(+), 2 deletions(-) diff --git a/site/index.html b/site/index.html index 4dea0de..2b19411 100644 --- a/site/index.html +++ b/site/index.html @@ -494,7 +494,7 @@ can get involved.
  • Implement a simple HTTP server
  • diff --git a/src/Http.c b/src/Http.c index c0c49f2..4b9db64 100644 --- a/src/Http.c +++ b/src/Http.c @@ -23,6 +23,8 @@ */ #include +#include +#include #include 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; +} diff --git a/src/HttpServer.c b/src/HttpServer.c index b9dc91b..9024be6 100644 --- a/src/HttpServer.c +++ b/src/HttpServer.c @@ -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; } diff --git a/src/include/Http.h b/src/include/Http.h index ae71399..5a6a607 100644 --- a/src/include/Http.h +++ b/src/include/Http.h @@ -109,4 +109,10 @@ extern HttpRequestMethod extern const char * HttpRequestMethodToString(const HttpRequestMethod); +extern char * + HttpUrlEncode(char *); + +extern char * + HttpUrlDecode(char *); + #endif