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
- Implement param parser
-- Properly decode paths
+URL encoder/decoder
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