summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/event/ngx_event.c7
-rw-r--r--src/event/ngx_event_openssl.c68
-rw-r--r--src/event/ngx_event_openssl.h1
-rw-r--r--src/event/ngx_event_posted.c1
-rw-r--r--src/event/ngx_event_posted.h1
5 files changed, 78 insertions, 0 deletions
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 69c55d7a0..6e19f311b 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -237,6 +237,12 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
}
}
+ if (!ngx_queue_empty(&ngx_posted_next_events)) {
+ ngx_queue_add(&ngx_posted_events, &ngx_posted_next_events);
+ ngx_queue_init(&ngx_posted_next_events);
+ timer = 0;
+ }
+
delta = ngx_current_msec;
(void) ngx_process_events(cycle, timer, flags);
@@ -639,6 +645,7 @@ ngx_event_process_init(ngx_cycle_t *cycle)
#endif
ngx_queue_init(&ngx_posted_accept_events);
+ ngx_queue_init(&ngx_posted_next_events);
ngx_queue_init(&ngx_posted_events);
if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 4e3eb391c..e9431b2d6 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -43,6 +43,7 @@ static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
#endif
static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
static void ngx_ssl_write_handler(ngx_event_t *wev);
+static void ngx_ssl_next_read_handler(ngx_event_t *rev);
#ifdef SSL_READ_EARLY_DATA_SUCCESS
static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
size_t size);
@@ -2003,6 +2004,48 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
if (size == 0) {
c->read->ready = 1;
+
+ if (c->read->available >= 0) {
+ c->read->available -= bytes;
+
+ /*
+ * there can be data buffered at SSL layer,
+ * so we post an event to continue reading on the next
+ * iteration of the event loop
+ */
+
+ if (c->read->available < 0) {
+ c->read->available = 0;
+ c->read->ready = 0;
+
+ if (c->ssl->next_read_handler == NULL) {
+ c->ssl->next_read_handler = c->read->handler;
+ c->read->handler = ngx_ssl_next_read_handler;
+ }
+
+ ngx_post_event(c->read, &ngx_posted_next_events);
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_read: avail:%d", c->read->available);
+
+ } else {
+
+#if (NGX_HAVE_FIONREAD)
+
+ if (ngx_socket_nread(c->fd, &c->read->available) == -1) {
+ c->read->error = 1;
+ ngx_connection_error(c, ngx_socket_errno,
+ ngx_socket_nread_n " failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_read: avail:%d", c->read->available);
+
+#endif
+ }
+
return bytes;
}
@@ -2285,6 +2328,31 @@ ngx_ssl_write_handler(ngx_event_t *wev)
}
+static void
+ngx_ssl_next_read_handler(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+
+ c = rev->data;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL next read handler");
+
+ rev->handler = c->ssl->next_read_handler;
+ c->ssl->next_read_handler = NULL;
+
+ if (!rev->ready) {
+ rev->ready = 1;
+ rev->available = -1;
+ }
+
+ if (rev->posted) {
+ ngx_delete_posted_event(rev);
+ }
+
+ rev->handler(rev);
+}
+
+
/*
* OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
* before the SSL_write() call to decrease a SSL overhead.
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 61da0c5db..71df90045 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -86,6 +86,7 @@ struct ngx_ssl_connection_s {
ngx_event_handler_pt saved_read_handler;
ngx_event_handler_pt saved_write_handler;
+ ngx_event_handler_pt next_read_handler;
u_char early_buf;
diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c
index d851f3d14..fd0b411c4 100644
--- a/src/event/ngx_event_posted.c
+++ b/src/event/ngx_event_posted.c
@@ -11,6 +11,7 @@
ngx_queue_t ngx_posted_accept_events;
+ngx_queue_t ngx_posted_next_events;
ngx_queue_t ngx_posted_events;
diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h
index 145d30fea..bac5b3555 100644
--- a/src/event/ngx_event_posted.h
+++ b/src/event/ngx_event_posted.h
@@ -42,6 +42,7 @@ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted);
extern ngx_queue_t ngx_posted_accept_events;
+extern ngx_queue_t ngx_posted_next_events;
extern ngx_queue_t ngx_posted_events;