diff src/event/ngx_event_openssl.c @ 38:2879cd3a40cb NGINX_0_1_19

nginx 0.1.19 *) Bugfix: now, if request contains the zero, then the 404 error is returned for the local requests. *) Bugfix: nginx could not be built on NetBSD 2.0. *) Bugfix: the timeout may occur while reading of the the client request body via SSL connections.
author Igor Sysoev <http://sysoev.ru>
date Wed, 16 Feb 2005 00:00:00 +0300
parents 7ca9bdc82b3f
children bc4fc02c96a3
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -11,12 +11,14 @@
 #include <openssl/engine.h>
 
 
+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 ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
 static void ngx_ssl_read_handler(ngx_event_t *rev);
 
 
-ngx_int_t ngx_ssl_init(ngx_log_t *log)
+ngx_int_t
+ngx_ssl_init(ngx_log_t *log)
 {
     ENGINE  *engine;
 
@@ -28,8 +30,9 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log)
 }
 
 
-ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c,
-                                 ngx_uint_t flags)
+ngx_int_t
+ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c,
+    ngx_uint_t flags)
 {   
     ngx_ssl_t  *ssl;
 
@@ -65,58 +68,105 @@ ngx_int_t ngx_ssl_create_session(ngx_ssl
 }
 
 
-ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
+ssize_t
+ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
 {
-    int         n, sslerr;
-    ngx_err_t   err;
-    char       *handshake;
+    int  n, bytes;
+
+    if (c->ssl->last == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    bytes = 0;
 
-    n = SSL_read(c->ssl->ssl, buf, size);
+    /*
+     * SSL_read() may return data in parts, so try to read
+     * until SSL_read() would return no data
+     */
+
+    for ( ;; ) {
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 
+        n = SSL_read(c->ssl->ssl, buf, size);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 
 
-    if (n > 0) {
+        if (n > 0) {
+
+            bytes += n;
 
 #if (NGX_DEBUG)
 
-        if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) {
-            char         buf[129], *s, *d;
-            SSL_CIPHER  *cipher;
+            if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) {
+                char         buf[129], *s, *d;
+                SSL_CIPHER  *cipher;
 
-            c->ssl->handshaked = 1;
+                c->ssl->handshaked = 1;
+
+                cipher = SSL_get_current_cipher(c->ssl->ssl);
+
+                if (cipher) {
+                    SSL_CIPHER_description(cipher, &buf[1], 128);
 
-            cipher = SSL_get_current_cipher(c->ssl->ssl);
+                    for (s = &buf[1], d = buf; *s; s++) {
+                        if (*s == ' ' && *d == ' ') {
+                            continue;
+                        }
 
-            if (cipher) {
-                SSL_CIPHER_description(cipher, &buf[1], 128);
+                        if (*s == '\n' || *s == '\r') {
+                            continue;
+                        }
 
-                for (s = &buf[1], d = buf; *s; s++) {
-                    if (*s == ' ' && *d == ' ') {
-                        continue;
+                        *++d = *s;
                     }
 
-                    if (*s == '\n' || *s == '\r') {
-                        continue;
+                    if (*d != ' ') {
+                        d++;
                     }
 
-                    *++d = *s;
-                }
+                    *d = '\0';
 
-                if (*d != ' ') {
-                    d++;
+                    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                                   "SSL cipher: \"%s\"", &buf[1]); 
+                } else {
+                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                                   "SSL no shared ciphers"); 
                 }
+            }
+#endif
 
-                *d = '\0';
+        }
+
+        c->ssl->last = ngx_ssl_handle_recv(c, n);
+
+        if (c->ssl->last != NGX_OK) {
 
-                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                               "SSL cipher: \"%s\"", &buf[1]); 
+            if (bytes) {
+                return bytes;
+
             } else {
-                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                               "SSL no shared ciphers"); 
+                return c->ssl->last;
             }
         }
 
-#endif
+        size -= n;
+
+        if (size == 0) {
+            return bytes;
+        }
+
+        buf += n;
+    }
+}
+
+
+static ngx_int_t
+ngx_ssl_handle_recv(ngx_connection_t *c, int n)
+{
+    int         sslerr;
+    ngx_err_t   err;
+    char       *handshake;
+
+    if (n > 0) {
 
         if (c->ssl->saved_write_handler) {
 
@@ -137,7 +187,7 @@ ssize_t ngx_ssl_recv(ngx_connection_t *c
             ngx_mutex_unlock(ngx_posted_events_mutex);
         }
 
-        return n;
+        return NGX_OK;
     }
 
     if (!SSL_is_init_finished(c->ssl->ssl)) {
@@ -197,7 +247,8 @@ ssize_t ngx_ssl_recv(ngx_connection_t *c
 }
 
 
-static void ngx_ssl_write_handler(ngx_event_t *wev)
+static void
+ngx_ssl_write_handler(ngx_event_t *wev)
 {
     ngx_connection_t  *c;
 
@@ -214,8 +265,8 @@ static void ngx_ssl_write_handler(ngx_ev
  * the output to decrease a SSL overhead some more.
  */
 
-ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
-                                off_t limit)
+ngx_chain_t *
+ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 {
     int          n;
     ngx_uint_t   flush;
@@ -338,7 +389,8 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_conn
 }
 
 
-static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
+static ssize_t
+ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
 {
     int         n, sslerr;
     ngx_err_t   err;
@@ -424,7 +476,8 @@ static ssize_t ngx_ssl_write(ngx_connect
 }
 
 
-static void ngx_ssl_read_handler(ngx_event_t *rev)
+static void
+ngx_ssl_read_handler(ngx_event_t *rev)
 {
     ngx_connection_t  *c;
 
@@ -433,7 +486,8 @@ static void ngx_ssl_read_handler(ngx_eve
 }
 
 
-ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
+ngx_int_t
+ngx_ssl_shutdown(ngx_connection_t *c)
 {
     int         n, sslerr, mode;
     ngx_uint_t  again;
@@ -520,8 +574,8 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio
 }
 
 
-void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
-                   char *fmt, ...)
+void
+ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
 {   
     u_char   errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
     va_list  args;