# HG changeset patch # User Igor Sysoev # Date 1089959615 0 # Node ID e7a68e14ccd3f873d8d8cea6b3f4b7cc3a389382 # Parent 5659d773cfa82f9ca2e7b7330879ebe12ccafaba nginx-0.0.7-2004-07-16-10:33:35 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 @@ -1,9 +1,7 @@ + #include #include - - -static void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, - char *fmt, ...); +#include ngx_int_t ngx_ssl_init(ngx_log_t *log) @@ -22,12 +20,12 @@ ngx_int_t ngx_ssl_create_session(ngx_ssl ssl = SSL_new(ssl_ctx); if (ssl == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); + ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_new() failed"); return NGX_ERROR; } if (SSL_set_fd(ssl, c->fd) == 0) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); + ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_set_fd() failed"); return NGX_ERROR; } @@ -59,7 +57,7 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t if (n == SSL_ERROR_WANT_READ) { return NGX_AGAIN; } - + #if 0 if (n == SSL_ERROR_WANT_WRITE) { return NGX_AGAIN; @@ -91,7 +89,7 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t return NGX_SSL_HTTP_ERROR; } - ngx_ssl_error(NGX_LOG_ALERT, c->log, n, "SSL_read() failed%s", handshake); + ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_read() failed%s", handshake); SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); @@ -99,8 +97,142 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t } -static void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, - char *fmt, ...) +ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, + off_t limit) +{ + int n; + ssize_t send, size; + + send = 0; + + 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, 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; + + if (n == size) { + if (send < limit) { + continue; + } + + return in; + } + + c->write->ready = 0; + return in; + } + + n = SSL_get_error(c->ssl, n); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); + + if (n == SSL_ERROR_WANT_WRITE) { + c->write->ready = 0; + return in; + } + +#if 0 + if (n == SSL_ERROR_WANT_READ) { + return NGX_AGAIN; + } +#endif + + ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed"); + + return NGX_CHAIN_ERROR; + } + + return in; +} + + +ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) +{ + int n; + ngx_uint_t again; + +#if 0 + if (c->read->timedout || c->write->timedout) { + SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); + SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); + } +#endif + +#if 0 + SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); +#endif + + again = 0; + + for ( ;; ) { + n = SSL_shutdown(c->ssl); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); + + if (n == 0) { + again = 1; + break; + } + + if (n == 1) { + SSL_free(c->ssl); + c->ssl = NULL; + return NGX_OK; + } + + break; + } + + if (!again) { + n = SSL_get_error(c->ssl, n); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); + } + + if (again || n == SSL_ERROR_WANT_READ) { + + ngx_add_timer(c->read, 10000); + + if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_AGAIN; + } + + if (n == SSL_ERROR_WANT_WRITE) { + + if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_AGAIN; + } + + ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_shutdown() failed"); + + return NGX_ERROR; +} + + +void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, char *fmt, ...) { int len; char errstr[NGX_MAX_CONF_ERRSTR]; 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 @@ -19,6 +19,10 @@ typedef SSL_CTX ngx_ssl_ctx_t; ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ctx, ngx_connection_t *c); 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); +ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c); +void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, char *fmt, ...); #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ diff --git a/src/http/modules/ngx_http_ssl_filter.c b/src/http/modules/ngx_http_ssl_filter.c --- a/src/http/modules/ngx_http_ssl_filter.c +++ b/src/http/modules/ngx_http_ssl_filter.c @@ -3,17 +3,11 @@ #include #include -/* STUB */ -#define NGX_SSL_ERROR -11 - #define NGX_DEFLAUT_CERTIFICATE "cert.pem" #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" -static ngx_int_t ngx_http_ssl_create_ssl(ngx_http_request_t *r); -static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, - char *fmt, ...); static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child); @@ -71,235 +65,6 @@ ngx_module_t ngx_http_ssl_filter_module }; -ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t size) -{ - int n; - SSL *ssl; - ngx_http_log_ctx_t *log_ctx; - - if (r->connection->ssl == NULL) { - if (ngx_http_ssl_create_ssl(r) == NGX_ERROR) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - } - - ssl = r->connection->ssl; - - n = SSL_read(ssl, buf, size); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "SSL_read: %d", n); - - if (n > 0) { - return n; - } - - n = SSL_get_error(ssl, n); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "SSL_get_error: %d", n); - - if (n == SSL_ERROR_WANT_READ) { - return NGX_AGAIN; - } - -#if 0 - if (n == SSL_ERROR_WANT_WRITE) { - return NGX_AGAIN; - } -#endif - - if (!SSL_is_init_finished(ssl)) { - log_ctx = (ngx_http_log_ctx_t *) r->connection->log->data; - log_ctx->action = "SSL handshake"; - } - - if (n == SSL_ERROR_ZERO_RETURN) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client closed connection"); - - SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - - return NGX_SSL_ERROR; - } - - if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "client sent plain HTTP request to HTTPS port"); - - SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); - - return NGX_SSL_HTTP_ERROR; - } - - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, n, - "SSL_read() failed"); - - SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - - return NGX_SSL_ERROR; -} - - -ngx_chain_t *ngx_http_ssl_write(ngx_connection_t *c, ngx_chain_t *in, - off_t limit) -{ - int n; - ssize_t send, size; - - send = 0; - - 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_HTTP, c->log, 0, "SSL to write: %d", size); - - n = SSL_write(c->ssl, in->buf->pos, size); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL_write: %d", n); - - if (n > 0) { - in->buf->pos += n; - send += n; - - if (n == size) { - if (send < limit) { - continue; - } - - return in; - } - - c->write->ready = 0; - return in; - } - - n = SSL_get_error(c->ssl, n); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL_get_error: %d", n); - - if (n == SSL_ERROR_WANT_WRITE) { - c->write->ready = 0; - return in; - } - - ngx_http_ssl_error(NGX_LOG_ALERT, c->log, n, "SSL_write() failed"); - - return NGX_CHAIN_ERROR; - } - - return in; -} - - -ngx_int_t ngx_http_ssl_shutdown(ngx_http_request_t *r) -{ - int n; - SSL *ssl; - - ssl = r->connection->ssl; - - n = SSL_shutdown(ssl); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "SSL_shutdown: %d", n); - - if (n == 0) { - return NGX_AGAIN; - } - - if (n == 1) { - SSL_free(ssl); - r->connection->ssl = NULL; - return NGX_OK; - } - - n = SSL_get_error(ssl, n); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "SSL_get_error: %d", n); - - if (n == SSL_ERROR_WANT_WRITE) { - return NGX_AGAIN; - } - - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, n, - "SSL_shutdown() failed"); - - return NGX_ERROR; -} - - -static ngx_int_t ngx_http_ssl_create_ssl(ngx_http_request_t *r) -{ - SSL *ssl; - ngx_http_ssl_srv_conf_t *scf; - - scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); - - ssl = SSL_new(scf->ssl_ctx); - - if (ssl == NULL) { - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, - "SSL_new() failed"); - return NGX_ERROR; - } - - if (SSL_set_fd(ssl, r->connection->fd) == 0) { - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, - "SSL_set_fd() failed"); - return NGX_ERROR; - } - - SSL_set_accept_state(ssl); - - r->connection->ssl = ssl; - - return NGX_OK; -} - - -void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log) -{ - int rc; - - SSL_free(ssl); -} - - -static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, - char *fmt, ...) -{ - int len; - char errstr[NGX_MAX_CONF_ERRSTR]; - va_list args; - - va_start(args, fmt); - len = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args); - va_end(args); - - errstr[len++] = ' '; - errstr[len++] = '('; - errstr[len++] = 'S'; - errstr[len++] = 'S'; - errstr[len++] = 'L'; - errstr[len++] = ':'; - errstr[len++] = ' '; - - ERR_error_string_n(ERR_get_error(), errstr + len, sizeof(errstr) - len - 1); - - ngx_log_error(level, log, 0, "%s)", errstr); -} - - static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) { ngx_http_ssl_srv_conf_t *scf; @@ -337,23 +102,23 @@ static char *ngx_http_ssl_merge_srv_conf conf->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if (conf->ssl_ctx == NULL) { - ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_new() failed"); + ngx_ssl_error(NGX_LOG_EMERG, cf->log, "SSL_CTX_new() failed"); return NGX_CONF_ERROR; } if (SSL_CTX_use_certificate_file(conf->ssl_ctx, conf->certificate.data, SSL_FILETYPE_PEM) == 0) { - ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_use_certificate_file(\"%s\") failed", - conf->certificate.data); + ngx_ssl_error(NGX_LOG_EMERG, cf->log, + "SSL_CTX_use_certificate_file(\"%s\") failed", + conf->certificate.data); return NGX_CONF_ERROR; } if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, conf->certificate_key.data, SSL_FILETYPE_PEM) == 0) { - ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_use_PrivateKey_file(\"%s\") failed", - conf->certificate_key.data); + ngx_ssl_error(NGX_LOG_EMERG, cf->log, + "SSL_CTX_use_PrivateKey_file(\"%s\") failed", + conf->certificate_key.data); return NGX_CONF_ERROR; } @@ -377,9 +142,7 @@ static ngx_int_t ngx_http_ssl_init_proce if (sscf->enable) { cscfp[i]->recv = ngx_ssl_recv; -#if 0 cscfp[i]->send_chain = ngx_ssl_send_chain; -#endif } } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1423,7 +1423,7 @@ static void ngx_http_keepalive_handler(n ngx_connection_t *c; ngx_http_log_ctx_t *ctx; - c = (ngx_connection_t *) rev->data; + c = rev->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler"); @@ -1725,6 +1725,26 @@ void ngx_http_close_request(ngx_http_req } +#if (NGX_HTTP_SSL) + +void ngx_ssl_close_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + + c = ev->data; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "http ssl close handler"); + + if (ngx_ssl_shutdown(c) == NGX_AGAIN) { + return; + } + + ngx_http_close_connection(c); +} + +#endif + + void ngx_http_close_connection(ngx_connection_t *c) { ngx_socket_t fd; @@ -1737,6 +1757,18 @@ void ngx_http_close_connection(ngx_conne return; } +#if (NGX_HTTP_SSL) + + if (c->ssl) { + if (ngx_ssl_shutdown(c) == NGX_AGAIN) { + c->read->event_handler = ngx_ssl_close_handler; + c->write->event_handler = ngx_ssl_close_handler; + return; + } + } + +#endif + if (c->read->timer_set) { ngx_del_timer(c->read); } diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -42,6 +42,7 @@ ngx_int_t ngx_http_write_filter(ngx_http int last; off_t size, flush, sent; ngx_chain_t *cl, *ln, **ll, *chain; + ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_write_filter_ctx_t *ctx; @@ -123,20 +124,11 @@ ngx_int_t ngx_http_write_filter(ngx_http sent = r->connection->sent; -/* STUB */ -#if (NGX_OPENSSL) - if (r->connection->ssl) { - chain = ngx_http_ssl_write(r->connection, ctx->out, - clcf->limit_rate ? clcf->limit_rate: - OFF_T_MAX_VALUE); - } else { -#endif - chain = ngx_write_chain(r->connection, ctx->out, - clcf->limit_rate ? clcf->limit_rate: - OFF_T_MAX_VALUE); -#if (NGX_OPENSSL) - } -#endif + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + + chain = cscf->send_chain(r->connection, ctx->out, + clcf->limit_rate ? clcf->limit_rate: + OFF_T_MAX_VALUE); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http write filter %X", chain);