• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

test/H03-May-2022-5140

CHANGESH A D20-Oct-20163.9 KiB11269

LICENSEH A D20-Oct-20161.3 KiB2625

MakefileH A D20-Oct-2016374 97

READMEH A D20-Oct-201611.5 KiB330259

configH A D20-Oct-2016425 1210

ngx_http_uploadprogress_module.cH A D20-Oct-201656 KiB1,7751,319

README

1Nginx Upload Progress Module
2============================
3
4Introduction
5============
6
7nginx_uploadprogress_module is an implementation of an upload progress system, that monitors
8RFC1867 POST upload as they are transmitted to upstream servers.
9
10It works by tracking the uploads proxied by Nginx to upstream servers without
11analysing the uploaded content and offers a web API to report upload progress in Javscript, Json or any
12other format (through the help of templates).
13
14It works because Nginx acts as an accelerator of an upstream server, storing uploaded POST content
15on disk, before transmitting it to the upstream server. Each individual POST upload request
16should contain a progress unique identifier.
17
18This module is Copyright (c) 2007-2012 Brice Figureau, and is licensed under the BSD license (see LICENSE).
19 * rbtree and shm_zone code is based on Igor Sysoev limit_zone Nginx module.
20 * expire header code is based on Igor Sysoev header_filter Nginx module.
21
22The JSON idea and the mechanism idea are based on Lighttpd mod_uploadprogress:
23http://blog.lighttpd.net/articles/2006/08/01/mod_uploadprogress-is-back
24
25
26WARNING:
27 * when compiled with --with-debug, this module will produce high number of log messages.
28
29INCOMPATIBLE CHANGES
30====================
31
32v0.9.0:
33
34JSONP is now the default output of the progress probes. If you rely on this module serving
35the deprecated java output use:
36     upload_progress_java_output
37in the progress probe location.
38
39
40Installation
41============
42
43nginx_uploadprogress_module has been tested with Nginx 0.6.x, 0.7.x, 0.8.x and 1.0.x.
44
45Download the Nginx sources from http://nginx.net/ and unpack it.
46
47To build Nginx, change to the directory which contains the Nginx
48sources, and run the configuration script making sure to add the path
49to the nginx_uploadprogress_module sources using the --add-module option: ::
50
51 $ ./configure --add-module=/path/to/nginx_uploadprogress_module/
52
53Now you can build and install the software:
54
55 $ make
56
57and as root:
58
59 $ make install
60
61
62Configuration
63=============
64
65Each upload request should be assigned a unique identifier. This unique identifier will be used
66to store the request and reference it to report.
67This identifier can be transmitted either as a GET argument or as an HTTP header whose name is X-Progress-ID.
68
69upload_progress
70+++++++++++++++
71    :Syntax: upload_progress <zone_name> <zone_size>
72    :Default: none
73    :Context: http
74    :Description:
75    This directive enables the upload progress module and reserve <zone_size> bytes to the <zone_name> which
76    will be used to store the per-connection tracking information.
77
78track_uploads
79+++++++++++++
80    :Syntax: track_uploads <zone_name> <timeout>
81    :Default: none
82    :Context: location
83    :Description:
84    This directive enables tracking uploads for the current location. Each POST landing in this location will register
85    the request in the <zone_name> upload progress tracker.
86    Since Nginx doesn't support yet RFC 1867 upload, the location must be a proxy_pass or fastcgi location.
87    The POST _must_ have a query parameter called X-Progress-ID (or an HTTP header of the same name) whose value is the
88    unique identifier used to get progress information. If the POST has no such information, the upload will not be tracked.
89    The tracked connections are kept at most <timeout> seconds after they have been finished to be able to serve
90    useful information to upload progress probes.
91    WARNING: this directive must be the last directive of the location. It must be in a proxy_pass or
92    fastcgi_pass location.
93
94report_uploads
95++++++++++++++
96    :Syntax: report_uploads <zone_name>
97    :Default: none
98    :Context: location
99    :Description:
100    This directive allows a location to report the upload progress that is tracked by track_uploads for <zone_name>.
101    The returned document is a Javascript text with the possible 4 results by default:
102      * the upload request hasn't been registered yet or is unknown:
103                new Object({ 'state' : 'starting' })
104
105        * the upload request has ended:
106                new Object({ 'state' : 'done' })
107
108        * the upload request generated an HTTP error
109                new Object({ 'state' : 'error', 'status' : <error code> })
110            one error code that can be of use to track for the client is 413 (request entity too large).
111
112        * the upload request is in progress:
113                new Object({ 'state' : 'uploading', 'received' : <size_received>, 'size' : <total_size>})
114
115    It is possible to return pure json instead of this javascript (see upload_progress_json_output).
116    It is also possible to configure completely the response format with the directive:
117            upload_progress_template
118
119    The HTTP request to this location must have a X-Progress-ID parameter or HTTP header containing a valid
120    unique identifier of an in progress upload.
121
122upload_progress_content_type
123++++++++++++++++++++++++++++
124    :Syntax: upload_progress_content_type <content_type>
125    :Default: text/javascript
126    :Context: location
127    :Description:
128    This directive allows to change the upload progress probe response content-type.
129
130upload_progress_header
131++++++++++++++++++++++
132    :Syntax: upload_progress_header <progress-id>
133    :Default: X-Progress-ID
134    :Context: location
135    :Description:
136    This directive allows to change the header name of the progress ID.
137
138upload_progress_jsonp_parameter
139++++++++++++++++++++++
140    :Syntax: upload_progress_jsonp_parameter <callback_parameter>
141    :Default: callback
142    :Context: location
143    :Description:
144    This directive allows to change the name of the GET parameter with the jsonp callback name.
145
146upload_progress_java_output
147+++++++++++++++++++++++++++
148    :Syntax: upload_progress_java_output
149    :Default: N/A
150    :Context: location
151    :Description:
152    This directive sets everything to output as eval() javascript compatible code.
153
154upload_progress_json_output
155+++++++++++++++++++++++++++
156    :Syntax: upload_progress_json_output
157    :Default: N/A
158    :Context: location
159    :Description:
160    This directive sets everything to output as pure json.
161
162upload_progress_jsonp_output
163++++++++++++++++++++++++++++
164    :Syntax: upload_progress_jsonp_output
165    :Default: N/A
166    :Context: location
167    :Description:
168    This directive sets everything to output as jsonp (like json output, but with callback).
169
170upload_progress_template
171++++++++++++++++++++++++
172    :Syntax: upload_progress_template <state> <template>
173    :Default: none
174    :Context: location
175    :Description:
176    This directive can be used to install a progress response template.
177    The available list of state is:
178        * starting
179        * uploading
180        * error
181        * done
182
183    Nginx will replace the value of the following variables with their respective
184    value for the upload:
185        * $uploadprogress_length: total size of the upload
186        * $uploadprogress_received: what the server has received so far
187        * $uploadprogress_status: error code in case of HTTP error
188        * $uploadprogress_callback: jsonp callback name if provided as a GET query parameter with name 'callback'
189
190    For instance to return XML (instead of the default Javascript or json):
191
192    upload_progress_content_type 'text/xml';
193    upload_progress_template starting '<upload><state>starting</state></upload>';
194    upload_progress_template uploading '<upload><state>uploading</state><size>$uploadprogress_length</size><uploaded>$uploadprogress_received</uploaded></upload>';
195    upload_progress_template done '<upload><state>done</state></upload>';
196    upload_progress_template error '<upload><state>error</state><code>$uploadprogress_status</code></upload>';
197
198    Example of jsonp response:
199
200    upload_progress_template starting "$uploadprogress_callback({ \"state\" : \"starting\"});";
201    upload_progress_template error "$uploadprogress_callback({ \"state\" : \"error\", \"status\" : $uploadprogress_status });";
202    upload_progress_template done "$uploadprogress_callback({ \"state\" : \"done\"});";
203    upload_progress_template uploading "$uploadprogress_callback({ \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });";
204
205Configuration Example:
206+++++++++++++++++++++
207
208http {
209
210    # reserve 1MB under the name 'proxied' to track uploads
211    upload_progress proxied 1m;
212
213  server {
214        listen       127.0.0.1 default;
215        server_name  _ *;
216
217        root /path/to/root;
218
219        location / {
220            # proxy to upstream server
221            proxy_pass http://127.0.0.1;
222            proxy_redirect default;
223
224            # track uploads in the 'proxied' zone
225            # remember connections for 30s after they finished
226            track_uploads proxied 30s;
227        }
228
229        location ^~ /progress {
230            # report uploads tracked in the 'proxied' zone
231            report_uploads proxied;
232        }
233}
234
235
236Usage Example
237=============
238
239(based on Lighttd mod_uploadprogress module example):
240
241First we need a upload form:
242
243  <form id="upload" enctype="multipart/form-data"
244    action="/upload.php" method="post"
245    onsubmit="openProgressBar(); return true;">
246  <input type="hidden" name="MAX_FILE_SIZE" value="30000000"  />
247  <input name="userfile" type="file" label="fileupload" />
248  <input type="submit" value="Send File" />
249  </form>
250
251And a progress bar to visualize the progress:
252
253  <div>
254   <div id="progress" style="width: 400px; border: 1px solid black">
255    <div id="progressbar"
256       style="width: 1px; background-color: black; border: 1px solid white">
257     &nbsp;
258    </div>
259   </div>
260   <div id="tp">(progress)</div>
261  </div>
262
263Then we need to generate the Unique Identifier and launch the upload on submit
264action. This also will start the ajax progress report mechanism.
265
266 interval = null;
267
268function openProgressBar() {
269 /* generate random progress-id */
270 uuid = "";
271 for (i = 0; i < 32; i++) {
272  uuid += Math.floor(Math.random() * 16).toString(16);
273 }
274 /* patch the form-action tag to include the progress-id */
275 document.getElementById("upload").action="/upload.php?X-Progress-ID=" + uuid;
276
277 /* call the progress-updater every 1000ms */
278 interval = window.setInterval(
279   function () {
280     fetch(uuid);
281   },
282   1000
283 );
284}
285
286function fetch(uuid) {
287 req = new XMLHttpRequest();
288 req.open("GET", "/progress", 1);
289 req.setRequestHeader("X-Progress-ID", uuid);
290 req.onreadystatechange = function () {
291  if (req.readyState == 4) {
292   if (req.status == 200) {
293    /* poor-man JSON parser */
294    var upload = eval(req.responseText);
295
296    document.getElementById('tp').innerHTML = upload.state;
297
298    /* change the width if the inner progress-bar */
299    if (upload.state == 'done' || upload.state == 'uploading') {
300     bar = document.getElementById('progressbar');
301     w = 400 * upload.received / upload.size;
302     bar.style.width = w + 'px';
303    }
304    /* we are done, stop the interval */
305    if (upload.state == 'done') {
306     window.clearTimeout(interval);
307    }
308   }
309  }
310 }
311 req.send(null);
312}
313
314Companion Software
315==================
316
317This software can also work with Valery Kholodkov' Nginx Upload Module:
318http://www.grid.net.ru/nginx/upload.en.html
319
320You can also use the following javascript libraries client side:
321http://drogomir.com/blog/2008/6/30/upload-progress-script-with-safari-support
322
323Note that when using jQuery AJAX for progress monitoring, such as:
324https://github.com/drogus/jquery-upload-progress
325you should be sure to set a upload_progress template parameter:
326upload_progress_json_output
327or
328upload_progress_jsonp_output
329depending on your jQuery AJAX dataType setting.
330