https + large-file sending, sometimes fails
Igor Sysoev
is at rambler-co.ru
Thu Dec 20 16:14:54 MSK 2007
On Thu, Dec 20, 2007 at 01:40:09PM +0300, Igor Sysoev wrote:
> On Thu, Dec 20, 2007 at 01:30:50PM +0300, Igor Sysoev wrote:
>
> > On Thu, Dec 20, 2007 at 01:16:19PM +0300, Igor Sysoev wrote:
> >
> > > On Thu, Dec 20, 2007 at 10:55:16AM +0100, G?bor Farkas wrote:
> > >
> > > > also, something i say by the testing: if you start to do a lot of
> > > > concurrent requests, and start to kill the clients (which are fetching
> > > > the file), then also other requests start to die more frequently then
> > > > normally.
> > >
> > > Thank you, I have just reproduce the case.
> >
> > The attached patch should fix the bug.
>
> The complete patch.
The new commited patch.
1st, it fixes the cause of bug - SSL_shutdown() handling.
SSL_shutdown() man states incorrectly that SSL_shutdown() will return -1
on error. Actually SSL_shutdown() never returns -1.
2nd, it clears and logs possible previously unhandled SSL errors so
they have not affect on a new operation.
--
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/event/ngx_event_openssl.c
===================================================================
--- src/event/ngx_event_openssl.c (revision 1073)
+++ src/event/ngx_event_openssl.c (revision 1075)
@@ -22,6 +22,7 @@
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
+static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
void *data);
@@ -404,6 +405,8 @@
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
n = SSL_do_handshake(c->ssl->connection);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
@@ -605,6 +608,8 @@
bytes = 0;
+ ngx_ssl_clear_error(c->log);
+
/*
* SSL_read() may return data in parts, so try to read
* until SSL_read() would return no data
@@ -895,6 +900,8 @@
int n, sslerr;
ngx_err_t err;
+ ngx_ssl_clear_error(c->log);
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
n = SSL_write(c->ssl->connection, data, size);
@@ -978,9 +985,8 @@
ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
- int n, sslerr, mode;
- ngx_err_t err;
- ngx_uint_t again;
+ int n, sslerr, mode;
+ ngx_err_t err;
if (c->timedout) {
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
@@ -999,40 +1005,34 @@
SSL_set_shutdown(c->ssl->connection, mode);
- again = 0;
- sslerr = 0;
+ ngx_ssl_clear_error(c->log);
- for ( ;; ) {
- n = SSL_shutdown(c->ssl->connection);
+ n = SSL_shutdown(c->ssl->connection);
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
- if (n == 1 || (n == 0 && c->timedout)) {
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
+ sslerr = 0;
- return NGX_OK;
- }
+ /* SSL_shutdown() never return -1, on error it return 0 */
- if (n == 0) {
- again = 1;
- break;
- }
-
- break;
- }
-
- if (!again) {
+ if (n != 1) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
}
- if (again
- || sslerr == SSL_ERROR_WANT_READ
- || sslerr == SSL_ERROR_WANT_WRITE)
+ if (n == 1
+ || sslerr == SSL_ERROR_ZERO_RETURN
+ || (sslerr == 0 && c->timedout))
{
+ SSL_free(c->ssl->connection);
+ c->ssl = NULL;
+
+ return NGX_OK;
+ }
+
+ if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
c->read->handler = ngx_ssl_shutdown_handler;
c->write->handler = ngx_ssl_shutdown_handler;
@@ -1044,7 +1044,7 @@
return NGX_ERROR;
}
- if (again || sslerr == SSL_ERROR_WANT_READ) {
+ if (sslerr == SSL_ERROR_WANT_READ) {
ngx_add_timer(c->read, 30000);
}
@@ -1125,6 +1125,15 @@
}
+static void
+ngx_ssl_clear_error(ngx_log_t *log)
+{
+ if (ERR_peek_error()) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
+ }
+}
+
+
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{
More information about the nginx
mailing list