2012-08-25 4 views
1

Google App Engine에 몇 개의 .rar 파일을 다운로드 할 수있는 정적 웹 사이트가 있습니다.Google App Engine과의 다운로드 링크

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

지금 내가하고 싶은 것을 그래서 할 수 카운트 다운로드 /download?MyFile.rar 같은 다운로드 링크를 제공 할 수 있습니다 : 은 지금 당장은 정적 파일 처리기 정의 (애플리케이션 제목)에 의해 처리 있어요누구의 핫 링크를 참조하십시오.

웹 사이트가이 URL (실제 경로는 숨김/사용할 수 없음)을 사용하는 한 핫 링크를 방지하고 싶지 않습니다. 이렇게하면 외부에서 오는 경우에도 다운로드 수를 계산할 수 있습니다 (Google 애널리틱스 또는 Clicky는 분명히 처리하지 못하고 로그 보존 기간은 약 90 일이며 그 목적에 편리하지 않습니다).

질문은 : 사용자를위한 파일 다운로드를 시작할 수있는 파이썬 처리기를 만드는 방법은 무엇입니까? 우리가 많은 php/asp 웹 사이트에서 보는 것처럼.

많이 검색하고 그 2 개 스레드 (How do I let Google App Engine have a download link that downloads something from a database?, google app engine download a file containing files)을 읽은 후, 그것이 내가 뭔가 할 수 보인다

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)처럼 보이는 URL을 가질 수는 있지만 파이썬에서는 실제로 처리됩니다 (그래서 referer를 확인하고 다운로드를 계산할 수 있습니다).

파일은 실제로 다른 하위 폴더에 있으며 은 경로가 생성되는 방식 때문에 실제 직접 다운로드으로부터 보호됩니다. 필자는 다른 문자 ('/'및 '\')가 필터링되어야하는지 모르지만이 방법으로는 아무도 상위 폴더의 다른 파일에 액세스 할 수 없어야합니다.

내 할당량 및 파일 크기 제한에 대한 모든 의미가 실제로 무엇인지는 알 수 없지만.

애플리케이션 제목을

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

당신은 BLOB 저장소에서 파일 내용을 저장하고 거기에서 역할을하지만, 큰 파일을 느린 클라이언트의 경우 수

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) 
+1

파일 크기가 작은 한 잘 수행됩니다. 크기가 더 큰 경우 블롭 스토어에 저장하고 직접 블롭 스토어 지원을 사용하여 제공해야하므로 앱의 메모리로 읽을 필요가 없습니다. –

답변

0

self.resquest.referer을 사용해보세요.

어떻게 할 수 있습니까? 파일 다운로드 페이지로 연결되는 링크를 다운로드하려면 여기를 클릭하십시오. FileDownloadHandler이있을 수 있습니다. name/id /이 매개 변수가 매개 변수로 전달되는 곳에서이 핸들러에서 referer가 '다운로드 페이지'였는지 확인하십시오. 요청이 유효한 다운로드인지 여부를 알 수 있습니다. 그렇다면 파일을 제공하고, 그렇지 않으면 리디렉션하거나 오류를 만드십시오.

그냥 생각해보기

0

main.py 시간 제한 (~ 30 초)을 맞춥니다.

또 다른 옵션은 간단한 핸들 r은 다운로드를 계산 한 다음 실제 다운로드 링크로 임시 리디렉션 (HTTP 302)을 실행합니다. 대용량 파일을 제공 할 수는 있지만 핸들러 URL이 아닌 실제 파일을 핫 링크 할 수 있습니다.

+2

요청 시간 제한은 30 초가 아니라 60 초이며 업로드 또는 다운로드 시간에는 적용되지 않으므로 크기에 관계없이 BLOBstore를 사용하면 문제가 없습니다. –

관련 문제