【问题标题】:Uploading blob to BlobStore from python returns 500 on http从 python 上传 blob 到 BlobStore 在 http 上返回 500
【发布时间】:2015-09-14 13:25:52
【问题描述】:

我正在尝试从 python 将 blob 上传到 BlobStore,它在 https://...appspot.comhttps://...com/ 上有效,但是当从 http 执行完全相同的代码时它不起作用并且 BlobStore 返回 500 错误。

我尝试过让连接始终安全,即使在不安全的情况下也是如此。

这是我的代码:

@staticmethod
def save_to_blobstore(_request, id, file_contents, file_type, file_name = 'fixmeh.png'):
    upload_url  = blobstore.create_upload_url('/upload-item/blob-key/{}'.format(id))

    if upload_url.startswith('http://') and 'localhost.com' not in _request.get_host():
        upload_url = 'https' + upload_url[4:]

    # ----- CREATING FORMDATA -----
    boundary = 'WebKitFormBoundaryE19zNvXGzXaLvS5C'
    body = '\r\n'.join([
        '--' + boundary,
        'Content-Disposition: form-data; name="file"; filename="{}"'.format(file_name),
        'Content-Type: {}'.format(file_type),
        '',
        file_contents,
        '',
        '--' + boundary + '--',
        '',
    ])

    headers = {
        'Content-Type'  : 'multipart/form-data; boundary={}'.format(boundary),
        'User-Agent'    : 'Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0',
    }

    logging.critical('blobstore save')

    # TODO Why the hell do we receive deadline limit exceeded?
    request = urllib2.Request(upload_url)

    # ----- FORCING SECURE CONNECTION EXCEPT ON LOCALHOST -----
    if 'localhost.com' in _request.get_host():
        conn = httplib.HTTPConnection(request.get_host(), timeout = 50)
    else:
        conn = httplib.HTTPSConnection(request.get_host(), timeout = 50)

    conn._follow_redirects = True

    logging.info(['upload_url', upload_url ])
    logging.info(['get_host', request.get_host() ])
    logging.info(['get_selector', request.get_selector() ])
    conn.request('POST', request.get_selector(), body, headers)

    try:
        response = conn.getresponse()
        response_body = response.read()

        logging.info(response_body)

        # TODO we need to have an exception if the response is not 200
    except DeadlineExceededError:
        logging.exception('Saving blob - DeadlineExceededError')
    except:
        logging.exception('Saving blob')

当通过 HTTP 执行时,这是 BlobStore 的返回,尽管它没有多大帮助。有没有办法在 https://console.developers.google.com/project/.../logs 或其他任何地方记录 blobstore 错误。

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>500 Server Error</title></head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Server Error</h1>
<h2>The server encountered an error and could not complete your request.
<p>Please retry your last submission.</p>
<p>If the problem persists, please contact the person responsible for the application you're using, or, if you are that person,
<a href="http://code.google.com/appengine/community.html">report</a> your
problem and mention this error message and the query that caused it.</h2>
</body></html>

你能帮我解释一下为什么不能在 http 上工作但在 https 上工作吗? (注意它适用于 SDK 上的 http - 那里没有 ssl,这只发生在 apppot 上)

【问题讨论】:

  • 您的日志中有什么错误?您有两个带有字符串参数的 logging.exception 调用。它们出现了吗?

标签: python google-app-engine blobstore google-app-engine-python


【解决方案1】:

我将此代码用于使用 webapp2 路由的完整上传 url:

upload_url = create_upload_url(webapp2.uri_for('blob_update', _full=True))

并且处理程序使用名为 route: 'blob_update' 的 webapp2

class BlobUpdate(blobstore_handlers.BlobstoreUploadHandler):
    """ has named route : blob_update : 
    webapp2.Route(r'/blob_update', handler='....BlobUpdate', name='blob_update') """

    def post(self):
        """ blob upload handler returns the new blobkey"""

    blob_info = self.get_uploads('file')[0]
    ....

更多:App Engine update blob

【讨论】:

    【解决方案2】:

    非常感谢您的指示和快速响应。我从你的代码中汲取了一些想法并调整了我的。

    我真的不想使用 google.appengine.api.urlfetch,遗憾的是我现在没有时间进行实验。

    这是最终代码,以防万一有人偶然发现东西(另请参阅 voscausa 的网址“App Engine update blob”:

        back_url = '{}{}/upload-item/blob-key/{}'.format(_request.protocol, _request.get_host(), id)
        # logging.info(back_url)
    
        upload_url  = blobstore.create_upload_url(back_url)
    
        BNDR = b'WebKitFormBoundaryE19zNvXGzXaLvS5C'  # '--PythonBlobstorevarBoundaryVXGzXaLvS5C'
        CRLF = b'\r\n'
        DD   = b'--'
    
        body = b''.join([
            DD + BNDR + CRLF,
            b'Content-Disposition: form-data; name="file"; filename="{}"'.format(file_name) + CRLF,
            b'Content-Type: {}'.format(file_type) + CRLF,
            CRLF,
            file_contents + CRLF,
            DD + BNDR + DD + CRLF,
        ])
    
        headers = {
            b'Content-Type' : b'multipart/form-data; boundary={}'.format(BNDR),
            # b'User-Agent' : b'Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0',
        }
    
        try:
            response = urlfetch.fetch(
                url                 = upload_url,
                payload             = body,
                method              = urlfetch.POST,
                deadline            = 40,
                follow_redirects    = False,
                headers             = headers
            )
    
            if response.status_code == 200:
                logging.info(response.content)
            else:
                logging.info(response)
                logging.error(response.content)
                logging.exception('URL : {} fetch ERROR : {}'.format(upload_url, response.status_code))
        except (urlfetch.DownloadError, DeadlineExceededError), e:
            logging.exception('fetch {} download or deadline error, exception : {}'.format(upload_url, str(e)))
    

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 2014-10-10
      • 1970-01-01
      • 2014-07-23
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      相关资源
      最近更新 更多