diff --git a/ArtyImplementation/.cproject b/ArtyImplementation/.cproject
index 4118e09324606aaaad9c6b8217c7845f1506334d..0c3a2c480672f32b4af1cda2b32ed3ce41fd8195 100644
--- a/ArtyImplementation/.cproject
+++ b/ArtyImplementation/.cproject
@@ -45,11 +45,11 @@
                             							
                             <targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.1356856028" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform"/>
                             							
-                            <builder id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.1966928500" name="Autotools Makefile Generator.Build (GNU)" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder"/>
+                            <builder id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.1966928500" keepEnvironmentInBuildfile="false" name="Autotools Makefile Generator" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder"/>
                             							
                             <tool id="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure.1370538481" name="configure" superClass="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure">
                                 								
-                                <option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.1547520623" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.14833071" valueType="string"/>
+                                <option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.1547520623" name="Name" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.14833071" valueType="string"/>
                                 							
                             </tool>
                             							
@@ -113,7 +113,7 @@
             			
             <storageModule moduleId="cdtBuildSystem" version="4.0.0">
                 				
-                <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1819037516" name="Debug (GNU)" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug">
+                <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.linuxtools.cdt.autotools.core.buildArtefactType.autotools,org.eclipse.cdt.build.core.buildType=org.eclipse.linuxtools.cdt.autotools.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1819037516" name="Debug (GNU)" optionalBuildProperties="" parent="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug">
                     					
                     <folderInfo id="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1819037516." name="/" resourcePath="">
                         						
@@ -121,13 +121,13 @@
                             							
                             <targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.debug.374872327" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.debug"/>
                             							
-                            <builder id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.debug.738536384" name="Autotools Makefile Generator.Debug (GNU)" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.debug"/>
+                            <builder id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.debug.738536384" keepEnvironmentInBuildfile="false" name="Autotools Makefile Generator" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.debug"/>
                             							
                             <tool id="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure.debug.2083164547" name="configure" superClass="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure.debug">
                                 								
-                                <option defaultValue="CFLAGS=-g -O0" id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.user.149937447" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.user" valueType="string"/>
+                                <option defaultValue="CFLAGS=-g -O0" id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.user.149937447" name="User-specified configuration options" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.user" valueType="string"/>
                                 								
-                                <option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.2101311718" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1819037516" valueType="string"/>
+                                <option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.2101311718" name="Name" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.configuration.build.debug.1819037516" valueType="string"/>
                                 							
                             </tool>
                             							
diff --git a/ArtyImplementation/bsp/X300/multizone.cfg b/ArtyImplementation/bsp/X300/multizone.cfg
index 26e9df78cc5f1f74688801a8f1489cc894f05ae8..e6db83e217035a3c7b98fea6c06d7fcdcadd103b 100644
--- a/ArtyImplementation/bsp/X300/multizone.cfg
+++ b/ArtyImplementation/bsp/X300/multizone.cfg
@@ -6,7 +6,7 @@ Tick = 10 # ms
 
 Zone = 1
 	plic = 21 # ETHERNET 
-	base = 0x20440000; size =     128K; rwx = rx # FLASH 
+	base = 0x20440000; size =     128K; rwx = rwx # FLASH 
 	base = 0x80001800; size =      38K; rwx = rw # RAM
 	base = 0x8000B000; size =       2K; rwx = w  # SH BUFF1
 	base = 0x8000B800; size =       8K; rwx = w  # SH BUFF2
@@ -17,4 +17,4 @@ Zone = 2
 	irq  = 3 # DMA
 	base = 0x20401800; size =      26K; rwx = rx # FLASH
 	base = 0x8000D800; size =       4K; rwx = rw # RAM
-	base = 0x10013000; size =    0x100; rwx = rw # UART
\ No newline at end of file
+	base = 0x10013000; size =    0x100; rwx = rw # UART
diff --git a/ArtyImplementation/bsp/X300/openocd.cfg b/ArtyImplementation/bsp/X300/openocd.cfg
index 0a6e756c8ac709acc794ae65759927f8fd672ffb..e39384b8ec31b72a362f0064927bacc0f364b180 100644
--- a/ArtyImplementation/bsp/X300/openocd.cfg
+++ b/ArtyImplementation/bsp/X300/openocd.cfg
@@ -4,6 +4,7 @@ adapter_khz 10000
 
 interface ftdi
 ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
