1

Google App Engineに静的なWebサイトがあり、いくつかの.rarファイルをダウンロードできます。現在、静的ファイルハンドラー定義(app.yaml)によって処理されています。

handlers:
- url: /(.*\.(bz2|gz|rar|tar|tgz|zip))
  static_files: static/\1
  upload: static/(.*\.(bz2|gz|rar|tar|tgz|zip))

今、私がやりたいのは、/ download?MyFile.rarのようなダウンロードリンクを提供することです。これにより、ダウンロードをカウントして、誰がホットリンクしているかを確認できます。

WebサイトがこのURLを使用している限り、ホットリンクを防止したくありません(実際のパスは非表示/使用不可になります)。このようにして、外部からのダウンロードであってもカウントできます(Google AnalyticsまたはClickyは明らかに処理せず、ログの保持期間は約90日であり、その目的には便利ではありません)。

問題は、ユーザーのためにファイルのダウンロードを起動できるPythonハンドラーを作成する方法です。多くのphp/aspWebサイトで見られるように。

たくさん検索してこれらの2つのスレッドを読んだ後(Google App Engineにデータベースから何かをダウンロードするダウンロードリンクを持たせるにはどうすればよいですか?google app engineにファイルを含むファイルをダウンロードさせるにはどうすればよいですか? )

self.response.headers['Content-Type'] = 'application/octet-stream'
self.response.out.write(filecontent) # how do I get that content?
#or
self.response.headers["Content-Type"] = "application/zip"
self.response.headers['Content-Disposition'] = "attachment; filename=MyFile.rar" # does that work? how do I get the actual path?

ハンドラーは限られた時間しか実行できないため、大きなファイルでは機能しない可能性があることを読みましたか?

どんなガイダンスでも大歓迎です!

ありがとう。

Romz

編集: それが機能するようになり、すべての.rarファイルに対して単一のハンドラーを持つことができます。直接リンク(example.com/File.rar)のように見えますが、実際にはpythonで処理されるURLを使用できます(したがって、リファラーを確認したり、ダウンロードをカウントしたりできます)。

ファイルは実際には別のサブフォルダーにあり、パスの生成方法により、実際の直接ダウンロードから保護されたままです。除外する必要のある他の文字(「/」および「\」以外)があるかどうかはわかりませんが、この方法では、親フォルダーなどの他のファイルにアクセスできないようにする必要があります。

これが私のクォータとファイルサイズの制限にとって何を意味するのか、私にはよくわかりませんが。

app.yaml

handlers:
- url: /(.*\.rar)
  script: main.app

main.py

from google.appengine.ext import webapp
from google.appengine.api import memcache
from google.appengine.ext import db
import os, urlparse

class GeneralCounterShard(db.Model):
    name = db.StringProperty(required=True)
    count = db.IntegerProperty(required=True, default=0)

def CounterIncrement(name):
    def txn():
        counter = GeneralCounterShard.get_by_key_name(name)
        if counter is None:
            counter = GeneralCounterShard(key_name=name, name=name)
        counter.count += 1
        counter.put()
    db.run_in_transaction(txn)
    memcache.incr(name) # does nothing if the key does not exist

class MainPage(webapp.RequestHandler):
    def get(self):

    referer = self.request.headers.get("Referer")
    if (referer and not referer.startswith("http://www.example.com/")):
        self.redirect('http://www.example.com')
        return

    path = urlparse.urlparse(self.request.url).path.replace('/', '').replace('\\', '')
    fullpath = os.path.join(os.path.dirname(__file__), 'files/'+path)
    if os.path.exists(fullpath):
        CounterIncrement(path)
        self.response.headers['Content-Type'] = 'application/zip'
        self.response.headers["Content-Disposition"] = 'attachment; filename=' + path
        self.response.out.write(file(fullpath, 'rb').read())
    else:
        self.response.out.write('<br>The file does not exist<br>')


app = webapp.WSGIApplication([('/.*', MainPage)], debug=False)
4

2 に答える 2

0

を使用してみることができself.resquest.refererます。

これがあなたがそれをする方法です。「ここをクリック」してファイルダウンロードページへのリンクをダウンロードすると、FileDownloadHandler//nameまたはidwhaterverがパラメーターとして渡される場合があります。このハンドラーで、リファラーが「ダウンロードページ」であるかどうかを確認してください。リクエストが有効なダウンロードだった場合。そうである場合は、ファイルを提供し、そうでない場合は、リダイレクトするか、エラーを実行します。

ただのアイデア

于 2012-08-26T02:40:49.247 に答える
0

ファイルコンテンツをblobストレージに保存し、そこから提供することができますが、巨大なファイルと遅いクライアントの場合、制限時間(〜30秒)に達します

もう1つのオプションは、ダウンロードをカウントしてから、実際のダウンロードリンクへの一時的なリダイレクト(HTTP 302)を発行する単純なハンドラーを用意することです。大きなファイルを提供できますが、ハンドラーURLではなく実際のファイルをホットリンクすることは可能です。

于 2012-08-26T02:21:25.673 に答える