2010-11-05 5 views
5

Ich möchte einen Dienst in Google App Engine (Python) erstellen, der die URL eines Bildes erhält und in Google Storage speichert. Ich habe es geschafft, von einer lokalen Datei mit boto oder gsutil Befehlszeile hochzuladen, aber nicht durch Abrufen der Datei über URL. Ich habe versucht, es mit der HTTP requests (PUT) und ich bekomme Fehler Antworten für falsche Signaturen. Offensichtlich mache ich etwas falsch, aber leider habe ich keine Ahnung wo.Wie kann eine Datei in Google Storage von URL in Google App Engine gespeichert werden?

Also meine Frage ist: Wie kann ich eine Datei von einer URL abrufen und in Google Storage mit Python für Google App Angine speichern?

Hier ist, was ich getan habe (unter Verwendung eines anderen answer):

class ImportPhoto(webapp.RequestHandler): 
    def get(self): 
     self.response.headers['Content-Type'] = 'text/plain' 
     srow = self.response.out.write 
     url = self.request.get('url') 
     srow('URL: %s\n' % (url)) 
     image_response = urlfetch.fetch(url) 
     m = md5.md5() 
     m.update(image_response.content) 
     hash = m.hexdigest() 
     time = "%s" % datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT") 
     str_to_sig = "PUT\n" + hash + "\n\n" + 
         time + "\nx-goog-acl:public-read\n/lipis/8418.png" 
     sig = base64.b64encode(hmac.new(
            config_credentials.GS_SECRET_ACCESS_KEY, 
            str_to_sig, hashlib.sha1).digest()) 
     total = len(image_response.content) 
     srow('Size: %d bytes\n' % (total)) 

     header = {"Date": time, 
        "x-goog-acl": "public-read", 
        "Content-MD5": hash, 
        'Content-Length': total, 
        'Authorization': "GOOG1 %s:%s" % 
            (config_credentials.GS_ACCESS_KEY_ID, sig)} 

     conn = httplib.HTTPConnection("lipis.commondatastorage.googleapis.com") 
     conn.set_debuglevel(2) 

     conn.putrequest('PUT', "/8418.png") 
     for h in header: 
      conn.putheader(h, header[h]) 
     conn.endheaders() 
     conn.send(image_response.content + '\r\n') 
     res = conn.getresponse() 

     srow('\n\n%d: %s\n' % (res.status, res.reason)) 
     data = res.read() 
     srow(data) 
     conn.close() 

Und ich als Antwort bekommen:

URL: https://stackoverflow.com/users/flair/8418.png 
Size: 9605 bytes 

400: Bad Request 
<?xml version='1.0' encoding='UTF-8'?><Error><Code>BadDigest</Code><Message>The Content-MD5 you specified did not match what we received.</Message><Details>lipis/hello.jpg</Details></Error> 
+0

Können Sie einen Code posten, der die POU und die Serverantwort beantwortet? –

+0

@Peter Knego Ich aktualisierte meine Antwort. – Lipis

Antwort

1

Haben Sie die Dokumentation auf how to sign requests lesen? Die zu signierende Zeichenfolge muss die Header Content-MD5, Content-Type und Date zusätzlich zu den benutzerdefinierten Headern und dem Ressourcenpfad enthalten.

+0

Ich tat, aber ich kann es nicht zur Arbeit bringen. Kannst du mir ein Beispiel geben, das ich versuchen könnte? – Lipis

+0

Sie fügen diese Header nicht in die Zeichenfolge ein, die Sie in dem von Ihnen angegebenen Beispielcode signieren. Versuchen Sie, sie wie dokumentiert hinzuzufügen, und wenn es immer noch nicht funktioniert, zeigen Sie uns den Code, den Sie dann verwenden. –

+0

Danke .. nachdem ich das Handbuch nochmal durchgegangen bin, funktionierte es: D – Lipis

1

Content-MD5 Header ist optional für PUT requests. Versuchen Sie, dies für einen Test auszulassen. Die erforderlichen Header sind Authorization, Date und Host. Es scheint, dass Ihre Anfrage Host Header fehlt.

+0

Als ich den Host hinzufügte, bekam ich immer noch den gleichen Fehler. Wenn ich Content-MD5 entfernte, erhielt ich eine * 403: Verboten * _Die von uns berechnete Anforderungssignatur stimmt nicht mit der von Ihnen angegebenen Signatur überein. Überprüfen Sie den geheimen Schlüssel und die Signaturmethode von Google. _ – Lipis

+0

Versuchen Sie, Chrome Potster- oder Firefox Poster-Plugins zu verwenden, um PUT-Anfragen manuell zu erstellen. Überprüfen Sie mit verschiedenen Kopfzeilen, bis Sie es richtig machen. Dann übertrage das auf den Code. https://chrome.google.com/extensions/detail/cdjfedloinmbppoppahmonnjigpmlajcd?hl=de https://addons.mozilla.org/en-US/firefox/addon/2691/ –

+0

kann es nicht zum Funktionieren bringen. Ich denke, dass meine Unterschrift falsch ist, also kann ich es nicht richtig machen, um es anzubringen Poster :(Mache ich in dem obigen Code einen Sinn, wie man es berechnet? – Lipis

Verwandte Themen