【问题标题】:How can store a file on Google Storage from URL on Google App Engine?如何从 Google App Engine 上的 URL 将文件存储在 Google Storage 上?
【发布时间】:2011-05-05 14:08:23
【问题描述】:

我想在 Google App Engine (Python) 上创建一个服务,该服务将接收图像的 URL 并将其存储在 Google 存储中。我设法使用botogsutil 命令行从本地文件上传,但不是通过URL 检索文件。我尝试使用HTTP requests (PUT) 进行操作,但我收到了错误签名的错误响应。显然我做错了什么,但不幸的是我不知道在哪里。

所以我的问题是:如何使用 Python for Google App Angine 从 URL 检索文件并将其存储在 Google Storage 中?

这是我所做的(使用另一个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()

我得到了回应:

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>

【问题讨论】:

  • 你能发布一些 POU 和服务器回复的代码吗?
  • @Peter Knego 我更新了我的答案。

标签: python google-app-engine boto google-cloud-storage


【解决方案1】:

您是否阅读过how to sign requests 上的文档?除了自定义标头和资源路径之外,要签名的字符串还必须包含 Content-MD5Content-TypeDate 标头。

【讨论】:

  • 我做了,但我无法让它工作。你能给我一个我可以尝试的例子吗?
  • 您没有在您提供的示例代码中签名的字符串中包含这些标题。尝试按照文档添加它们,如果仍然无法正常工作,请向我们展示您当时使用的代码。
【解决方案2】:

Content-MD5 标头对于 PUT requests 是可选的。尝试将其保留以进行测试。

此外,必需的标头是 AuthorizationDateHost。您的请求似乎缺少Host 标头。

【讨论】:

  • 当我添加主机时,我仍然遇到同样的错误。当我删除 Content-MD5 时,我得到一个 403: Forbidden 我们计算的请求签名与您提供的签名不匹配。检查您的 Google 密钥和签名方法。
  • 尝试使用 Chrome Potster 或 Firefox Poster 插件手动创建 PUT 请求。检查各种标题,直到你做对了。然后将其转移到代码中。 chrome.google.com/extensions/detail/…addons.mozilla.org/en-US/firefox/addon/2691
  • 无法正常工作。我认为我的签名是错误的,所以我不能把它放在海报上:(我在上面的代码中关于如何计算它有什么意义吗?
  • 我在 AppEngine 上使用 Java 开发,因此无法评论 Python。这似乎是正确的。但是,如果您无法让 Poster 工作,那么也许您应该重新检查其他标头参数,例如 Host 和 Authentication。
猜你喜欢
  • 1970-01-01
  • 2015-07-07
  • 2017-05-04
  • 2013-01-26
  • 2021-11-05
  • 2020-06-08
  • 2018-07-22
  • 2020-04-04
  • 2014-11-22
相关资源
最近更新 更多