forked from Telodendria/Telodendria
Implement URL encoding and decoding.
This commit is contained in:
parent
2ba2656e4a
commit
c607ba05a9
4 changed files with 157 additions and 2 deletions
|
@ -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>
|
||||
|
|
149
src/Http.c
149
src/Http.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -109,4 +109,10 @@ extern HttpRequestMethod
|
|||
extern const char *
|
||||
HttpRequestMethodToString(const HttpRequestMethod);
|
||||
|
||||
extern char *
|
||||
HttpUrlEncode(char *);
|
||||
|
||||
extern char *
|
||||
HttpUrlDecode(char *);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue