comparison src/http/ngx_http_request.c @ 7738:554c6ae25ffc

SSL: fixed non-working SSL shutdown on lingering close. When doing lingering close, the socket was first shut down for writing, so SSL shutdown initiated after lingering close was not able to send the close_notify alerts (ticket #2056). The fix is to call ngx_ssl_shutdown() before shutting down the socket.
author Ruslan Ermilov <ru@nginx.com>
date Fri, 06 Nov 2020 23:44:54 +0300
parents ed17a2a95c8d
children 7efae6b4cfb0 507da0d3b070
comparison
equal deleted inserted replaced
7737:ed17a2a95c8d 7738:554c6ae25ffc
47 static void ngx_http_writer(ngx_http_request_t *r); 47 static void ngx_http_writer(ngx_http_request_t *r);
48 static void ngx_http_request_finalizer(ngx_http_request_t *r); 48 static void ngx_http_request_finalizer(ngx_http_request_t *r);
49 49
50 static void ngx_http_set_keepalive(ngx_http_request_t *r); 50 static void ngx_http_set_keepalive(ngx_http_request_t *r);
51 static void ngx_http_keepalive_handler(ngx_event_t *ev); 51 static void ngx_http_keepalive_handler(ngx_event_t *ev);
52 static void ngx_http_set_lingering_close(ngx_http_request_t *r); 52 static void ngx_http_set_lingering_close(ngx_connection_t *c);
53 static void ngx_http_lingering_close_handler(ngx_event_t *ev); 53 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
54 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); 54 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
55 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); 55 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
56 static void ngx_http_log_request(ngx_http_request_t *r); 56 static void ngx_http_log_request(ngx_http_request_t *r);
57 57
2752 || (clcf->lingering_close == NGX_HTTP_LINGERING_ON 2752 || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
2753 && (r->lingering_close 2753 && (r->lingering_close
2754 || r->header_in->pos < r->header_in->last 2754 || r->header_in->pos < r->header_in->last
2755 || r->connection->read->ready))) 2755 || r->connection->read->ready)))
2756 { 2756 {
2757 ngx_http_set_lingering_close(r); 2757 ngx_http_set_lingering_close(r->connection);
2758 return; 2758 return;
2759 } 2759 }
2760 2760
2761 ngx_http_close_request(r, 0); 2761 ngx_http_close_request(r, 0);
2762 } 2762 }
3366 ngx_http_process_request_line(rev); 3366 ngx_http_process_request_line(rev);
3367 } 3367 }
3368 3368
3369 3369
3370 static void 3370 static void
3371 ngx_http_set_lingering_close(ngx_http_request_t *r) 3371 ngx_http_set_lingering_close(ngx_connection_t *c)
3372 { 3372 {
3373 ngx_event_t *rev, *wev; 3373 ngx_event_t *rev, *wev;
3374 ngx_connection_t *c; 3374 ngx_http_request_t *r;
3375 ngx_http_core_loc_conf_t *clcf; 3375 ngx_http_core_loc_conf_t *clcf;
3376 3376
3377 c = r->connection; 3377 r = c->data;
3378 3378
3379 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 3379 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
3380
3381 if (r->lingering_time == 0) {
3382 r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
3383 }
3384
3385 #if (NGX_HTTP_SSL)
3386 if (c->ssl) {
3387 ngx_int_t rc;
3388
3389 rc = ngx_ssl_shutdown(c);
3390
3391 if (rc == NGX_ERROR) {
3392 ngx_http_close_request(r, 0);
3393 return;
3394 }
3395
3396 if (rc == NGX_AGAIN) {
3397 c->ssl->handler = ngx_http_set_lingering_close;
3398 return;
3399 }
3400
3401 c->recv = ngx_recv;
3402 }
3403 #endif
3380 3404
3381 rev = c->read; 3405 rev = c->read;
3382 rev->handler = ngx_http_lingering_close_handler; 3406 rev->handler = ngx_http_lingering_close_handler;
3383
3384 r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
3385 ngx_add_timer(rev, clcf->lingering_timeout);
3386 3407
3387 if (ngx_handle_read_event(rev, 0) != NGX_OK) { 3408 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
3388 ngx_http_close_request(r, 0); 3409 ngx_http_close_request(r, 0);
3389 return; 3410 return;
3390 } 3411 }
3403 ngx_connection_error(c, ngx_socket_errno, 3424 ngx_connection_error(c, ngx_socket_errno,
3404 ngx_shutdown_socket_n " failed"); 3425 ngx_shutdown_socket_n " failed");
3405 ngx_http_close_request(r, 0); 3426 ngx_http_close_request(r, 0);
3406 return; 3427 return;
3407 } 3428 }
3429
3430 ngx_add_timer(rev, clcf->lingering_timeout);
3408 3431
3409 if (rev->ready) { 3432 if (rev->ready) {
3410 ngx_http_lingering_close_handler(rev); 3433 ngx_http_lingering_close_handler(rev);
3411 } 3434 }
3412 } 3435 }