Kaynağa Gözat

Ability to notify remote server about upload progress via UDP messages

pull/30/head
devgs 13 yıl önce
ebeveyn
işleme
0c7662d166
1 değiştirilmiş dosya ile 76 ekleme ve 2 silme
  1. 76
    2
      ngx_http_uploadprogress_module.c

+ 76
- 2
ngx_http_uploadprogress_module.c Dosyayı Görüntüle

@@ -32,6 +32,7 @@ struct ngx_http_uploadprogress_node_s {
32 32
     off_t                            rest;
33 33
     off_t                            length;
34 34
     ngx_uint_t                       done;
35
+    ngx_uint_t                       sequence;
35 36
     time_t                           timeout;
36 37
     struct ngx_http_uploadprogress_node_s *prev;
37 38
     struct ngx_http_uploadprogress_node_s *next;
@@ -68,6 +69,9 @@ typedef struct {
68 69
     ngx_str_t                        header;
69 70
     ngx_str_t                        header_mul;
70 71
 
72
+    ngx_addr_t                       progress_server;
73
+    int                              udp_socket;
74
+
71 75
     ngx_str_t                        jsonp_parameter;
72 76
     ngx_int_t                        json_multiple:1;
73 77
 } ngx_http_uploadprogress_conf_t;
@@ -104,6 +108,7 @@ static char* ngx_http_upload_progress_java_output(ngx_conf_t * cf, ngx_command_t
104 108
 static char* ngx_http_upload_progress_json_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
105 109
 static char* ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
106 110
 static char* ngx_http_upload_progress_json_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
111
+static char* ngx_http_upload_progress_jsonp_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
107 112
 static void ngx_clean_old_connections(ngx_event_t * ev);
108 113
 static ngx_int_t ngx_http_uploadprogress_content_handler(ngx_http_request_t *r);
109 114
 
@@ -119,7 +124,7 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
119 124
      NULL},
120 125
 
121 126
     {ngx_string("track_uploads"),
122
-     NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE2,
127
+     NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE2 | NGX_CONF_TAKE3,
123 128
      ngx_http_track_uploads,
124 129
      NGX_HTTP_LOC_CONF_OFFSET,
125 130
      0,
@@ -174,6 +179,13 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
174 179
      0,
175 180
      NULL},
176 181
 
182
+    {ngx_string("upload_progress_jsonp_multiple_output"),
183
+     NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
184
+     ngx_http_upload_progress_jsonp_multiple_output,
185
+     NGX_HTTP_LOC_CONF_OFFSET,
186
+     0,
187
+     NULL},
188
+
177 189
     {ngx_string("upload_progress_header"),
178 190
      NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
179 191
      ngx_conf_set_str_slot,
@@ -293,6 +305,13 @@ static ngx_str_t ngx_http_uploadprogress_json_multiple_defaults[] = {
293 305
     ngx_string("{ \"id\" : $uploadprogress_id, \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length }")
294 306
 };
295 307
 
308
+static ngx_str_t ngx_http_uploadprogress_jsonp_multiple_defaults[] = {
309
+    ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"starting\" });\r\n"),
310
+    ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"error\", \"status\" : $uploadprogress_status });\r\n"),
311
+    ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"done\" });\r\n"),
312
+    ngx_string("$uploadprogress_callback({ \"id\" : $uploadprogress_id, \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });\r\n")
313
+};
314
+
296 315
 
297 316
 static ngx_array_t ngx_http_uploadprogress_global_templates;
298 317
 
@@ -644,6 +663,15 @@ static void ngx_http_uploadprogress_event_handler(ngx_http_request_t *r)
644 663
         up->rest = r->request_body->rest;
645 664
         if(up->length == 0)
646 665
             up->length = r->headers_in.content_length_n;
666
+        if(upcf->udp_socket != -1 && upcf->progress_server.socklen != 0)
667
+        {
668
+            u_char      datagram_buf[1024];
669
+            u_char *    end;
670
+
671
+            end = ngx_snprintf(datagram_buf, sizeof(datagram_buf), "{\"id\" : \"%V\", \"sequence\", \"size\" : %u, \"uploaded\" : %u}", id, up->sequence, up->length, up->rest);
672
+            sendto(upcf->udp_socket, datagram_buf, end - datagram_buf, 0, (struct sockaddr*)upcf->progress_server.sockaddr, upcf->progress_server.socklen);
673
+            ++up->sequence;
674
+        }
647 675
         ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
