Accept cookies for analytics, social media, and advertising, or learn more and adjust your preferences. These cookies are on by default for visitors outside the UK and EEA. Privacy Notice.
nginx_uploadprogress_module - upstreamサーバに転送する時に RFC1867 POST アップロードを監視する、アップロード進捗システムの実装です。
アップロードされた内容を解析すること無しに、NGINXによってupstreamサーバにプロキシされるアップロードを追跡することで動作し、JavaScript、JSON、あるいは設定可能な形式でアップロードの進捗を報告するweb APIを提供します。NGINXはアップロードされたPOSTの内容をupstreamサーバに転送する前にディスクに格納し、upstreamサーバのアクセラレータとして振舞うため、このように動作します。個々の各POSTアップロードリクエストは進捗のユニークな識別子を持つべきです。
JSONと仕組みの考えは、Lighttpd の mod_uploadprogressに基づいています。
注意
このモジュールはNGINXのソースと一緒に配布されません。
masterzen/nginx-upload-progress-module
警告
バージョン 0.9.0 では、非互換の変更があります: JSONPは今では進捗の調査のデフォルトの出力です。もし、以下のように非推奨のjava出力を提供するこのモジュールに頼る場合は:
upload_progress_java_output
進捗調査locationの中で。
解凍した後で、以下のオプションをNGINX ./configure
コマンドに追加します。
--add-module=path/to/nginx_uploadprogress_module
警告
--with-debug
を使ってコンパイルされた場合、このモジュールはかなり多くのログメッセージを生成するでしょう。
構文: | upload_progress |
---|---|
デフォルト: | n/a |
コンテキスト: | http |
このディレクティブはアップロード進捗モジュールを有効にし、接続ごとの追跡情報を格納するために使われるzone_nameにzone_size バイトを予約します。
構文: | track_uploads |
---|---|
デフォルト: | n/a |
コンテキスト: | location |
このディレクティブは現在のlocationのためのアップロードの追跡を有効にします。このlocationへのPOSTの到着はzone_name アップロード進捗トラッカー内にリクエストを登録するでしょう。NGINXはまだ RFC 1867 アップロードをサポートしないため、locationは proxy_pass あるいは fastcgi location でなければなりません。POSTは、進捗情報を取得するために使われるユニークな識別子を値に持つX-Progress-IDと呼ばれるクエリパラメータ (あるいは同じ名前の HTTP ヘッダ)を持たなければなりません。POSTがそのような情報を持たない場合、アップロードは追跡されないでしょう。進捗調査をアップロードするために役立つ情報を提供できるように、追跡されている接続は終了後最大で timeout 秒保持されます。
警告
このディレクティブはlocationの最後のディレクティブでなければなりません。proxy_pass あるいは fastcgi_pass locationの中になければなりません。location内でのディレクティブの繰り返しはsegfaultsに繋がるでしょう。
構文: | report_uploads |
---|---|
デフォルト: | n/a |
コンテキスト: | location |
このディレクティブによりlocationはzone_nameについて track_uploadsによって追跡されるアップロード進捗を報告することができます。返されるドキュメントはデフォルトで4つの結果を取り得るJavascriptテキストです:
アップロードリクエストはまだ登録されていないか、unknownです:
new Object({ 'state' : 'starting' })
アップロードリクエストが終了しました:
new Object({ 'state' : 'done' })
アップロードリクエストがHTTPエラーを起こしました
new Object({ 'state' : 'error', 'status' : <error code> })
クライアントのために追跡に使うことができる1つのエラーコードが 413 (request entity too large) です。
アップロードリクエストは進行中です:
new Object({ 'state' : 'uploading', 'received' : <size_received>, 'size' : <total_size>})
このjavascriptの代わりにピュアなjsonを返すことができます (upload_progress_json_outputを見てください)。upload_progress_templateディレクティブを使って応答フォーマットを完全に設定することも可能です。
このlocationへのHTTPリクエストはX-Progress-IDパラメータを持つか、進捗中のアップロードの有効なユニークな識別子が含まれるHTTPヘッダを持つ必要があります。
構文: | upload_progress_content_type |
---|---|
デフォルト: | test/javascript |
コンテキスト: | location |
このディレクティブを使ってアップロード進捗調査content-typeを変更することができます。
構文: | upload_progress_header |
---|---|
デフォルト: | X-Progress-ID |
コンテキスト: | location |
このディレクティブを使って進捗IDのヘッダー名を変更することができます。
構文: | upload_progress_jsonp_parameter |
---|---|
デフォルト: | callback |
コンテキスト: | location |
このディレクティブを使って、jsonpコールバック名を持つGETパラメータの名前を変更することができます。
構文: | upload_progress_json_output |
---|---|
デフォルト: | n/a |
コンテキスト: | main,sever,location |
このディレクティブはピュアなjsonとして全てを出力するように設定します。
構文: | upload_progress_jsonp_output |
---|---|
デフォルト: | none |
コンテキスト: | location |
このディレクティブはjsonpとして全てを出力するように設定します(json出力だがcallbackをf持たない)。
構文: | upload_progress_template |
---|---|
デフォルト: | n/a |
コンテキスト: | location |
このディレクティブは進捗応答テンプレートをインストールするために使うことができます。利用可能な状態のリスト:
NGINXは以下の変数の値をアップロードについてのそれぞれの値に置き換えるでしょう:
例えば、(デフォルトのJavascriptあるいはjsonの代わりに)XMLを返すには:
upload_progress_content_type 'text/xml';
upload_progress_template starting '<upload><state>starting</state></upload>';
upload_progress_template uploading '<upload><state>uploading</state>
<size>$uploadprogress_length</size><uploaded>$uploadprogress_received</uploaded></upload>';
upload_progress_template done '<upload><state>done</state></upload>';
upload_progress_template error '<upload><state>error</state>
<syntaxhighlight>$uploadprogress_status</syntaxhighlight></upload>';
jsonp応答の例:
upload_progress_template starting "$uploadprogress_callback({ 'state' : 'starting'});";
upload_progress_template error "$uploadprogress_callback({ 'state' : 'error',
'status' : $uploadprogress_status });";
upload_progress_template done "$uploadprogress_callback({ 'state' : 'done'});";
upload_progress_template uploading "$uploadprogress_callback({ 'state' : 'uploading',
'received' : $uploadprogress_received, 'size' : $uploadprogress_length });";
http {
# reserve 1MB under the name 'proxied' to track uploads
upload_progress proxied 1m;
server {
listen 127.0.0.1 default;
server_name localhost;
root /path/to/root;
location / {
# proxy to upstream server
proxy_pass http://127.0.0.1;
proxy_redirect default;
# track uploads in the 'proxied' zone
# remember connections for 30s after they finished
track_uploads proxied 30s;
}
location ^~ /progress {
# report uploads tracked in the 'proxied' zone
report_uploads proxied;
}
}
}
(Lighttd mod_uploadprogress もジュールの例に基づいています):
まず、アップロードフォームが必要です:
<form id="upload" enctype="multipart/form-data"
action="/upload.php" method="post" onsubmit="openProgressBar(); return true;">
<input type="hidden" name="MAX_FILE_SIZE" value="30000000" />
<input name="userfile" type="file" label="fileupload" />
<input type="submit" value="Send File" />
</form>
進捗を表示するための進捗バー:
<div>
<div id="progress" style="width: 400px; border: 1px solid black">
<div id="progressbar" style="width: 1px; background-color: black; border: 1px solid white"> </div>
</div>
<div id="tp">(progress)</div>
</div>
そして、ユニークな識別子を生成し、submitアクション上でアップロードを起動する必要があります。これはajax進捗レポート機構も開始するでしょう。
interval = null;
function openProgressBar() {
/* generate random progress-id */
uuid = "";
for (i = 0; i < 32; i++) {
uuid += Math.floor(Math.random() * 16).toString(16);
}
/* patch the form-action tag to include the progress-id */
document.getElementById("upload").action="/upload.php?X-Progress-ID=" + uuid;
/* call the progress-updater every 1000ms */
interval = window.setInterval(
function () {
fetch(uuid);
},
1000
);
}
function fetch(uuid) {
req = new XMLHttpRequest();
req.open("GET", "/progress", 1);
req.setRequestHeader("X-Progress-ID", uuid);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
/* poor-man JSON parser */
var upload = eval(req.responseText);
document.getElementById('tp').innerHTML = upload.state;
/* change the width if the inner progress-bar */
if (upload.state == 'done' || upload.state == 'uploading') {
bar = document.getElementById('progressbar');
w = 400 * upload.received / upload.size;
bar.style.width = w + 'px';
}
/* we are done, stop the interval */
if (upload.state == 'done') {
window.clearTimeout(interval);
}
}
}
}
req.send(null);
}
NGINX upload-progress-module と一緒にjQueryプラグインを使うことができます - https://github.com/drogus/jquery-upload-progress (そのドキュメントに基づいています)。
htmlの一部:
<form id="upload" enctype="multipart/form-data" action="index.html" method="post">
<input name="file" type="file"/>
<input type="submit" value="Upload"/>
</form>
<div id="uploading">
<div id="progress" class="bar">
<div id="progressbar"> </div>
<div id="percents"></div>
</div>
</div>
cssの一部:
.bar {
width: 300px;
}
#progress {
background: #eee;
border: 1px solid #222;
margin-top: 20px;
}
#progressbar {
width: 0px;
height: 24px;
background: #333;
}
少しのjavascript
$(function() {
$('form').uploadProgress({
/* scripts locations for safari */
jqueryPath: "../lib/jquery.js",
uploadProgressPath: "../jquery.uploadProgress.js",
/* function called each time bar is updated */
uploading: function(upload) {$('#percents').html(upload.percents+'%');},
/* selector or element that will be updated */
progressBar: "#progressbar",
/* progress reports url */
progressUrl: "/progress",
/* how often will bar be updated */
interval: 2000
});
});
アップロードサーバが通常のwebサーバと違う場合など、異なるドメインあるいはサブドメイン(クロスドメイン)から進捗バーを更新する必要がある場合は、以下のようにJSONPプロトコルを試すことができます:
$(function() {
$('form').uploadProgress({
/* scripts locations for safari */
jqueryPath: "../lib/jquery.js",
uploadProgressPath: "../jquery.uploadProgress.js",
/* function called each time bar is updated */
uploading: function(upload) {$('#percents').html(upload.percents+'%');},
/* selector or element that will be updated */
progressBar: "#progressbar",
/* progress reports url in a different domain or subdomain from caller */
progressUrl: "uploads.somewhere.com/progress",
/* how often will bar be updated */
interval: 2000,
/* use json-p for cross-domain call */
dataType: 'jsonp'
});
});
デフォルト:
このソフトウェアは Valery Kholodkov の NGINX アップロードモジュールとも動作します: http://www.grid.net.ru/nginx/upload.en.html