4

Flask では、ファイルを というディレクトリに置くとstatic/、フォームの任意の URL がhttp://localhost/static/foo.jpgからそのファイルを提供しますstatic/foo.jpg

これは、nginx 構成を介して実現することもできます。

    location /static {
        alias    /var/www/mywebsite/static;
    }

しかし、動的な URL 書き換えを行いたいと考えています。

誰かが URL を要求した場合http://localhost/username/foo.jpg、nginx に任意の URL から静的ファイルをフェッチするように指示したいと思います/var/www/assets/11235/1bcd5.jpg。ユーザーにきれいな URL を表示し、場所をユーザーに透過的にしたい。

これを行う簡単な方法はありますか?理想的には、nginx がファイルを提供するように何かを行うことができます。ただし、Flask がそれを提供する必要がある場合は、それも問題ありません (私のプロジェクトにはまだユーザーがいないようです!)

ここで何が欠けていますか?

4

1 に答える 1

1

「きれいな」URLで直接参照されている名前でファイルを保存できる場合は、nginxで簡単に書き直すことができます。

username -> 11235ただし、およびのように、URL パス情報をディスク上の他の表現にマップしたいようですfoo.jpg -> 1bcd5.jpg。提供されるコンテンツを認証またはセッションで保護する必要がある場合は、Flask がその手段を提供するため、Flask アプリ内でマッピングと書き換えを保持する必要があります。

コンテンツをパブリックとして扱うことができ、マッピングを行うだけでよい場合は、nginx を構成して、クエリ文字列パラメーターを取得し、データストアでそれらを検索して、URL を書き換えることができます。

nginx メーリング リストに最初に投稿されたagentzhの例を次に示します。

seo uri が /baz だとすると、本当の uri は /foo/bar です。そして、ローカルのmysql「テスト」データベースに次のテーブルがあります。

create table my_url_map(id serial, url text, seo_url);
insert into my_url_map(url, seo_url)values('/foo/bar', '/baz');

そして、nginx 0.8.41 を次のようにビルドします。

./configure \
--add-module=/path/to/ngx_devel_kit \
--add-module=/path/to/set-misc-nginx-module \
--add-module=/path/to/ngx_http_auth_request_module-0.2 \
--add-module=/path/to/echo-nginx-module \
--add-module=/path/to/lua-nginx-module \
--add-module=/path/to/drizzle-nginx-module \
--add-module=/path/to/rds-json-nginx-module

また、lua 5.1.4 と lua-yajl ライブラリがシステムにインストールされています。

そして、これが私のnginx.confの中心部分です:

upstream backend {
    drizzle_server 127.0.0.1:3306 dbname=test
    password=some_pass user=monty protocol=mysql;
    drizzle_keepalive max=300 mode=single overflow=ignore;
}

lua_package_cpath '/path/to/your/lua/yajl/library/?.so';

server {
    ...

    location /conv-mysql {
        internal;
        set_quote_sql_str $seo_uri $query_string; # to prevent sql injection
        drizzle_query "select url from my_url_map where seo_url=$seo_uri";
        drizzle_pass backend;
        rds_json on;
    }

    location /conv-uid {
        internal;
        content_by_lua_file 'html/foo.lua';
    }

    location /jump {
        internal;
        rewrite ^ $query_string? redirect;
    }

    # your SEO uri
    location /baz {
        set $my_uri $uri;
        auth_request /conv-uid;

        echo_exec /jump $my_uri;
    }
}

重要な接着剤である foo.lua の内容:

local yajl = require('yajl')
local seo_uri = ngx.var.my_uri
local res = ngx.location.capture('/conv-mysql?' .. seo_uri)
if (res.status ~= ngx.HTTP_OK) then
ngx.throw_error(res.status)
end
res = yajl.to_value(res.body)
if (not res or not res[1] or not res[1].url) then
ngx.throw_error(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.my_uri = res[1].url;

次に、クライアント側から /baz にアクセスしましょう:

$ curl -i localhost:1984/baz
HTTP/1.1 302 Moved Temporarily
Server: nginx/0.8.41 (without pool)
Date: Tue, 24 Aug 2010 03:28:42 GMT
Content-Type: text/html
Content-Length: 176
Location: http://localhost:1984/foo/bar
Connection: keep-alive

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/0.8.41 (without pool)</center>
</body>
</html>
于 2012-10-04T17:15:10.300 に答える