]> git.kaiwu.me - nginx.git/commitdiff
nginx-0.0.7-2004-07-23-09:37:29 import
authorIgor Sysoev <igor@sysoev.ru>
Fri, 23 Jul 2004 05:37:29 +0000 (05:37 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Fri, 23 Jul 2004 05:37:29 +0000 (05:37 +0000)
src/event/ngx_event_openssl.c
src/event/ngx_event_openssl.h

index 27d33b0e723648cd1d3d9646bfae79290b933b31..0b0174ccf9df84372bfc8b578b7453c56a4ac048 100644 (file)
@@ -4,6 +4,9 @@
 #include <ngx_event.h>
 
 
+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_ctx_t *ssl_ctx, ngx_connection_t *c,
         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 *c, u_char *buf, size_t size)
 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 (in && in->next == NULL && !c->ssl->buffer && buf->pos == buf->last) {
 
-    if (buf) {
+        /*
+         * 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 ( ;; ) {
+        n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos);
 
-            for ( /* void */ ; in && buf->last < buf->end; in = in->next) {
-                if (ngx_buf_special(in->buf)) {
-                    continue;
-                }
+        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 (send + size > limit) {
-                size = limit - send;
+            if (ngx_buf_special(in->buf)) {
+                continue;
             }
 
-            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);
-
-            if (n > 0) {
-                buf->pos += n;
-                send += n;
-                c->sent += n;
+            size = in->buf->last - in->buf->pos;
 
-                if (n < size) {
-                    break;
-                }
-
-                if (send < limit) {
-                    if (buf->pos == buf->last) {
-                        buf->pos = buf->start;
-                        buf->last = buf->start;
-                    }
+            if (size > buf->end - buf->last) {
+                size = buf->end - buf->last;
+            }
 
-                    if (in == NULL) {
-                        break;
-                    }
+            /*
+             * TODO: the taking in->buf->flush into account can be
+             *       implemented using the limit
+             */
 
-                    continue;
-                }
+            if (send + size > limit) {
+                size = limit - send;
+                flush = 1;
             }
 
-            n = SSL_get_error(c->ssl->ssl, n);
-
             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                           "SSL_get_error: %d", n);
+                           "SSL buf copy: %d", size);
 
-            if (n == SSL_ERROR_WANT_WRITE) {
-                break;
-            }
-
-#if 0
-            if (n == SSL_ERROR_WANT_READ) {
-                break;
-            }
-#endif
+            ngx_memcpy(buf->last, in->buf->pos, size);
 
-            ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed");
+            buf->last += size;
 
-            return NGX_CHAIN_ERROR;
+            in->buf->pos += size;
+            if (in->buf->pos == in->buf->last) {
+                in = in->next;
+            }
         }
 
-        if (in) {
-            c->write->ready = 0;
-            return in;
-        }
+        size = buf->last - buf->pos;
 
-        if (buf->pos == buf->last) {
-            return NULL;
+        if (flush || buf->last == buf->end || !c->ssl->buffer) {
+            n = ngx_ssl_write(c, buf->pos, size);
 
         } else {
-            c->write->ready = 0;
             return NGX_CHAIN_AGAIN;            
         }
-    }
 
-#endif
+        if (n < 0) {
+            return (ngx_chain_t *) n;
+        }
+
+        buf->pos += n;
+        send += n;
+        c->sent += n;
 
-    for (/* void */; in; in = in->next) {
-        if (ngx_buf_special(in->buf)) {
-            continue;
+        if (n < size) {
+            break;
         }
 
-        size = in->buf->last - in->buf->pos;
+        if (buf->pos == buf->last) {
+            buf->pos = buf->start;
+            buf->last = buf->start;
+        }
 
-        if (send + size > limit) {
-            size = limit - send;
+        if (in == NULL || send == limit) {
+            break;
         }
+    }
 
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                       "SSL to write: %d", size);
+    if (in) {
+        return in;
+    }
 
-        n = SSL_write(c->ssl->ssl, in->buf->pos, size);
+    if (buf->pos == buf->last) {
+        return NULL;
+    }
 
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
+    return NGX_CHAIN_AGAIN;            
+}
 
-        if (n > 0) {
-            in->buf->pos += n;
-            send += n;
-            c->sent += n;
 
-            if (n == size) {
-                if (send < limit) {
-                    continue;
-                }
+static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
+{
+    int        n, sslerr;
+    ngx_err_t  err;
 
-                return in;
-            }
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
 
-            c->write->ready = 0;
-            return in;
-        }
+    n = SSL_write(c->ssl->ssl, data, size);
 
-        sslerr = SSL_get_error(c->ssl->ssl, n);
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
+
+    if (n > 0) {
+        return n;
+    }
 
-        err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
+    sslerr = SSL_get_error(c->ssl->ssl, n);
 
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                       "SSL_get_error: %d", sslerr);
+    err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
 
-        if (sslerr == SSL_ERROR_WANT_WRITE) {
-            c->write->ready = 0;
-            return in;
-        }
+    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;
-        }
+    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");
+    c->ssl->no_rcv_shut = 1;
 
-        return NGX_CHAIN_ERROR;
-    }
+    ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed");
 
-    return in;
+    return NGX_ERROR;
 }
 
 
index c1b36feb7ab92d547f83853c4c112d74236f20d9..6c28ba5a717c0452f3871ff06c320ab18a8d4007 100644 (file)
@@ -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;