[MINOR] check: add redis check support

This patch provides a new "option redis-check" statement to enable server health checks based on redis PING request (http://www.redis.io/commands/ping).
diff --git a/doc/configuration.txt b/doc/configuration.txt
index d2f75a7..f4c1692 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1003,6 +1003,7 @@
 option originalto                         X          X         X         X
 option persist                       (*)  X          -         X         X
 option redispatch                    (*)  X          -         X         X
+option redis-check                        X          -         X         X
 option smtpchk                            X          -         X         X
 option socket-stats                  (*)  X          X         X         -
 option splice-auto                   (*)  X          X         X         X
@@ -3754,6 +3755,23 @@
   See also : "redispatch", "retries", "force-persist"
 
 
+option redis-check
+  Use redis health checks for server testing
+  May be used in sections :   defaults | frontend | listen | backend
+                                 yes   |    no    |   yes  |   yes
+  Arguments : none
+
+  It is possible to test that the server correctly talks REDIS protocol instead
+  of just testing that it accepts the TCP connection. When this option is set,
+  a PING redis command is sent to the server, and the response is analyzed to
+  find the "+PONG" response message.
+
+  Example :
+        option redis-check
+
+  See also : "option httpchk"
+
+
 option smtpchk
 option smtpchk <hello> <domain>
   Use SMTP health checks for server testing
diff --git a/include/common/defaults.h b/include/common/defaults.h
index 96e0f61..0a4f420 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -131,6 +131,7 @@
 #define DEF_CHECK_REQ   "OPTIONS / HTTP/1.0\r\n"
 #define DEF_SMTP_CHECK_REQ   "HELO localhost\r\n"
 #define DEF_LDAP_CHECK_REQ   "\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x03\x04\x00\x80\x00"
+#define DEF_REDIS_CHECK_REQ  "*1\r\n$4\r\nPING\r\n"
 
 #define DEF_HANA_ONERR		HANA_ONERR_FAILCHK
 #define DEF_HANA_ERRLIMIT	10
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 82c3458..b4385a9 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -155,6 +155,7 @@
 #define PR_O2_PGSQL_CHK 0x10000000      /* use PGSQL check for server health */
 #define PR_O2_DISPATCH  0x20000000      /* use dispatch mode */
 #define PR_O2_NODELAY   0x40000000      /* fully interactive mode, never delay outgoing data */
+#define PR_O2_REDIS_CHK 0x80000000      /* use LDAP check for server health */
 /* end of proxy->options2 */
 
 /* bits for sticking rules */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 04373ac..44fc1da 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3260,6 +3260,7 @@
 			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
 			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
 			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options |= PR_O_HTTP_CHK;
 			if (!*args[2]) { /* no argument */
 				curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
@@ -3293,6 +3294,7 @@
 			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
 			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
 			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options2 |= PR_O2_SSL3_CHK;
 		}
 		else if (!strcmp(args[1], "smtpchk")) {
@@ -3304,6 +3306,7 @@
 			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
 			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
 			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options |= PR_O_SMTP_CHK;
 
 			if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
@@ -3334,6 +3337,7 @@
 			curproxy->options &= ~PR_O_SMTP_CHK;
 			curproxy->options2 &= ~PR_O2_SSL3_CHK;
 			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
 			curproxy->options2 |= PR_O2_PGSQL_CHK;
 
@@ -3386,6 +3390,26 @@
 			}
 		}
 
+		else if (!strcmp(args[1], "redis-check")) {
+			/* use REDIS PING request to check servers' health */
+			if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
+				err_code |= ERR_WARN;
+
+			free(curproxy->check_req);
+			curproxy->check_req = NULL;
+			curproxy->options &= ~PR_O_HTTP_CHK;
+			curproxy->options &= ~PR_O_SMTP_CHK;
+			curproxy->options2 &= ~PR_O2_SSL3_CHK;
+			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
+			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
+			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 |= PR_O2_REDIS_CHK;
+
+			curproxy->check_req = (char *) malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
+			memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
+			curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
+		}
+
 		else if (!strcmp(args[1], "mysql-check")) {
 			/* use MYSQL request to check servers' health */
 			if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
@@ -3397,6 +3421,7 @@
 			curproxy->options &= ~PR_O_SMTP_CHK;
 			curproxy->options2 &= ~PR_O2_SSL3_CHK;
 			curproxy->options2 &= ~PR_O2_LDAP_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
 			curproxy->options2 |= PR_O2_MYSQL_CHK;
 
@@ -3469,6 +3494,7 @@
 			curproxy->options2 &= ~PR_O2_SSL3_CHK;
 			curproxy->options2 &= ~PR_O2_MYSQL_CHK;
 			curproxy->options2 &= ~PR_O2_PGSQL_CHK;
+			curproxy->options2 &= ~PR_O2_REDIS_CHK;
 			curproxy->options2 |= PR_O2_LDAP_CHK;
 
 			curproxy->check_req = (char *) malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
diff --git a/src/checks.c b/src/checks.c
index 5bcf47c..50fe2a2 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -773,6 +773,7 @@
 		    (s->proxy->options2 & PR_O2_SSL3_CHK) ||
 		    (s->proxy->options2 & PR_O2_MYSQL_CHK) ||
 		    (s->proxy->options2 & PR_O2_PGSQL_CHK) ||
+		    (s->proxy->options2 & PR_O2_REDIS_CHK) ||
 		    (s->proxy->options2 & PR_O2_LDAP_CHK)) {
 			int ret;
 			const char *check_req = s->proxy->check_req;
@@ -1047,6 +1048,17 @@
 			set_server_check_status(s, HCHK_STATUS_L7STS, desc);
 		}
 	}
+	else if (s->proxy->options2 & PR_O2_REDIS_CHK) {
+		if (!done && s->check_data_len < 7)
+			goto wait_more_data;
+
+		if (strcmp(s->check_data, "+PONG\r\n") == 0) {
+			set_server_check_status(s, HCHK_STATUS_L7OKD, "Redis server is ok");
+		}
+		else {
+			set_server_check_status(s, HCHK_STATUS_L7STS, s->check_data);
+		}
+	}
 	else if (s->proxy->options2 & PR_O2_MYSQL_CHK) {
 		if (!done && s->check_data_len < 5)
 			goto wait_more_data;