Przeglądaj źródła

better handle cleanupped/freed connection in read_event_handler

tags/v0.4
Brice Figureau 18 lat temu
rodzic
commit
89e1b33ad1
1 zmienionych plików z 37 dodań i 38 usunięć
  1. 37
    38
      ngx_http_uploadprogress_module.c

+ 37
- 38
ngx_http_uploadprogress_module.c Wyświetl plik

@@ -28,6 +28,7 @@ struct ngx_http_uploadprogress_node_s {
28 28
 typedef struct {
29 29
     ngx_shm_zone_t                  *shm_zone;
30 30
     ngx_rbtree_node_t               *node;
31
+    ngx_http_request_t              *r;
31 32
     time_t                           timeout;
32 33
 } ngx_http_uploadprogress_cleanup_t;
33 34
 
@@ -299,49 +300,28 @@ static void ngx_http_uploadprogress_event_handler(ngx_http_request_t *r)
299 300
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upload-progress: ngx_http_uploadprogress_event_handler");
300 301
     
301 302
     c = r->connection;
303
+
304
+    /* find node, update rest */
305
+    id = get_tracking_id(r);
306
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
307
+                   "upload-progress: read_event_handler found id: %V", id);
308
+    upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
302 309
     
303 310
     /* call the original read event handler */
304 311
     module_ctx = ngx_http_get_module_ctx(r, ngx_http_uploadprogress_module);
305 312
     module_ctx->read_event_handler(r);
306 313
 
307
-    /* check that the request/connection is still OK */
308
-    if (r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE) {
309
-        /* should mark up as error */
310
-        id = get_tracking_id(r);
311
-        if (id != NULL) {
312
-            upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
313
-            if (upcf != NULL && upcf->shm_zone != NULL) {
314
-                ctx = upcf->shm_zone->data;
315
-
316
-                /* get the original connection of the upload */
317
-                shpool = (ngx_slab_pool_t *) upcf->shm_zone->shm.addr;
318
-
319
-                ngx_shmtx_lock(&shpool->mutex);
320
-                up = find_node(id, ctx, ngx_cycle->log);
321
-                if (up != NULL) {
322
-                    up->err_status = r->headers_out.status;
323
-                }
324
-                ngx_shmtx_unlock(&shpool->mutex);
325
-            }
326
-        }
327
-        return;
328
-    }
329
-
330
-    /* find node, update rest */
331
-    id = get_tracking_id(r);
314
+    /* at this stage, r is not anymore safe to use */
315
+    /* the request could have been closed/freed behind our back */
332 316
 
333 317
     if (id == NULL) {
334
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
318
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
335 319
                        "upload-progress: read_event_handler cant find id");
336 320
         return;
337 321
     }
338 322
 
339
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
340
-                   "upload-progress: read_event_handler found id: %V", id);
341
-
342
-    upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
343 323
     if (upcf->shm_zone == NULL) {
344
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
324
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
345 325
                        "upload-progress: read_event_handler no shm_zone for id: %V", id);
346 326
         return;
347 327
     }
@@ -353,16 +333,16 @@ static void ngx_http_uploadprogress_event_handler(ngx_http_request_t *r)
353 333
 
354 334
     ngx_shmtx_lock(&shpool->mutex);
355 335
 
356
-    up = find_node(id, ctx, r->connection->log);
336
+    up = find_node(id, ctx, ngx_cycle->log);
357 337
     if (up != NULL && !up->done) {
358
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
338
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
359 339
                        "upload-progress: read_event_handler found node: %V", id);
360 340
         up->rest = r->request_body->rest;
361 341
         up->length = r->headers_in.content_length_n;
362
-        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
342
+        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
363 343
                        "upload-progress: read_event_handler storing rest %uO/%uO for %V", up->rest, up->length, id);
364 344
     } else {
365
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
345
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
366 346
                        "upload-progress: read_event_handler not found: %V", id);
367 347
     }
368 348
     ngx_shmtx_unlock(&shpool->mutex);
@@ -515,15 +495,18 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
515 495
    * request not yet started: found = false
516 496
    * request in error:        err_status >= NGX_HTTP_SPECIAL_RESPONSE
517 497
    * request finished:        done = true
498
+   * request not yet started but registered:        length==0 && rest ==0
518 499
    * reauest in progress:     rest > 0 
