aboutsummaryrefslogtreecommitdiff
path: root/src/imap/ngx_imap_proxy_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap/ngx_imap_proxy_module.c')
-rw-r--r--src/imap/ngx_imap_proxy_module.c122
1 files changed, 77 insertions, 45 deletions
diff --git a/src/imap/ngx_imap_proxy_module.c b/src/imap/ngx_imap_proxy_module.c
index 62329607f..bdce364b9 100644
--- a/src/imap/ngx_imap_proxy_module.c
+++ b/src/imap/ngx_imap_proxy_module.c
@@ -286,8 +286,6 @@ ngx_imap_proxy_imap_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
-
- c->log->action = "proxying";
}
}
@@ -405,16 +403,24 @@ ngx_imap_proxy_pop3_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
-
- c->log->action = "proxying";
}
}
static void
-ngx_imap_proxy_dummy_handler(ngx_event_t *ev)
+ngx_imap_proxy_dummy_handler(ngx_event_t *wev)
{
- ngx_log_debug0(NGX_LOG_DEBUG_IMAP, ev->log, 0, "imap proxy dummy handler");
+ ngx_connection_t *c;
+ ngx_imap_session_t *s;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_IMAP, wev->log, 0, "imap proxy dummy handler");
+
+ if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
+ c = wev->data;
+ s = c->data;
+
+ ngx_imap_proxy_close_session(s);
+ }
}
@@ -487,11 +493,11 @@ ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t what)
static void
ngx_imap_proxy_handler(ngx_event_t *ev)
{
- char *action;
+ char *action, *recv_action, *send_action;
size_t size;
ssize_t n;
ngx_buf_t *b;
- ngx_uint_t again, do_write;
+ ngx_uint_t do_write;
ngx_connection_t *c, *src, *dst;
ngx_imap_session_t *s;
ngx_imap_proxy_conf_t *pcf;
@@ -500,6 +506,8 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
s = c->data;
if (ev->timedout) {
+ c->log->action = "proxying";
+
if (c == s->connection) {
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
"client timed out");
@@ -516,11 +524,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
if (c == s->connection) {
if (ev->write) {
+ recv_action = "proxying and reading from upstream";
+ send_action = "proxying and sending to client";
src = s->proxy->upstream.connection;
dst = c;
b = s->proxy->buffer;
} else {
+ recv_action = "proxying and reading from client";
+ send_action = "proxying and sending to upstream";
src = c;
dst = s->proxy->upstream.connection;
b = s->buffer;
@@ -528,11 +540,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
} else {
if (ev->write) {
+ recv_action = "proxying and reading from upstream";
+ send_action = "proxying and sending to client";
src = s->connection;
dst = c;
b = s->buffer;
} else {
+ recv_action = "proxying and reading from client";
+ send_action = "proxying and sending to upstream";
src = c;
dst = s->connection;
b = s->proxy->buffer;
@@ -545,14 +561,15 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
"imap proxy handler: %d, #%d > #%d",
do_write, src->fd, dst->fd);
- do {
- again = 0;
+ for ( ;; ) {
- if (do_write == 1) {
+ if (do_write) {
size = b->last - b->pos;
if (size && dst->write->ready) {
+ c->log->action = send_action;
+
n = dst->send(dst, b->pos, size);
if (n == NGX_ERROR) {
@@ -561,7 +578,6 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
}
if (n > 0) {
- again = 1;
b->pos += n;
if (b->pos == b->last) {
@@ -569,58 +585,74 @@ ngx_imap_proxy_handler(ngx_event_t *ev)
b->last = b->start;
}
}
-
- if (n == NGX_AGAIN || n < (ssize_t) size) {
- if (ngx_handle_write_event(dst->write, /* TODO: LOWAT */ 0)
- == NGX_ERROR)
- {
- ngx_imap_proxy_close_session(s);
- return;
- }
- }
}
}
size = b->end - b->last;
if (size && src->read->ready) {
- n = src->recv(src, b->last, size);
-
- if (n == NGX_ERROR) {
- ngx_imap_proxy_close_session(s);
- return;
- }
+ c->log->action = recv_action;
- if (n == 0) {
- action = c->log->action;
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done");
- c->log->action = action;
+ n = src->recv(src, b->last, size);
- ngx_imap_proxy_close_session(s);
- return;
+ if (n == NGX_AGAIN || n == 0) {
+ break;
}
if (n > 0) {
- again = 1;
do_write = 1;
b->last += n;
- }
- if (n == NGX_AGAIN || n < (ssize_t) size) {
- if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) {
- ngx_imap_proxy_close_session(s);
- return;
- }
+ continue;
}
- if (c == s->connection) {
- pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
- ngx_add_timer(c->read, pcf->timeout);
+ if (n == NGX_ERROR) {
+ src->read->eof = 1;
}
}
- } while (again);
+ break;
+ }
+
+ c->log->action = "proxying";
+
+ if ((s->connection->read->eof || s->proxy->upstream.connection->read->eof)
+ && s->buffer->pos == s->buffer->last
+ && s->proxy->buffer->pos == s->proxy->buffer->last)
+ {
+ action = c->log->action;
+ c->log->action = NULL;
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done");
+ c->log->action = action;
+
+ ngx_imap_proxy_close_session(s);
+ return;
+ }
+
+ if (ngx_handle_write_event(dst->write, 0) == NGX_ERROR) {
+ ngx_imap_proxy_close_session(s);
+ return;
+ }
+
+ if (ngx_handle_read_event(dst->read, 0) == NGX_ERROR) {
+ ngx_imap_proxy_close_session(s);
+ return;
+ }
+
+ if (ngx_handle_write_event(src->write, 0) == NGX_ERROR) {
+ ngx_imap_proxy_close_session(s);
+ return;
+ }
+
+ if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) {
+ ngx_imap_proxy_close_session(s);
+ return;
+ }
+
+ if (c == s->connection) {
+ pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
+ ngx_add_timer(c->read, pcf->timeout);
+ }
}