Skip to content
Snippets Groups Projects
Commit 18f34786 authored by aticu's avatar aticu
Browse files

Add percent decoding to the POST handler

parent 4df4deef
No related branches found
No related tags found
No related merge requests found
......@@ -132,3 +132,49 @@ void webserver_run(request_handler handler) {
free(data);
}
}
uint32_t webserver_percent_decode(char *data, uint32_t len) {
// Decode in-place according to https://url.spec.whatwg.org/#percent-decode and https://url.spec.whatwg.org/#urlencoded-parsing
// The in-place decoding works, because in_index can only be "faster" than out_index, not "slower".
// The new length is returned.
// If The length is reduced, a '\0'-byte is appended at the end, but not included with the length.
uint32_t in_index = 0, out_index = 0;
while(in_index < len) {
if(data[in_index] == '+') {
data[out_index] = ' ';
} else if(data[in_index] == '%' && in_index + 2 < len) {
char bytes[2];
for(int i = 0; i < 2; ++i) {
if('0' <= data[in_index + i + 1] && data[in_index + i + 1] <= '9') {
bytes[i] = data[in_index + i + 1] - '0';
} else if('a' <= data[in_index + i + 1] && data[in_index + i + 1] <= 'f') {
bytes[i] = data[in_index + i + 1] - 'a' + 10;
} else if('A' <= data[in_index + i + 1] && data[in_index + i + 1] <= 'F') {
bytes[i] = data[in_index + i + 1] - 'A' + 10;
} else {
bytes[i] = 16;
}
}
if(bytes[0] == 16 || bytes[1] == 16) {
data[out_index] = data[in_index];
} else {
data[out_index] = (bytes[0] << 4) | bytes[1];
in_index += 2;
}
} else {
data[out_index] = data[in_index];
}
++in_index;
++out_index;
}
if(out_index < in_index) {
data[out_index] = '\0';
}
return out_index;
}
......@@ -41,5 +41,8 @@ typedef char *(*request_handler)(char *location, enum request_type type, char *d
int webserver_init(struct network_implementation network);
// Runs the webserver with the given request handling function.
void webserver_run(request_handler handler);
// Percent decodes the given data in-place returning the new length.
// Also appends a '\0'-byte, if the output is shorter than the input.
uint32_t webserver_percent_decode(char *data, uint32_t len);
#endif /* WEBSERVER_H_ */
......@@ -50,12 +50,14 @@ char *server_request_handler(char *location, enum request_type type, char *data,
return http_prepare_response(INDEX_PAGE, strlen(INDEX_PAGE), 200, out_len);
} else if(type == POST_REQUEST && strncmp(location, "/", 2) == 0) {
if(data_len >= 5 && strncmp(data, "name=", 5) == 0) {
uint32_t name_len = data_len - 5;
name_len = webserver_percent_decode(&data[5], name_len);
// nobody could possibly enter a name longer than 20 characters, so this buffer
// is definitely large enough
char message[28];
memcpy(message, "Hallo, ", 7);
memcpy(message + 7, &data[5], data_len - 5);
*(message + 7 + data_len - 5) = 0;
memcpy(message + 7, &data[5], name_len);
*(message + 7 + name_len) = 0;
return http_prepare_response(message, strlen(message), 200, out_len);
} else {
return http_prepare_response(RESPONSE_404, strlen(RESPONSE_404), 404, out_len);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment