Quellcode durchsuchen

Support jsonp by storing the value of the callback parameter in $uploadprogress_callback.

Added an 'upload_progress_jsonp_output' directive that sets templates that work with jsonp.
Make jsonp parameter name configurable with the 'upload_progress_jsonp_parameter' directive.
tags/v0.8
Bruno Deferrari vor 16 Jahren
Ursprung
Commit
c4551e8d7f
2 geänderte Dateien mit 131 neuen und 0 gelöschten Zeilen
  1. 23
    0
      README
  2. 108
    0
      ngx_http_uploadprogress_module.c

+ 23
- 0
README Datei anzeigen

@@ -125,6 +125,14 @@ upload_progress_header
125 125
     :Description:
126 126
     This directive allows to change the header name of the progress ID.
127 127
 
128
+upload_progress_jsonp_parameter
129
+++++++++++++++++++++++
130
+    :Syntax: upload_progress_jsonp_parameter <callback_parameter>
131
+    :Default: callback
132
+    :Context: location
133
+    :Description:
134
+    This directive allows to change the name of the GET parameter with the jsonp callback name.
135
+
128 136
 upload_progress_json_output
129 137
 +++++++++++++++++++++++++++
130 138
     :Syntax: upload_progress_json_output
@@ -133,6 +141,14 @@ upload_progress_json_output
133 141
     :Description:
134 142
     This directive sets everything to output as pure json.
135 143
 
144
+upload_progress_jsonp_output
145
++++++++++++++++++++++++++++
146
+    :Syntax: upload_progress_jsonp_output
147
+    :Default: N/A
148
+    :Context: location
149
+    :Description:
150
+    This directive sets everything to output as jsonp (like json output, but with callback).
151
+
136 152
 upload_progress_template
137 153
 ++++++++++++++++++++++++
138 154
     :Syntax: upload_progress_template <state> <template>
@@ -151,6 +167,7 @@ upload_progress_template
151 167
         * $uploadprogress_length: total size of the upload
152 168
         * $uploadprogress_received: what the server has received so far
153 169
         * $uploadprogress_status: error code in case of HTTP error
170
+        * $uploadprogress_callback: jsonp callback name if provided as a GET query parameter with name 'callback'
154 171
     
155 172
     For instance to return XML (instead of the default Javascript or json):
156 173
 
@@ -160,6 +177,12 @@ upload_progress_template
160 177
     upload_progress_template done '<upload><state>done</state></upload>';
161 178
     upload_progress_template error '<upload><state>error</state><code>$uploadprogress_status</code></upload>';
162 179
 
180
+    Example of jsonp response:
181
+
182
+    upload_progress_template starting "$uploadprogress_callback({ 'state' : 'starting'});";
183
+    upload_progress_template error "$uploadprogress_callback({ 'state' : 'error', 'status' : $uploadprogress_status });";
184
+    upload_progress_template done "$uploadprogress_callback({ 'state' : 'done'});";
185
+    upload_progress_template uploading "$uploadprogress_callback({ 'state' : 'uploading', 'received' : $uploadprogress_received, 'size' : $uploadprogress_length });";
163 186
 
164 187
 Configuration Example:
165 188
 +++++++++++++++++++++

+ 108
- 0
ngx_http_uploadprogress_module.c Datei anzeigen

@@ -65,6 +65,7 @@ typedef struct {
65 65
     ngx_str_t                        content_type;
66 66
     ngx_array_t                      templates;
67 67
     ngx_str_t                        header;
68
+    ngx_str_t                        jsonp_parameter;
68 69
 } ngx_http_uploadprogress_conf_t;
69 70
 