+#ftdi_device_desc "Olimex Ltd. ARM-USB-TINY-H JTAG interface"
 ftdi_vid_pid 0x15ba 0x002a
 
 ftdi_layout_init 0x0808 0x0a1b
diff --git a/ArtyImplementation/zone1/Makefile b/ArtyImplementation/zone1/Makefile
index 8c7e27ad81982316aac6ce4f0d32f270a8bce228..174c6523e0141c1528ef363b8213531a8a37337f 100644
--- a/ArtyImplementation/zone1/Makefile
+++ b/ArtyImplementation/zone1/Makefile
@@ -2,13 +2,15 @@
 
 TARGET = zone1.elf
 
-C_SRCS += main.c tcp_cb.c queue.c
+C_SRCS += main.c tcp_cb.c queue.c http_helpers.c webserver.c
 
 INCLUDES += -I ../ext
 INCLUDES += -I ../ext/multizone
 INCLUDES += -I ../ext/lwip/src/include
 INCLUDES += -I ../ext/mbedtls/include
 
+C_FLAGS+="-g"
+
 LINKER_SCRIPT := linker.lds
 
 ### BSP
diff --git a/ArtyImplementation/zone1/tcp_cb.c b/ArtyImplementation/zone1/tcp_cb.c
index 22cd933686517e2df0880471b69adc1180629666..3750ccae2b6dde90f6cbd546f5163398657e719b 100644
--- a/ArtyImplementation/zone1/tcp_cb.c
+++ b/ArtyImplementation/zone1/tcp_cb.c
@@ -13,7 +13,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 //for enums
-#include "webserver.h"
+#include "server_utility.h"
 
 
 static err_t tcp_cb_parse_http(struct altcp_pcb *package_control_block, struct tcp_cb_state *tcp_state, struct pbuf *package_buffer)
@@ -42,6 +42,8 @@ static err_t tcp_cb_parse_http(struct altcp_pcb *package_control_block, struct t
 		//drop
 		return ERR_OK;
 	}
+	char *location = current_position;
+
 	while(current_position < end_ptr && *current_position != ' ') {
 		++current_position;
 	}
@@ -80,21 +82,19 @@ static err_t tcp_cb_parse_http(struct altcp_pcb *package_control_block, struct t
 			return ERR_VAL;
 		}
 
-
-		//we have no handler, so from here in it differs
-		//mainly the same as the server_resp in wifi_exploit.c
-
-		if(request_type == GET_REQUEST) {
-			char *get_response =
-					"HTTP/1.1 200 OK\r\n"
-					"Content-Length: 15\r\n"
-					"Connection: Close\r\n"
-					"\r\n"
-					"Hello, World!"
-					"\r\n";
-
-			error_rv = altcp_write(package_control_block, get_response, strlen(get_response)+1, 0);
+		uint32_t outlen = 0;
+		bool free_result = false;
+		char* response = server_request_handler(location, request_type, current_position, length, &outlen, &free_result);
+		error_rv = altcp_write(
+			package_control_block
+			, response
+			, outlen
+			, 0
+		);
+		if(free_result) {
+			free(response);
 		}
+
 		return error_rv;
 }
 
@@ -218,7 +218,7 @@ static err_t tcp_cb_poll(void *arg, struct altcp_pcb *package_control_block)
 		}
 	}
 	else {
-		tcp_abort(package_control_block);
+		altcp_abort(package_control_block);
 		tcp_cb_close(package_control_block, tcp_state);
 		error_rv = ERR_ABRT;
 	}
diff --git a/ArtyImplementation/zone1/webserver.c b/ArtyImplementation/zone1/webserver.c
index dcd921c9450722fcf5f8b9972195ed377314f54b..e124805eb623f87f6a2fea4850dcb78110666e17 100644
--- a/ArtyImplementation/zone1/webserver.c
+++ b/ArtyImplementation/zone1/webserver.c
@@ -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;
+}
diff --git a/ArtyImplementation/zone1/webserver.h b/ArtyImplementation/zone1/webserver.h
index 0f64b6c8c1cc24eb709cd453218319abd4865024..6aa68d1bd3aae06f9dcc603a217ed7504b6707de 100644
--- a/ArtyImplementation/zone1/webserver.h
+++ b/ArtyImplementation/zone1/webserver.h
@@ -41,7 +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);
-
-void webserver_handle_request(request_handler handler, int id, uint32_t len, char *data);
+// 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_ */