# HG changeset patch # User Igor Sysoev # Date 1090561049 0 # Node ID de797f3b4c27e2339b08b5029239c73c14612cee # Parent 6f3b20c1ac50edb0c330174ac5c511c8215a8659 nginx-0.0.7-2004-07-23-09:37:29 import diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -4,6 +4,9 @@ #include +static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size); + + ngx_int_t ngx_ssl_init(ngx_log_t *log) { SSL_library_init(); @@ -22,10 +25,12 @@ ngx_int_t ngx_ssl_create_session(ngx_ssl return NGX_ERROR; } + if (!(ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE))) { + return NGX_ERROR; + } + if (flags & NGX_SSL_BUFFER) { - if (!(ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE))) { - return NGX_ERROR; - } + ssl->buffer = 1; } ssl->ssl = SSL_new(ssl_ctx); @@ -104,175 +109,154 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { - int n, sslerr; - ngx_err_t err; - ssize_t send, size; - ngx_buf_t *buf; - - send = 0; + int n; + ngx_uint_t flush; + ssize_t send, size; + ngx_buf_t *buf; buf = c->ssl->buf; -#if 0 - - if (buf) { + if (in && in->next == NULL && !c->ssl->buffer && buf->pos == buf->last) { - for ( ;; ) { + /* + * the optimized path without a copy if there is the single incoming + * buf, we do not need to buffer output and our buffer is empty + */ - for ( /* void */ ; in && buf->last < buf->end; in = in->next) { - if (ngx_buf_special(in->buf)) { - continue; - } + n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos); + + if (n < 0) { + return (ngx_chain_t *) n; + } - size = in->buf->last - in->buf->pos; + in->buf->pos += n; - if (size > buf->end - buf->last) { - size = buf->end - buf->last; - } + return in; + } - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL buf copy: %d", size); + send = 0; + flush = (in == NULL) ? 1 : 0; - ngx_memcpy(buf->last, in->buf->pos, size); + for ( ;; ) { - buf->last += size; - in->buf->pos += size; + while (in && buf->last < buf->end) { + if (in->buf->last_buf) { + flush = 1; } - size = buf->last - buf->pos; + if (ngx_buf_special(in->buf)) { + continue; + } + + size = in->buf->last - in->buf->pos; + + if (size > buf->end - buf->last) { + size = buf->end - buf->last; + } + + /* + * TODO: the taking in->buf->flush into account can be + * implemented using the limit + */ if (send + size > limit) { size = limit - send; + flush = 1; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL to write: %d", size); - - n = SSL_write(c->ssl->ssl, buf->pos, size); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL_write: %d", n); + "SSL buf copy: %d", size); - if (n > 0) { - buf->pos += n; - send += n; - c->sent += n; - - if (n < size) { - break; - } - - if (send < limit) { - if (buf->pos == buf->last) { - buf->pos = buf->start; - buf->last = buf->start; - } + ngx_memcpy(buf->last, in->buf->pos, size); - if (in == NULL) { - break; - } - - continue; - } - } - - n = SSL_get_error(c->ssl->ssl, n); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL_get_error: %d", n); + buf->last += size; - if (n == SSL_ERROR_WANT_WRITE) { - break; + in->buf->pos += size; + if (in->buf->pos == in->buf->last) { + in = in->next; } - -#if 0 - if (n == SSL_ERROR_WANT_READ) { - break; - } -#endif - - ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed"); - - return NGX_CHAIN_ERROR; } - if (in) { - c->write->ready = 0; - return in; + size = buf->last - buf->pos; + + if (flush || buf->last == buf->end || !c->ssl->buffer) { + n = ngx_ssl_write(c, buf->pos, size); + + } else { + return NGX_CHAIN_AGAIN; + } + + if (n < 0) { + return (ngx_chain_t *) n; + } + + buf->pos += n; + send += n; + c->sent += n; + + if (n < size) { + break; } if (buf->pos == buf->last) { - return NULL; + buf->pos = buf->start; + buf->last = buf->start; + } - } else { - c->write->ready = 0; - return NGX_CHAIN_AGAIN; + if (in == NULL || send == limit) { + break; } } + if (in) { + return in; + } + + if (buf->pos == buf->last) { + return NULL; + } + + return NGX_CHAIN_AGAIN; +} + + +static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) +{ + int n, sslerr; + ngx_err_t err; + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); + + n = SSL_write(c->ssl->ssl, data, size); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); + + if (n > 0) { + return n; + } + + sslerr = SSL_get_error(c->ssl->ssl, n); + + err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); + + if (sslerr == SSL_ERROR_WANT_WRITE) { + c->write->ready = 0; + return NGX_AGAIN; + } + +#if 0 + if (sslerr == SSL_ERROR_WANT_READ) { + return NGX_AGAIN; + } #endif - for (/* void */; in; in = in->next) { - if (ngx_buf_special(in->buf)) { - continue; - } - - size = in->buf->last - in->buf->pos; - - if (send + size > limit) { - size = limit - send; - } - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL to write: %d", size); - - n = SSL_write(c->ssl->ssl, in->buf->pos, size); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); - - if (n > 0) { - in->buf->pos += n; - send += n; - c->sent += n; - - if (n == size) { - if (send < limit) { - continue; - } - - return in; - } + c->ssl->no_rcv_shut = 1; - c->write->ready = 0; - return in; - } - - sslerr = SSL_get_error(c->ssl->ssl, n); - - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL_get_error: %d", sslerr); + ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed"); - if (sslerr == SSL_ERROR_WANT_WRITE) { - c->write->ready = 0; - return in; - } - -#if 0 - if (sslerr == SSL_ERROR_WANT_READ) { - return NGX_AGAIN; - } -#endif - - c->ssl->no_rcv_shut = 1; - - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_write() failed"); - - return NGX_CHAIN_ERROR; - } - - return in; + return NGX_ERROR; } diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -14,6 +14,7 @@ typedef struct { ngx_buf_t *buf; ngx_event_handler_pt saved_handler; + unsigned buffer:1; unsigned no_rcv_shut:1; unsigned no_send_shut:1; } ngx_ssl_t;