Web ブラウザーでファイルをアップロードしたりダウンロードしたりすることは、事実上すべての Web アプリケーションやサービスで一般的なタスクです。この記事では、100 行未満のコードでこれを実行する方法を説明します。使用するデータベースは PostgreSQL、Web サーバーは Nginx です。
Gliimly をアプリケーション サーバーおよびプログラミング言語として使用します。パフォーマンスとセキュリティのため、またより豊富な Web 機能を有効にするために、Web サーバーの背後で実行されます。この方法では、すべてのリクエストが Web サーバーを経由するため、エンド ユーザーはアプリケーション サーバーと直接通信できませんが、バックエンド アプリケーションはアプリケーション サーバーと直接通信してパフォーマンスを向上させることができます。
現在ログオンしている Linux ユーザーがアプリケーションの所有者であると仮定して、ソース コード ディレクトリを作成し、"file-manager" という名前の Gliimly アプリケーションも作成します。
mkdir filemgr cd filemgr gg -k file-manager
次に、現在ログオンしているユーザーが所有する「db_file_manager」という名前の PostgreSQL データベースを作成します (つまり、パスワードなしの設定)。
echo "create user $(whoami); create database db_file_manager with owner=$(whoami); grant all on database db_file_manager to $(whoami); \q" | sudo -u postgres psql
Gliimly が使用する、データベースを記述するデータベース構成ファイルを作成します (ファイル「db」)。
echo "user=$(whoami) dbname=db_file_manager" > db
現在サーバー上に保存されているファイルを保持する SQL テーブルを作成します。
echo "create table if not exists files (fileName varchar(100), localPath varchar(300), extension varchar(10), description varchar(200), fileSize int, fileID bigserial primary key);" | psql -d db_file_manager
最後に、ソース Gliimly ファイルを作成します。まず、「start.gliim」ファイルを作成し、コピーして貼り付けます。
begin-handler /start public @<h2>File Manager</h2> @To manage the uploaded files, <a href="<<p-path "/list">>">click here.</a><br/> @<br/> @<form action="<<p-path "/upload">>" method="POST" enctype="multipart/form-data"> @ <label for="file_description">File description:</label><br> @ <textarea name="filedesc" rows="3" columns="50"></textarea><br/> @ <br/> @ <label for="filename">File:</label> @ <input type="file" name="file" value=""><br><br> @ <input type="submit" value="Submit"> @</form> end-handler
「list.gliim」ファイルを作成し、コピーして貼り付けます:
begin-handler /list public @<h2>List of files</h2> @To add a file, <a href="<<p-path "/start">>">click here</a><br/><br/> @<table border="1"> @<tr> @ <td>File</td><td>Description</td><td>Size</td><td>Show</td><td>Delete</td> @</tr> run-query @db= \ "select fileName, description, fileSize, fileID from files order by fileSize desc" \ output file_name, description noencode, file_size, file_ID @<tr> @ <td><<p-web file_name>></td><td><<p-web description>><td><<p-web file_size>></td> @ <td><a href="<<p-path "/download">>/file_id=<<p-url file_ID>>">Show</a></td> @ <td><a href="<<p-path "/delete">>/action=confirm/file_id=<<p-url file_ID>>">Delete</a></td> @</tr> end-query @</table> end-handler
「upload.gliim」ファイルを作成し、コピーして貼り付けます:
begin-handler /upload public get-param filedesc // file description from the upload form get-param file_filename // file name get-param file_location // the path to uploaded file get-param file_size // size in bytes get-param file_ext // the file extension @<h2>Uploading file</h2> run-query @db= \ "insert into files (fileName, localPath, extension, description, fileSize) \ values ('%s', '%s', '%s', '%s', '%s')" \ input file_filename, file_location, file_ext, filedesc, file_size end-query @File <<p-web file_filename>> of size <<p-web file_size>> \ is stored on server at <<p-web file_location>>. \ File description is <<p-web filedesc>>.<hr/> end-handler
「download.gliim」ファイルを作成し、コピーして貼り付けます:
begin-handler /download public get-param file_id run-query @db= \ "select localPath,extension from files where fileID='%s'" \ input file_id \ output local_path, ext \ row-count num_files if-true ext equal ".jpg" send-file local_path headers content-type "image/jpg" else-if ext equal ".pdf" send-file local_path headers content-type "application/pdf" else-if send-file local_path headers content-type "application/octet-stream" download end-if end-query if-true num_files not-equal 1 @Cannot find this file!<hr/> exit-handler end-if end-handler
「delete.gliim」ファイルを作成し、コピーして貼り付けます:
begin-handler /delete public @<h2>Delete a file</h2> get-param action get-param file_id run-query @db="select fileName, localPath, description from files where fileID='%s'" output file_name, local_path, desc input file_id if-true action equal "confirm" // get file information to confirm what will be deleted @Are you sure you want to delete file <<p-web file_name>> (<<p-web desc>>)? Click <a href="<<p-path "/delete">>?action=delete&file_id=<<p-url file_id>>">Delete</a> or click the browser's Back button to go back.<br/> else-if action equal "delete" // actual delete file, once confirmed begin-transaction @db run-query @db= "delete from files where fileID='%s'" input file_id error err no-loop if-true err not-equal "0" @Could not delete the file (error <<p-web err>>) rollback-transaction @db else-if delete-file local_path status st if-true st equal GG_OKAY commit-transaction @db @File deleted. Go back to <a href="<<p-path "/start">>">start page</a> else-if rollback-transaction @db @File could not be deleted, error <<p-num st>> end-if end-if else-if @Unrecognized action <<p-web action>> end-if end-query end-handler
アプリケーションを作成します。
gg -q --db=postgres:db
アプリケーション サーバーを実行します。
mgrg file-manager
Gliimly アプリケーション サーバーの前に Web サーバーがあるので、これをセットアップする必要があります。この例は Ubuntu 用なので、そこで Nginx 構成ファイルを編集します。
sudo vi /etc/nginx/sites-enabled/default
「server {}」セクションにこれを追加します (「client_max_body_size」により、標準的なサイズの画像をアップロードできるようになります)。
location /file-manager/ { include /etc/nginx/fastcgi_params; fastcgi_pass unix:///var/lib/gg/file-manager/sock/sock; } client_max_body_size 100M;
Nginxを再起動します。
sudo systemctl restart nginx
Web ブラウザにアクセスし、次のように入力します。
http://127.0.0.1/file-manager/start
最終結果は次のようになります。もちろん、最低限の HTML だけを使用しましたが、それはここでのポイントではありません。フロントエンド テクノロジはどれでも使用できますが、ポイントは、Gliimly を Web アプリケーション/サービスのバックエンド サーバーとして実証することです。
以下は、ファイルをアップロードするためのフォームと、ファイルのリストへのリンクがあるホーム画面です。
ファイルの一覧:
ファイルの削除を要求しています:
削除の確認: