mod_netconf, test-client: JSON messages are now encoded using Chunked Framing Mechanism before sending over UNIX socket.
diff --git a/src/README b/src/README
index 08ea6b4..dceacbc 100644
--- a/src/README
+++ b/src/README
@@ -20,8 +20,10 @@
 --------------------------
 
 UNIX socket (with default path /tmp/mod_netconf.sock) is used for communication
-with mod_netconf daemon. Messages are formated using JSON with the following
-content. Client is free to send multiple requests when the communication socket
+with mod_netconf daemon. Messages are formated using JSON and encoded using
+Chunked Framing Mechanism described in RFC6242 (http://tools.ietf.org/html/rfc6242#section-4.2)
+with the following content.
+Client is free to send multiple requests when the communication socket
 to the mod_netconf daemon is opened.
 
 Replies
diff --git a/src/mod_netconf.c b/src/mod_netconf.c
index ceff507..c9cfecd 100644
--- a/src/mod_netconf.c
+++ b/src/mod_netconf.c
@@ -767,27 +767,51 @@
 		buffer_len = 0;
 		buffer = NULL;
 		while (1) {
-			fds.fd = client;
-			fds.events = POLLIN;
-			fds.revents = 0;
-
-			status = poll(&fds, 1, 1000);
-
-			if (status == 0 || (status == -1 && (errno == EAGAIN || (errno == EINTR && isterminated == 0)))) {
-				/* poll was interrupted - check if the isterminated is set and if not, try poll again */
-				//ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "poll interrupted");
-				continue;
-			} else if (status < 0) {
-				/* 0:  poll time outed
-				 *     close socket and ignore this request from the client, it can try it again
-				 * -1: poll failed
-				 *     something wrong happend, close this socket and wait for another request
-				 */
-				//ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "poll failed, status %d(%d: %s)", status, errno, strerror(errno));
-				close(client);
+			/* read chunk length */
+			if ((ret = recv (client, &c, 1, 0)) != 1 || c != '\n') {
+				free (buffer);
+				buffer = NULL;
 				break;
 			}
-			/* status > 0 */
+			if ((ret = recv (client, &c, 1, 0)) != 1 || c != '#') {
+				free (buffer);
+				buffer = NULL;
+				break;
+			}
+			i=0;
+			memset (chunk_len_str, 0, 12);
+			while ((ret = recv (client, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
+				if (i==0 && c == '#') {
+					if (recv (client, &c, 1, 0) != 1 || c != '\n') {
+						/* end but invalid */
+						free (buffer);
+						buffer = NULL;
+					}
+					/* end of message, double-loop break */
+					goto msg_complete;
+				}
+				chunk_len_str[i++] = c;
+			}
+			if (c != '\n') {
+				free (buffer);
+				buffer = NULL;
+				break;
+			}
+			if ((chunk_len = atoi (chunk_len_str)) == 0) {
+				free (buffer);
+				buffer = NULL;
+				break;
+			}
+			buffer_size += chunk_len+1;
+			buffer = realloc (buffer, sizeof(char)*buffer_size);
+			if ((ret = recv (client, buffer+buffer_len, chunk_len, 0)) == -1 || ret != chunk_len) {
+				free (buffer);
+				buffer = NULL;
+				break;
+			}
+			buffer_len += ret;
+		}
+msg_complete:
 
 		if (buffer != NULL) {
 			request = json_tokener_parse(buffer);
@@ -1172,14 +1196,19 @@
 			}
 			json_object_put(request);
 
-				/* send reply to caller */
-				if (reply != NULL) {
-					msgtext = json_object_to_json_string(reply);
-					send(client, msgtext, strlen(msgtext) + 1, 0);
-					json_object_put(reply);
-				} else {
+			/* send reply to caller */
+			if (reply != NULL) {
+				msgtext = json_object_to_json_string(reply);
+				if (asprintf (&chunked_msg, "\n#%d\n%s\n##\n", (int)strlen(msgtext), msgtext) == -1) {
+					free (buffer);
 					break;
 				}
+				send(client, chunked_msg, strlen(chunked_msg) + 1, 0);
+				json_object_put(reply);
+				free (chunked_msg);
+				free (buffer);
+			} else {
+				break;
 			}
 		}
 	}
diff --git a/src/test-client.c b/src/test-client.c
index 5ae3501..0c3fa75 100644
--- a/src/test-client.c
+++ b/src/test-client.c
@@ -41,6 +41,7 @@
  *
  */
 
+#define _GNU_SOURCE
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -50,9 +51,10 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <json/json.h>
+#include <ctype.h>
 
 #define SOCKET_FILENAME "/tmp/mod_netconf.sock"
-#define BUFFER_SIZE 4096
+#define BUFFER_SIZE 40960
 
 typedef enum MSG_TYPE {
 	REPLY_OK,
@@ -98,9 +100,11 @@
 	int sock;
 	struct sockaddr_un addr;
 	size_t len;
-	char buffer[BUFFER_SIZE];
-	char* line = NULL;
+	char *buffer;
+	char* line = NULL, *chunked_msg_text;
 	int i, alen;
+	int buffer_size, buffer_len, ret, chunk_len;
+	char c, chunk_len_str[12];
 
 	if (argc != 2) {
 		print_help(argv[0]);
@@ -342,23 +346,79 @@
 	/* send the message */
 	if (msg != NULL) {
 		msg_text = json_object_to_json_string(msg);
+		asprintf (&chunked_msg_text, "\n#%d\n%s\n##\n", (int)strlen(msg_text), msg_text);
 
 		if (json_object_object_get(msg, "pass") == NULL) {
 			/* print message only if it does not contain password */
 			printf("Sending: %s\n", msg_text);
 		}
-		send(sock, msg_text, strlen(msg_text) + 1, 0);
+		send(sock, chunked_msg_text, strlen(chunked_msg_text) + 1, 0);
 
 		json_object_put(msg);
+		free (chunked_msg_text);
 	} else {
 		close(sock);
 		return (EXIT_FAILURE);
 	}
 
-	len = recv(sock, buffer, BUFFER_SIZE, 0);
-	if (len > 0) {
-		reply = json_tokener_parse(buffer);
+	/* read json in chunked framing */
+	buffer_size = 0;
+	buffer_len = 0;
+	buffer = NULL;
+	while (1) {
+		/* read chunk length */
+		if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '\n') {
+			free (buffer);
+			buffer = NULL;
+			break;
+		}
+		if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '#') {
+			free (buffer);
+			buffer = NULL;
+			break;
+		}
+		i=0;
+		memset (chunk_len_str, 0, 12);
+		while ((ret = recv (sock, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
+			if (i==0 && c == '#') {
+				if (recv (sock, &c, 1, 0) != 1 || c != '\n') {
+					/* end but invalid */
+					free (buffer);
+					buffer = NULL;
+				}
+				/* end of message, double-loop break */
+				goto msg_complete;
+			}
+			chunk_len_str[i++] = c;
+		}
+		if (c != '\n') {
+			free (buffer);
+			buffer = NULL;
+			break;
+		}
+		if ((chunk_len = atoi (chunk_len_str)) == 0) {
+			free (buffer);
+			buffer = NULL;
+			break;
+		}
+		buffer_size += chunk_len+1;
+		buffer = realloc (buffer, sizeof(char)*buffer_size);
+		if ((ret = recv (sock, buffer+buffer_len, chunk_len, 0)) == -1 || ret != chunk_len) {
+			free (buffer);
+			buffer = NULL;
+			break;
+		}
+		buffer_len += ret;
 	}
+msg_complete:
+
+	if (buffer != NULL) {
+		reply = json_tokener_parse(buffer);
+		free (buffer);
+	} else {
+		reply = NULL;
+	}
+
 	printf("Received:\n");
 	if (reply == NULL) {
 		printf("(null)\n");