70 71
 typedef struct {
@@ -86,12 +87,15 @@ static ngx_int_t ngx_http_uploadprogress_offset_variable(ngx_http_request_t *r,
86 87
     ngx_http_variable_value_t *v, uintptr_t data);
87 88
 static ngx_int_t ngx_http_uploadprogress_status_variable(ngx_http_request_t *r,
88 89
     ngx_http_variable_value_t *v, uintptr_t data);
90
+static ngx_int_t ngx_http_uploadprogress_callback_variable(ngx_http_request_t *r,
91
+    ngx_http_variable_value_t *v, uintptr_t data);
89 92
 static char* ngx_http_upload_progress_set_template(ngx_conf_t * cf, ngx_http_uploadprogress_template_t *t, ngx_str_t *source);
90 93
 static char *ngx_http_track_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
91 94
 static char *ngx_http_report_uploads(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
92 95
 static char *ngx_http_upload_progress(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
93 96
 static char* ngx_http_upload_progress_template(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
94 97
 static char* ngx_http_upload_progress_json_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
98
+static char* ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
95 99
 static void ngx_clean_old_connections(ngx_event_t * ev);
96 100
 static ngx_int_t ngx_http_uploadprogress_content_handler(ngx_http_request_t *r);
97 101
 
@@ -141,6 +145,13 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
141 145
      0,
142 146
      NULL},
143 147
 
148
+    {ngx_string("upload_progress_jsonp_output"),
149
+     NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
150
+     ngx_http_upload_progress_jsonp_output,
151
+     NGX_HTTP_LOC_CONF_OFFSET,
152
+     0,
153
+     NULL},
154
+
144 155
     {ngx_string("upload_progress_header"),
145 156
      NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
146 157
      ngx_conf_set_str_slot,
@@ -148,6 +159,13 @@ static ngx_command_t ngx_http_uploadprogress_commands[] = {
148 159
      offsetof(ngx_http_uploadprogress_conf_t, header),
149 160
      NULL},
150 161
 
162
+    {ngx_string("upload_progress_jsonp_parameter"),
163
+     NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
164
+     ngx_conf_set_str_slot,
165
+     NGX_HTTP_LOC_CONF_OFFSET,
166
+     offsetof(ngx_http_uploadprogress_conf_t, jsonp_parameter),
167
+     NULL},
168
+
151 169
     ngx_null_command
152 170
 };
153 171
 
@@ -169,6 +187,10 @@ static ngx_http_variable_t  ngx_http_uploadprogress_variables[] = {
169 187
       (uintptr_t) offsetof(ngx_http_uploadprogress_node_t, err_status),
170 188
       NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
171 189
 
190
+    { ngx_string("uploadprogress_callback"), NULL, ngx_http_uploadprogress_callback_variable,
191
+      (uintptr_t) NULL,
192
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
193
+
172 194
     { ngx_null_string, NULL, NULL, 0, 0, 0 }
173 195
 };
174 196
 
@@ -224,6 +246,14 @@ static ngx_str_t ngx_http_uploadprogress_json_defaults[] = {
224 246
     ngx_string("{ \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length }\r\n")
225 247
 };
226 248
 
249
+static ngx_str_t ngx_http_uploadprogress_jsonp_defaults[] = {
250
+    ngx_string("$uploadprogress_callback({ \"state\" : \"starting\" });\r\n"),
251
+    ngx_string("$uploadprogress_callback({ \"state\" : \"error\", \"status\" : $uploadprogress_status });\r\n"),
252
+    ngx_string("$uploadprogress_callback({ \"state\" : \"done\" });\r\n"),
253
+    ngx_string("$uploadprogress_callback({ \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });\r\n")
254
+};
255
+
256
+
227 257
 static ngx_array_t ngx_http_uploadprogress_global_templates;
228 258
 
229 259
 static ngx_str_t*
@@ -1267,6 +1297,7 @@ ngx_http_uploadprogress_merge_loc_conf(ngx_conf_t * cf, void *parent, void *chil
1267 1297
     } 
1268 1298
 
1269 1299
     ngx_conf_merge_str_value(conf->header, prev->header, "X-Progress-ID");
1300
+    ngx_conf_merge_str_value(conf->jsonp_parameter, prev->jsonp_parameter, "callback");
1270 1301
 
1271 1302
     return NGX_CONF_OK;
1272 1303
 }
@@ -1546,6 +1577,30 @@ ngx_http_upload_progress_json_output(ngx_conf_t * cf, ngx_command_t * cmd, void
1546 1577
     return NGX_CONF_OK;
1547 1578
 }
1548 1579
 
1580
+static char*
1581
+ngx_http_upload_progress_jsonp_output(ngx_conf_t * cf, ngx_command_t * cmd, void *conf)
1582
+{
1583
+    ngx_http_uploadprogress_conf_t       *upcf = conf;
1584
+    ngx_http_uploadprogress_template_t   *t;
1585
+    ngx_uint_t                            i;
1586
+    char*                                 rc;
1587
+
1588
+    t = (ngx_http_uploadprogress_template_t*)upcf->templates.elts;
1589
+
1590
+    for(i = 0;i < upcf->templates.nelts;i++) {
1591
+        rc = ngx_http_upload_progress_set_template(cf, t + i, ngx_http_uploadprogress_jsonp_defaults + i);
1592
+
1593
+        if(rc != NGX_CONF_OK) {
1594
+            return rc;
1595
+        }
1596
+    }
1597
+
1598
+    upcf->content_type.data = (u_char*)"application/javascript";
1599
+    upcf->content_type.len = sizeof("application/javascript") - 1;
1600
+
1601
+    return NGX_CONF_OK;
1602
+}
1603
+
1549 1604
 static ngx_int_t ngx_http_uploadprogress_received_variable(ngx_http_request_t *r,
1550 1605
     ngx_http_variable_value_t *v, uintptr_t data)
1551 1606
 {
@@ -1622,3 +1677,56 @@ ngx_http_uploadprogress_status_variable(ngx_http_request_t *r,
1622 1677
     return NGX_OK;
1623 1678
 }
1624 1679
 
1680
+static ngx_int_t
1681
+ngx_http_uploadprogress_callback_variable(ngx_http_request_t *r,
1682
+    ngx_http_variable_value_t *v,  uintptr_t data)
1683
+{
1684
+    u_char                          *p, *start_p, *val, prefix[1024];
1685
+    ngx_http_uploadprogress_conf_t  *upcf;
1686
+    u_int                            len;
1687
+
1688
+    upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
1689
+
1690
+    if (r->args.len) {
1691
+        /* '=' has to be appended to avoid matching parameters that have the */
1692
+        /* configured name as a prefix but are longer */
1693
+        ngx_snprintf(prefix, sizeof(prefix) - 1, "%s=", upcf->jsonp_parameter.data);
1694
+        len = upcf->jsonp_parameter.len + 1;
1695
+        prefix[len] = '\0'; /* Force termination of string */
1696
+
1697
+        p = (u_char *) ngx_strstr(r->args.data, prefix);
1698
+
1699
+        if (p) {
1700
+            p += len;
1701
+            start_p = p;
1702
+            while (p < r->args.data + r->args.len) {
1703
+                if (*((p++) + 1) == '&') {
1704
+                    break;
1705
+                }
1706
+            }
1707
+
1708
+            v->len = p - start_p;
1709
+
1710
+            val = ngx_palloc(r->pool, v->len + 1);
1711
+            if (val == NULL) {
1712
+                return NGX_ERROR;
1713
+            }
1714
+
1715
+            ngx_memcpy(val, start_p, v->len);
1716
+            val[v->len] = '\0';
1717
+
1718
+            v->valid = 1;
1719
+            v->no_cacheable = 0;
1720
+            v->not_found = 0;
1721
+            v->data = val;
1722
+        } else {
1723
+            return NGX_ERROR;
1724
+        }
1725
+    } else {
1726
+        return NGX_ERROR;
1727
+    }
1728
+
1729
+    return NGX_OK;
1730
+}
1731
+
1732
+

Laden…
Abbrechen
Speichern