cookie.py

来自「mallet是自然语言处理、机器学习领域的一个开源项目。」· Python 代码 · 共 743 行 · 第 1/2 页

PY
743
字号
# The _getdate() routine is used to set the expiration time in# the cookie's HTTP header.      By default, _getdate() returns the# current time in the appropriate "expires" format for a# Set-Cookie header.     The one optional argument is an offset from# now, in seconds.      For example, an offset of -3600 means "one hour ago".# The offset may be a floating point number.#_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']_monthname = [None,              'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):    from time import gmtime, time    now = time()    year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)    return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \           (weekdayname[wd], day, monthname[month], year, hh, mm, ss)## A class to hold ONE key,value pair.# In a cookie, each such pair may have several attributes.#       so this class is used to keep the attributes associated#       with the appropriate key,value pair.# This class also includes a coded_value attribute, which#       is used to hold the network representation of the#       value.  This is most useful when Python objects are#       pickled for network transit.#class Morsel(UserDict):    # RFC 2109 lists these attributes as reserved:    #   path       comment         domain    #   max-age    secure      version    #    # For historical reasons, these attributes are also reserved:    #   expires    #    # This dictionary provides a mapping from the lowercase    # variant on the left to the appropriate traditional    # formatting on the right.    _reserved = { "expires" : "expires",                   "path"        : "Path",                   "comment" : "Comment",                   "domain"      : "Domain",                   "max-age" : "Max-Age",                   "secure"      : "secure",                   "version" : "Version",                   }    _reserved_keys = _reserved.keys()    def __init__(self):        # Set defaults        self.key = self.value = self.coded_value = None        UserDict.__init__(self)        # Set default attributes        for K in self._reserved_keys:            UserDict.__setitem__(self, K, "")    # end __init__    def __setitem__(self, K, V):        K = string.lower(K)        if not K in self._reserved_keys:            raise CookieError("Invalid Attribute %s" % K)        UserDict.__setitem__(self, K, V)    # end __setitem__    def isReservedKey(self, K):        return string.lower(K) in self._reserved_keys    # end isReservedKey    def set(self, key, val, coded_val,            LegalChars=_LegalChars,            idmap=string._idmap, translate=string.translate ):        # First we verify that the key isn't a reserved word        # Second we make sure it only contains legal characters        if string.lower(key) in self._reserved_keys:            raise CookieError("Attempt to set a reserved key: %s" % key)        if "" != translate(key, idmap, LegalChars):            raise CookieError("Illegal key value: %s" % key)        # It's a good key, so save it.        self.key                 = key        self.value               = val        self.coded_value         = coded_val    # end set    def output(self, attrs=None, header = "Set-Cookie:"):        return "%s %s" % ( header, self.OutputString(attrs) )    __str__ = output    def __repr__(self):        return '<%s: %s=%s>' % (self.__class__.__name__,                                self.key, repr(self.value) )    def js_output(self, attrs=None):        # Print javascript        return """        <SCRIPT LANGUAGE="JavaScript">        <!-- begin hiding        document.cookie = \"%s\"        // end hiding -->        </script>        """ % ( self.OutputString(attrs), )    # end js_output()    def OutputString(self, attrs=None):        # Build up our result        #        result = []        RA = result.append        # First, the key=value pair        RA("%s=%s;" % (self.key, self.coded_value))        # Now add any defined attributes        if attrs is None:            attrs = self._reserved_keys        items = self.items()        items.sort()        for K,V in items:            if V == "": continue            if K not in attrs: continue            if K == "expires" and type(V) == type(1):                RA("%s=%s;" % (self._reserved[K], _getdate(V)))            elif K == "max-age" and type(V) == type(1):                RA("%s=%d;" % (self._reserved[K], V))            elif K == "secure":                RA("%s;" % self._reserved[K])            else:                RA("%s=%s;" % (self._reserved[K], V))        # Return the result        return string.join(result, " ")    # end OutputString# end Morsel class## Pattern for finding cookie## This used to be strict parsing based on the RFC2109 and RFC2068# specifications.  I have since discovered that MSIE 3.0x doesn't# follow the character rules outlined in those specs.  As a# result, the parsing rules here are less strict.#_LegalCharsPatt  = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]"_CookiePattern = re.compile(    r"(?x)"                       # This is a Verbose pattern    r"(?P<key>"                   # Start of group 'key'    ""+ _LegalCharsPatt +"+?"     # Any word of at least one letter, nongreedy    r")"                          # End of group 'key'    r"\s*=\s*"                    # Equal Sign    r"(?P<val>"                   # Start of group 'val'    r'"(?:[^\\"]|\\.)*"'            # Any doublequoted string    r"|"                            # or    ""+ _LegalCharsPatt +"*"        # Any word or empty string    r")"                          # End of group 'val'    r"\s*;?"                      # Probably ending in a semi-colon    )# At long last, here is the cookie class.#   Using this class is almost just like using a dictionary.# See this module's docstring for example usage.#class BaseCookie(UserDict):    # A container class for a set of Morsels    #    def value_decode(self, val):        """real_value, coded_value = value_decode(STRING)        Called prior to setting a cookie's value from the network        representation.  The VALUE is the value read from HTTP        header.        Override this function to modify the behavior of cookies.        """        return val, val    # end value_encode    def value_encode(self, val):        """real_value, coded_value = value_encode(VALUE)        Called prior to setting a cookie's value from the dictionary        representation.  The VALUE is the value being assigned.        Override this function to modify the behavior of cookies.        """        strval = str(val)        return strval, strval    # end value_encode    def __init__(self, input=None):        UserDict.__init__(self)        if input: self.load(input)    # end __init__    def __set(self, key, real_value, coded_value):        """Private method for setting a cookie's value"""        M = self.get(key, Morsel())        M.set(key, real_value, coded_value)        UserDict.__setitem__(self, key, M)    # end __set    def __setitem__(self, key, value):        """Dictionary style assignment."""        rval, cval = self.value_encode(value)        self.__set(key, rval, cval)    # end __setitem__    def output(self, attrs=None, header="Set-Cookie:", sep="\n"):        """Return a string suitable for HTTP."""        result = []        items = self.items()        items.sort()        for K,V in items:            result.append( V.output(attrs, header) )        return string.join(result, sep)    # end output    __str__ = output    def __repr__(self):        L = []        items = self.items()        items.sort()        for K,V in items:            L.append( '%s=%s' % (K,repr(V.value) ) )        return '<%s: %s>' % (self.__class__.__name__, string.join(L))    def js_output(self, attrs=None):        """Return a string suitable for JavaScript."""        result = []        items = self.items()        items.sort()        for K,V in items:            result.append( V.js_output(attrs) )        return string.join(result, "")    # end js_output    def load(self, rawdata):        """Load cookies from a string (presumably HTTP_COOKIE) or        from a dictionary.  Loading cookies from a dictionary 'd'        is equivalent to calling:            map(Cookie.__setitem__, d.keys(), d.values())        """        if type(rawdata) == type(""):            self.__ParseString(rawdata)        else:            self.update(rawdata)        return    # end load()    def __ParseString(self, str, patt=_CookiePattern):        i = 0            # Our starting point        n = len(str)     # Length of string        M = None         # current morsel        while 0 <= i < n:            # Start looking for a cookie            match = patt.search(str, i)            if not match: break          # No more cookies            K,V = match.group("key"), match.group("val")            i = match.end(0)            # Parse the key, value in case it's metainfo            if K[0] == "$":                # We ignore attributes which pertain to the cookie                # mechanism as a whole.  See RFC 2109.                # (Does anyone care?)                if M:                    M[ K[1:] ] = V            elif string.lower(K) in Morsel._reserved_keys:                if M:                    M[ K ] = _unquote(V)            else:                rval, cval = self.value_decode(V)                self.__set(K, rval, cval)                M = self[K]    # end __ParseString# end BaseCookie classclass SimpleCookie(BaseCookie):    """SimpleCookie    SimpleCookie supports strings as cookie values.  When setting    the value using the dictionary assignment notation, SimpleCookie    calls the builtin str() to convert the value to a string.  Values    received from HTTP are kept as strings.    """    def value_decode(self, val):        return _unquote( val ), val    def value_encode(self, val):        strval = str(val)        return strval, _quote( strval )# end SimpleCookieclass SerialCookie(BaseCookie):    """SerialCookie    SerialCookie supports arbitrary objects as cookie values. All    values are serialized (using cPickle) before being sent to the    client.  All incoming values are assumed to be valid Pickle    representations.  IF AN INCOMING VALUE IS NOT IN A VALID PICKLE    FORMAT, THEN AN EXCEPTION WILL BE RAISED.    Note: Large cookie values add overhead because they must be    retransmitted on every HTTP transaction.    Note: HTTP has a 2k limit on the size of a cookie.  This class    does not check for this limit, so be careful!!!    """    def value_decode(self, val):        # This could raise an exception!        return loads( _unquote(val) ), val    def value_encode(self, val):        return val, _quote( dumps(val) )# end SerialCookieclass SmartCookie(BaseCookie):    """SmartCookie    SmartCookie supports arbitrary objects as cookie values.  If the    object is a string, then it is quoted.  If the object is not a    string, however, then SmartCookie will use cPickle to serialize    the object into a string representation.    Note: Large cookie values add overhead because they must be    retransmitted on every HTTP transaction.    Note: HTTP has a 2k limit on the size of a cookie.  This class    does not check for this limit, so be careful!!!    """    def value_decode(self, val):        strval = _unquote(val)        try:            return loads(strval), val        except:            return strval, val    def value_encode(self, val):        if type(val) == type(""):            return val, _quote(val)        else:            return val, _quote( dumps(val) )# end SmartCookie############################################################ Backwards Compatibility:  Don't break any existing code!# We provide Cookie() as an alias for SmartCookie()Cookie = SmartCookie############################################################def _test():    import doctest, Cookie    return doctest.testmod(Cookie)if __name__ == "__main__":    _test()#Local Variables:#tab-width: 4#end:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?