648 676
                        "upload-progress: read_event_handler storing rest %uO/%uO for %V", up->rest, up->length, id);
649 677
     } else {
@@ -1155,6 +1183,7 @@ ngx_http_uploadprogress_handler(ngx_http_request_t * r)
1155 1183
     up->rest = 0;
1156 1184
     up->length = 0;
1157 1185
     up->timeout = 0;
1186
+    up->sequence = 0;
1158 1187
 
1159 1188
     up->next = ctx->list_head.next;
1160 1189
     up->next->prev = up;
@@ -1495,6 +1524,7 @@ ngx_http_uploadprogress_errortracker(ngx_http_request_t * r)
1495 1524
         up->rest = 0;
1496 1525
         up->length = 0;
1497 1526
         up->timeout = 0;
1527
+        up->sequence = 0;
1498 1528
 
1499 1529
         ngx_memcpy(up->data, id->data, id->len);
1500 1530
 
@@ -1746,6 +1776,7 @@ ngx_http_track_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
1746 1776
     ngx_http_core_loc_conf_t        *clcf;
1747 1777
     ngx_http_uploadprogress_conf_t  *lzcf = conf;
1748 1778
     ngx_str_t                       *value;
1779
+    ngx_url_t                       url;
1749 1780
 
1750 1781
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "ngx_track_uploads in");
1751 1782
 
@@ -1770,10 +1801,27 @@ ngx_http_track_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
1770 1801
     lzcf->timeout = ngx_parse_time(&value[2], 1);
1771 1802
     if (lzcf->timeout == NGX_ERROR) {
1772 1803
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1773
-                           "track_uploads \"%V\" timeout value invalid", &value[1]);
1804
+                           "track_uploads \"%V\" timeout value invalid", &value[2]);
1774 1805
         return NGX_CONF_ERROR;
1775 1806
     }
1776 1807
 
1808
+    if(cf->args->nelts > 3)
1809
+    {
1810
+        ngx_memzero(&url, sizeof(ngx_url_t));
1811
+        url.url = value[3];
1812
+        url.default_port = 80;
1813
+        url.no_resolve = 0;
1814
+
1815
+        if(ngx_parse_url(cf->pool, &url) != NGX_OK)
1816
+        {
1817
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "Invalid graphite server %V: %s", &url.host, url.err);
1818
+            return NGX_CONF_ERROR;
1819
+        }
1820
+        lzcf->progress_server = url.addrs[0];
1821
+        if(lzcf->udp_socket == -1)
1822
+            lzcf->udp_socket = ngx_socket(PF_INET, SOCK_DGRAM, 0);
1823
+    }
1824
+
1777 1825
     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
1778 1826
     lzcf->handler = clcf->handler;
1779 1827
     if ( lzcf->handler == NULL )
@@ -1981,6 +2029,32 @@ ngx_http_upload_progress_json_multiple_output(ngx_conf_t * cf, ngx_command_t * c
1981 2029
     return NGX_CONF_OK;
1982 2030
 }
1983 2031
 
2032
+static char*
2033
+ngx_http_upload_progress_jsonp_multiple_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
2034
+{
2035
+    ngx_http_uploadprogress_conf_t       *upcf = conf;
2036
+    ngx_http_uploadprogress_template_t   *t;
2037
+    ngx_uint_t                            i;
2038
+    char*                                 rc;
2039
+
2040
+    upcf->json_multiple = 1;
2041
+
2042
+    t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
2043
+
2044
+    for(i = 0;i < upcf->templates.nelts;i++) {
2045
+        rc = ngx_http_upload_progress_set_template(cf, t + i, ngx_http_uploadprogress_jsonp_multiple_defaults + i);
2046
+
2047
+        if(rc != NGX_CONF_OK) {
2048
+            return rc;
2049
+        }
2050
+    }
2051
+
2052
+    upcf->content_type.data = (u_char*)"application/json";
2053
+    upcf->content_type.len = sizeof("application/json") - 1;
2054
+
2055
+    return NGX_CONF_OK;
2056
+}
2057
+
1984 2058
 static ngx_int_t ngx_http_uploadprogress_received_variable(ngx_http_request_t *r,
1985 2059
     ngx_http_variable_value_t *v, uintptr_t data)
1986 2060
 {

Loading…
İptal
Kaydet