|
|
@@ -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
|
{
|