在 Google App Engine 中,如何检查 urlsafe 创建的 Key 的输入有效性? [英] In Google App Engine, how to check input validity of Key created by urlsafe?

查看:19
本文介绍了在 Google App Engine 中,如何检查 urlsafe 创建的 Key 的输入有效性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我从用户输入的 websafe url 创建一个密钥

Suppose I create a key from user input websafe url

key = ndb.Key(urlsafe=some_user_input)

如何检查 some_user_input 是否有效?

How can I check if the some_user_input is valid?

我当前的实验表明,如果 some_user_input 无效,上面的语句将抛出 ProtocolBufferDecodeError (Unable to merge from string.) 异常,但无法从API.有人可以确认这一点,并指出一些更好的方法来检查用户输入的有效性而不是捕获异常吗?

My current experiment shows that statement above will throw ProtocolBufferDecodeError (Unable to merge from string.) exception if the some_user_input is invalid, but could not find anything about this from the API. Could someone kindly confirm this, and point me some better way for user input validity checking instead of catching the exception?

非常感谢!

推荐答案

如果您尝试使用无效的 urlsafe 参数构造 Key

If you try to construct a Key with an invalid urlsafe parameter

key = ndb.Key(urlsafe='bogus123')

你会得到类似的错误

Traceback (most recent call last):
  File "/opt/google/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "/opt/google/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File "/opt/google/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
    obj = __import__(path[0])
  File "/home/tim/git/project/main.py", line 10, in <module>
    from src.tim import handlers as handlers_
  File "/home/tim/git/project/src/tim/handlers.py", line 42, in <module>
    class ResetHandler(BaseHandler):
  File "/home/tim/git/project/src/tim/handlers.py", line 47, in ResetHandler
    key = ndb.Key(urlsafe='bogus123')
  File "/opt/google/google_appengine/google/appengine/ext/ndb/key.py", line 212, in __new__
    self.__reference = _ConstructReference(cls, **kwargs)
  File "/opt/google/google_appengine/google/appengine/ext/ndb/utils.py", line 142, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/opt/google/google_appengine/google/appengine/ext/ndb/key.py", line 642, in _ConstructReference
    reference = _ReferenceFromSerialized(serialized)
  File "/opt/google/google_appengine/google/appengine/ext/ndb/key.py", line 773, in _ReferenceFromSerialized
    return entity_pb.Reference(serialized)
  File "/opt/google/google_appengine/google/appengine/datastore/entity_pb.py", line 1710, in __init__
    if contents is not None: self.MergeFromString(contents)
  File "/opt/google/google_appengine/google/net/proto/ProtocolBuffer.py", line 152, in MergeFromString
    self.MergePartialFromString(s)
  File "/opt/google/google_appengine/google/net/proto/ProtocolBuffer.py", line 168, in MergePartialFromString
    self.TryMerge(d)
  File "/opt/google/google_appengine/google/appengine/datastore/entity_pb.py", line 1839, in TryMerge
    d.skipData(tt)
  File "/opt/google/google_appengine/google/net/proto/ProtocolBuffer.py", line 677, in skipData
    raise ProtocolBufferDecodeError, "corrupted"
ProtocolBufferDecodeError: corrupted

这里有趣的是

File "/opt/google/google_appengine/google/appengine/ext/ndb/key.py", line 773, in _ReferenceFromSerialized
  return entity_pb.Reference(serialized)

这是在 key.py 模块:

def _ReferenceFromSerialized(serialized):
  """Construct a Reference from a serialized Reference."""
  if not isinstance(serialized, basestring):
    raise TypeError('serialized must be a string; received %r' % serialized)
  elif isinstance(serialized, unicode):
    serialized = serialized.encode('utf8')
  return entity_pb.Reference(serialized)

serialized 这里是解码的 urlsafe 字符串,您可以在源代码链接中阅读更多相关信息.

serialized here being the decoded urlsafe string, you can read more about it in the link to the source code.

另一个有趣的是最后一个:

another interesting one is the last one:

File "/opt/google/google_appengine/google/appengine/datastore/entity_pb.py",   line 1839, in TryMerge

entity_pb.py 模块看起来像这样

  def TryMerge(self, d):
    while d.avail() > 0:
      tt = d.getVarInt32()
      if tt == 106:
        self.set_app(d.getPrefixedString())
        continue
      if tt == 114:
        length = d.getVarInt32()
        tmp = ProtocolBuffer.Decoder(d.buffer(), d.pos(), d.pos() + length)
        d.skip(length)
        self.mutable_path().TryMerge(tmp)
        continue
      if tt == 162:
        self.set_name_space(d.getPrefixedString())
        continue


      if (tt == 0): raise ProtocolBuffer.ProtocolBufferDecodeError
      d.skipData(tt)

这是实际尝试将输入合并到密钥中"的地方.

which is where the actual attempt to 'merge the input to into a Key' is made.

您可以在源代码中看到,在从 urlsafe 参数构造 Key 的过程中,不会出错.首先,它检查输入是否是 string,如果不是,则引发 TypeError,如果是但不是有效",实际上是 ProtocolBufferDecodeError 被提升.

You can see in the source code that during the process of constructing a Key from an urlsafe parameter not a whole lot can go wrong. First it checks if the input is a string and if it's not, a TypeError is raised, if it is but it's not 'valid', indeed a ProtocolBufferDecodeError is raised.

我目前的实验表明,如果 some_user_input 无效,上面的语句将抛出 ProtocolBufferDecodeError (Unable to merge from string.) 异常,但无法从 API 中找到任何相关信息.有人可以确认这一点

My current experiment shows that statement above will throw ProtocolBufferDecodeError (Unable to merge from string.) exception if the some_user_input is invalid, but could not find anything about this from the API. Could someone kindly confirm this

某种确认 - 我们现在知道也可以引发 TypeError.

Sort of confirmed - we now know that also TypeError can be raised.

并指出一些更好的方法来检查用户输入的有效性而不是捕获异常?

and point me some better way for user input validity checking instead of catching the exception?

这是检查有效性的好方法!如果 appengine 已经完成,为什么要自己检查?一个代码片段可能看起来像这样(不是工作代码,只是一个例子)

This is an excellent way to check validity! Why do the checks yourself if the they are already done by appengine? A code snippet could look like this (not working code, just an example)

def get(self):
  # first, fetch the user_input from somewhere

  try:
    key = ndb.Key(urlsafe=user_input)
  except TypeError:
    return 'Sorry, only string is allowed as urlsafe input'
  except ProtocolBufferDecodeError:
    return 'Sorry, the urlsafe string seems to be invalid'

这篇关于在 Google App Engine 中,如何检查 urlsafe 创建的 Key 的输入有效性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