Permalink
Browse files

add check type of pop3 and imap, tag v0.19

  • Loading branch information...
1 parent 4f3868e commit df22ece360bf59c288e528aebe76fac441617c7a @yaoweibin committed Apr 6, 2010
Showing with 280 additions and 3 deletions.
  1. +8 −3 README
  2. +174 −0 ngx_tcp_upstream_check.c
  3. +2 −0 ngx_tcp_upstream_check.h
  4. +48 −0 test/t/imap_check.t
  5. +48 −0 test/t/pop3_check.t
View
11 README
@@ -58,7 +58,7 @@ Description
upstream server health check, status monitor.
The motivation of writing these modules is Nginx's high performance and
- robustness. It's more scalable in the SMP system when compared with HAProxy.
+ robustness.
Directives
@@ -144,7 +144,7 @@ Directives
==check==
syntax: check interval=milliseconds [fall=count] [rise=count]
- [timeout=milliseconds] [type=tcp|ssl_hello|smtp|mysql]
+ [timeout=milliseconds] [type=tcp|ssl_hello|smtp|mysql|pop3|imap]
default: none, if parameters omitted, default parameters are 'interval=30000
fall=5 rise=2 timeout=1000'
context: upstream
@@ -165,9 +165,14 @@ Directives
response to diagnose if the upstream server is alive.
'smtp' sends a smtp requst packet, recvives and parses the smtp
response to diagnose if the upstream server is alive. The response
- begins with '2' will be judged to be a OK response.
+ begins with '2' should be an OK response.
'mysql' connects to the mysql server, recvives the greeting response
to diagnose if the upstream server is alive.
+ 'pop3' recvives and parses the pop3 response to diagnose if the
+ upstream server is alive. The response begins with '+' should be an
+ OK response.
+ 'imap' connects to the imap server, recvives the greeting response
+ to diagnose if the upstream server is alive.
==check_http_send=
syntax: check_http_send http_packet
View
@@ -32,6 +32,14 @@ static ngx_int_t ngx_tcp_check_mysql_init(ngx_tcp_check_peer_conf_t *peer_conf);
static ngx_int_t ngx_tcp_check_mysql_parse(ngx_tcp_check_peer_conf_t *peer_conf);
static void ngx_tcp_check_mysql_reinit(ngx_tcp_check_peer_conf_t *peer_conf);
+static ngx_int_t ngx_tcp_check_pop3_init(ngx_tcp_check_peer_conf_t *peer_conf);
+static ngx_int_t ngx_tcp_check_pop3_parse(ngx_tcp_check_peer_conf_t *peer_conf);
+static void ngx_tcp_check_pop3_reinit(ngx_tcp_check_peer_conf_t *peer_conf);
+
+static ngx_int_t ngx_tcp_check_imap_init(ngx_tcp_check_peer_conf_t *peer_conf);
+static ngx_int_t ngx_tcp_check_imap_parse(ngx_tcp_check_peer_conf_t *peer_conf);
+static void ngx_tcp_check_imap_reinit(ngx_tcp_check_peer_conf_t *peer_conf);
+
static char * ngx_tcp_upstream_check_status_set_status(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
@@ -134,6 +142,31 @@ static check_conf_t ngx_check_types[] = {
ngx_tcp_check_mysql_reinit,
1
},
+ {
+ NGX_TCP_CHECK_POP3,
+ "pop3",
+ ngx_null_string,
+ 0,
+ ngx_tcp_check_send_handler,
+ ngx_tcp_check_recv_handler,
+ ngx_tcp_check_pop3_init,
+ ngx_tcp_check_pop3_parse,
+ ngx_tcp_check_pop3_reinit,
+ 1
+ },
+ {
+ NGX_TCP_CHECK_IMAP,
+ "imap",
+ ngx_null_string,
+ 0,
+ ngx_tcp_check_send_handler,
+ ngx_tcp_check_recv_handler,
+ ngx_tcp_check_imap_init,
+ ngx_tcp_check_imap_parse,
+ ngx_tcp_check_imap_reinit,
+ 1
+ },
+
{0, "", ngx_null_string, 0, NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -915,6 +948,12 @@ ngx_tcp_check_smtp_parse(ngx_tcp_check_peer_conf_t *peer_conf) {
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
"smtp parse error with peer: %V, recv data: %s",
&peer_conf->peer->name, ctx->recv.pos);
+
+ /*Some SMTP servers are not strictly designed with the RFC2821, but it does work*/
+ if (*ctx->recv.start == '2') {
+ return NGX_OK;
+ }
+
return NGX_ERROR;
}
@@ -1009,6 +1048,138 @@ ngx_tcp_check_mysql_reinit(ngx_tcp_check_peer_conf_t *peer_conf) {
ctx->recv.pos = ctx->recv.last = ctx->recv.start;
}
+
+static ngx_int_t
+ngx_tcp_check_pop3_init(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ ngx_tcp_check_ctx *ctx;
+ ngx_tcp_upstream_srv_conf_t *uscf;
+
+ ctx = peer_conf->check_data;
+ uscf = peer_conf->conf;
+
+ ctx->send.start = ctx->send.pos = (u_char *)uscf->send.data;
+ ctx->send.end = ctx->send.last = ctx->send.start + uscf->send.len;
+
+ ctx->recv.start = ctx->recv.pos = NULL;
+ ctx->recv.end = ctx->recv.last = NULL;
+
+ return NGX_OK;
+}
+
+static ngx_int_t
+ngx_tcp_check_pop3_parse(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ u_char ch;
+ ngx_tcp_check_ctx *ctx;
+
+ ctx = peer_conf->check_data;
+
+ if (ctx->recv.last - ctx->recv.pos <= 0 ) {
+ return NGX_AGAIN;
+ }
+
+ ch = *(ctx->recv.start);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_TCP, ngx_cycle->log, 0,
+ "pop3_parse: packet_greeting \"%s\"", ctx->recv.start);
+
+ /* RFC 1939
+ There are currently two status indicators: positive ("+OK") and
+ negative ("-ERR"). Servers MUST send the "+OK" and "-ERR" in upper case.
+ */
+ if (ch != '+') {
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+static void
+ngx_tcp_check_pop3_reinit(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ ngx_tcp_check_ctx *ctx;
+
+ ctx = peer_conf->check_data;
+
+ ctx->send.pos = ctx->send.start;
+ ctx->send.last = ctx->send.end;
+
+ ctx->recv.pos = ctx->recv.last = ctx->recv.start;
+}
+
+static ngx_int_t
+ngx_tcp_check_imap_init(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ ngx_tcp_check_ctx *ctx;
+ ngx_tcp_upstream_srv_conf_t *uscf;
+
+ ctx = peer_conf->check_data;
+ uscf = peer_conf->conf;
+
+ ctx->send.start = ctx->send.pos = (u_char *)uscf->send.data;
+ ctx->send.end = ctx->send.last = ctx->send.start + uscf->send.len;
+
+ ctx->recv.start = ctx->recv.pos = NULL;
+ ctx->recv.end = ctx->recv.last = NULL;
+
+ return NGX_OK;
+}
+
+static ngx_int_t
+ngx_tcp_check_imap_parse(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ u_char *p;
+ ngx_tcp_check_ctx *ctx;
+
+ ctx = peer_conf->check_data;
+
+ if (ctx->recv.last - ctx->recv.pos <= 0 ) {
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_TCP, ngx_cycle->log, 0,
+ "imap_parse: packet_greeting \"%s\"", ctx->recv.start);
+
+ /* RFC 3501
+ command = tag SP (command-any / command-auth / command-nonauth /
+ command-select) CRLF
+ */
+
+ p = ctx->recv.start;
+ while (p < ctx->recv.last) {
+
+ if (*p == ' ') {
+ if ((p + 2) >= ctx->recv.last) {
+ return NGX_AGAIN;
+ }
+ else if (*(p + 1) == 'O' && *(p + 2) == 'K') {
+ return NGX_OK;
+ }
+ else {
+ return NGX_ERROR;
+ }
+ }
+
+ p++;
+ }
+
+ return NGX_AGAIN;
+}
+
+static void
+ngx_tcp_check_imap_reinit(ngx_tcp_check_peer_conf_t *peer_conf) {
+
+ ngx_tcp_check_ctx *ctx;
+
+ ctx = peer_conf->check_data;
+
+ ctx->send.pos = ctx->send.start;
+ ctx->send.last = ctx->send.end;
+
+ ctx->recv.pos = ctx->recv.last = ctx->recv.start;
+}
+
static void
ngx_tcp_check_send_handler(ngx_event_t *event) {
@@ -1177,6 +1348,9 @@ ngx_tcp_check_recv_handler(ngx_event_t *event) {
case NGX_AGAIN:
return;
case NGX_ERROR:
+ ngx_log_error(NGX_LOG_ERR, event->log, 0,
+ "check protocol %s error with peer: %V ",
+ peer_conf->conf->check_type_conf->name, &peer_conf->peer->name);
ngx_tcp_check_status_update(peer_conf, 0);
break;
case NGX_OK:
View
@@ -86,6 +86,8 @@ typedef void (*ngx_tcp_check_packet_clean_pt)(ngx_tcp_check_peer_conf_t *peer_co
#define NGX_TCP_CHECK_SSL_HELLO 0x0004
#define NGX_TCP_CHECK_SMTP 0x0008
#define NGX_TCP_CHECK_MYSQL 0x0010
+#define NGX_TCP_CHECK_POP3 0x0020
+#define NGX_TCP_CHECK_IMAP 0x0040
#define NGX_CHECK_HTTP_2XX 0x0002
View
@@ -0,0 +1,48 @@
+#
+#===============================================================================
+#
+# FILE: imap_check.t
+#
+# DESCRIPTION: test
+#
+# FILES: ---
+# BUGS: ---
+# NOTES: ---
+# AUTHOR: Weibin Yao (http://yaoweibin.cn/), yaoweibin@gmail.com
+# COMPANY:
+# VERSION: 1.0
+# CREATED: 03/02/2010 03:18:28 PM
+# REVISION: ---
+#===============================================================================
+
+
+# vi:filetype=perl
+
+use lib 'lib';
+use Test::Nginx::LWP;
+
+plan tests => repeat_each() * 2 * blocks();
+
+#no_diff;
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: the imap_check
+--- config
+ upstream test{
+ server imap.163.com:143;
+
+ #ip_hash;
+ check interval=3000 rise=2 fall=5 timeout=1000 type=imap;
+ }
+
+ server {
+ listen 1982;
+
+ proxy_pass test;
+ }
+--- request
+GET /
+--- response_body_like: ^(.*)$
View
@@ -0,0 +1,48 @@
+#
+#===============================================================================
+#
+# FILE: pop3_check.t
+#
+# DESCRIPTION: test
+#
+# FILES: ---
+# BUGS: ---
+# NOTES: ---
+# AUTHOR: Weibin Yao (http://yaoweibin.cn/), yaoweibin@gmail.com
+# COMPANY:
+# VERSION: 1.0
+# CREATED: 03/02/2010 03:18:28 PM
+# REVISION: ---
+#===============================================================================
+
+
+# vi:filetype=perl
+
+use lib 'lib';
+use Test::Nginx::LWP;
+
+plan tests => repeat_each() * 2 * blocks();
+
+#no_diff;
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: the pop3_check
+--- config
+ upstream test{
+ server pop3.163.com:110;
+
+ #ip_hash;
+ check interval=3000 rise=2 fall=5 timeout=1000 type=pop3;
+ }
+
+ server {
+ listen 1982;
+
+ proxy_pass test;
+ }
+--- request
+GET /
+--- response_body_like: ^(.*)$

0 comments on commit df22ece

Please sign in to comment.