519 500
  */
520 501
 
521 502
     if (!found) {
522
-        size = sizeof("new Object({ 'state' : 'starting' })\r\n");			
503
+        size = sizeof("new Object({ 'state' : 'starting' })\r\n");
523 504
     } else if (err_status >= NGX_HTTP_SPECIAL_RESPONSE) {
524 505
         size = sizeof("new Object({ 'state' : 'error', 'status' : ") + NGX_INT_T_LEN + sizeof(" })\r\n");
525 506
     } else if (done) {
526 507
         size = sizeof("new Object({ 'state' : 'done' })\r\n");
508
+    } else if ( length == 0 && rest == 0 ) {
509
+        size = sizeof("new Object({ 'state' : 'starting' })\r\n");
527 510
     } else {
528 511
         size = sizeof("new Object({ 'state' : 'uploading', 'received' : ") + NGX_INT_T_LEN + sizeof(" })\r\n");
529 512
         size += sizeof(", 'size' : ") + NGX_INT_T_LEN;
@@ -552,6 +535,10 @@ ngx_http_reportuploads_handler(ngx_http_request_t * r)
552 535
                              sizeof("new Object({ 'state' : 'done' })\r\n") - 1);
553 536
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
554 537
                         "reportuploads returning done");
538
+    } else if (length == 0 && rest == 0) {
539
+        b->last = ngx_cpymem(b->last, "new Object({ 'state' : 'starting' })\r\n",
540
+                            sizeof("new Object({ 'state' : 'starting' })\r\n") - 1);
541
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "reportuploads returning starting");
555 542
     } else {
556 543
         b->last = ngx_cpymem(b->last, "new Object({ 'state' : 'uploading', 'received' : ",
557 544
                              sizeof("new Object({ 'state' : 'uploading', 'received' : ") - 1);
@@ -689,9 +676,9 @@ ngx_http_uploadprogress_handler(ngx_http_request_t * r)
689 676
     upcln->shm_zone = upcf->shm_zone;
690 677
     upcln->node = node;
691 678
     upcln->timeout = upcf->timeout;
679
+    upcln->r = r;
692 680
 
693
-    /* start the timer if needed */
694
-
681
+    /* finally says to the core we don't handle anything */
695 682
     return NGX_DECLINED;
696 683
 }
697 684
 
@@ -824,6 +811,7 @@ ngx_http_uploadprogress_cleanup(void *data)
824 811
     ngx_rbtree_node_t               *node;
825 812
     ngx_http_uploadprogress_ctx_t   *ctx;
826 813
     ngx_http_uploadprogress_node_t  *up;
814
+    ngx_http_request_t              *r;
827 815
 
828 816
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, upcln->shm_zone->shm.log, 0,
829 817
                    "uploadprogress cleanup called");
@@ -831,11 +819,21 @@ ngx_http_uploadprogress_cleanup(void *data)
831 819
     ctx = upcln->shm_zone->data;
832 820
     shpool = (ngx_slab_pool_t *) upcln->shm_zone->shm.addr;
833 821
     node = upcln->node;
822
+    r = upcln->r;
834 823
     up = (ngx_http_uploadprogress_node_t *) node;
835 824
 
836 825
     ngx_shmtx_lock(&shpool->mutex);
826
+    
837 827
     up->done = 1;               /* mark the original request as done */
838 828
     up->timeout = ngx_time() + upcln->timeout;      /* keep tracking for 60s */
829
+    
830
+    if (r != NULL ) {
831
+        ngx_uint_t rc = r->err_status ? r->err_status : r->headers_out.status;
832
+        if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
833
+            up->err_status = rc;
834
+        }
835
+    }
836
+    
839 837
     ngx_shmtx_unlock(&shpool->mutex);
840 838
 
841 839
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, upcln->shm_zone->shm.log, 0,
@@ -989,6 +987,7 @@ ngx_http_uploadprogress_errortracker(ngx_http_request_t * r)
989 987
         upcln->shm_zone = upcf->shm_zone;
990 988
         upcln->node = node;
991 989
         upcln->timeout = upcf->timeout;
990
+        upcln->r = r;
992 991
 
993 992
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
994 993
                        "trackuploads error-tracking adding: %08XD", node->key);

Ładowanie…
Anuluj
Zapisz