Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../opt/imh-pyth.../lib/python2....
File: Cookie.py
####
[0] Fix | Delete
# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
[1] Fix | Delete
#
[2] Fix | Delete
# All Rights Reserved
[3] Fix | Delete
#
[4] Fix | Delete
# Permission to use, copy, modify, and distribute this software
[5] Fix | Delete
# and its documentation for any purpose and without fee is hereby
[6] Fix | Delete
# granted, provided that the above copyright notice appear in all
[7] Fix | Delete
# copies and that both that copyright notice and this permission
[8] Fix | Delete
# notice appear in supporting documentation, and that the name of
[9] Fix | Delete
# Timothy O'Malley not be used in advertising or publicity
[10] Fix | Delete
# pertaining to distribution of the software without specific, written
[11] Fix | Delete
# prior permission.
[12] Fix | Delete
#
[13] Fix | Delete
# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
[14] Fix | Delete
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
[15] Fix | Delete
# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
[16] Fix | Delete
# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
[17] Fix | Delete
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
[18] Fix | Delete
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
[19] Fix | Delete
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
[20] Fix | Delete
# PERFORMANCE OF THIS SOFTWARE.
[21] Fix | Delete
#
[22] Fix | Delete
####
[23] Fix | Delete
#
[24] Fix | Delete
# Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp
[25] Fix | Delete
# by Timothy O'Malley <timo@alum.mit.edu>
[26] Fix | Delete
#
[27] Fix | Delete
# Cookie.py is a Python module for the handling of HTTP
[28] Fix | Delete
# cookies as a Python dictionary. See RFC 2109 for more
[29] Fix | Delete
# information on cookies.
[30] Fix | Delete
#
[31] Fix | Delete
# The original idea to treat Cookies as a dictionary came from
[32] Fix | Delete
# Dave Mitchell (davem@magnet.com) in 1995, when he released the
[33] Fix | Delete
# first version of nscookie.py.
[34] Fix | Delete
#
[35] Fix | Delete
####
[36] Fix | Delete
[37] Fix | Delete
r"""
[38] Fix | Delete
Here's a sample session to show how to use this module.
[39] Fix | Delete
At the moment, this is the only documentation.
[40] Fix | Delete
[41] Fix | Delete
The Basics
[42] Fix | Delete
----------
[43] Fix | Delete
[44] Fix | Delete
Importing is easy..
[45] Fix | Delete
[46] Fix | Delete
>>> import Cookie
[47] Fix | Delete
[48] Fix | Delete
Most of the time you start by creating a cookie. Cookies come in
[49] Fix | Delete
three flavors, each with slightly different encoding semantics, but
[50] Fix | Delete
more on that later.
[51] Fix | Delete
[52] Fix | Delete
>>> C = Cookie.SimpleCookie()
[53] Fix | Delete
>>> C = Cookie.SerialCookie()
[54] Fix | Delete
>>> C = Cookie.SmartCookie()
[55] Fix | Delete
[56] Fix | Delete
[Note: Long-time users of Cookie.py will remember using
[57] Fix | Delete
Cookie.Cookie() to create a Cookie object. Although deprecated, it
[58] Fix | Delete
is still supported by the code. See the Backward Compatibility notes
[59] Fix | Delete
for more information.]
[60] Fix | Delete
[61] Fix | Delete
Once you've created your Cookie, you can add values just as if it were
[62] Fix | Delete
a dictionary.
[63] Fix | Delete
[64] Fix | Delete
>>> C = Cookie.SmartCookie()
[65] Fix | Delete
>>> C["fig"] = "newton"
[66] Fix | Delete
>>> C["sugar"] = "wafer"
[67] Fix | Delete
>>> C.output()
[68] Fix | Delete
'Set-Cookie: fig=newton\r\nSet-Cookie: sugar=wafer'
[69] Fix | Delete
[70] Fix | Delete
Notice that the printable representation of a Cookie is the
[71] Fix | Delete
appropriate format for a Set-Cookie: header. This is the
[72] Fix | Delete
default behavior. You can change the header and printed
[73] Fix | Delete
attributes by using the .output() function
[74] Fix | Delete
[75] Fix | Delete
>>> C = Cookie.SmartCookie()
[76] Fix | Delete
>>> C["rocky"] = "road"
[77] Fix | Delete
>>> C["rocky"]["path"] = "/cookie"
[78] Fix | Delete
>>> print C.output(header="Cookie:")
[79] Fix | Delete
Cookie: rocky=road; Path=/cookie
[80] Fix | Delete
>>> print C.output(attrs=[], header="Cookie:")
[81] Fix | Delete
Cookie: rocky=road
[82] Fix | Delete
[83] Fix | Delete
The load() method of a Cookie extracts cookies from a string. In a
[84] Fix | Delete
CGI script, you would use this method to extract the cookies from the
[85] Fix | Delete
HTTP_COOKIE environment variable.
[86] Fix | Delete
[87] Fix | Delete
>>> C = Cookie.SmartCookie()
[88] Fix | Delete
>>> C.load("chips=ahoy; vienna=finger")
[89] Fix | Delete
>>> C.output()
[90] Fix | Delete
'Set-Cookie: chips=ahoy\r\nSet-Cookie: vienna=finger'
[91] Fix | Delete
[92] Fix | Delete
The load() method is darn-tootin smart about identifying cookies
[93] Fix | Delete
within a string. Escaped quotation marks, nested semicolons, and other
[94] Fix | Delete
such trickeries do not confuse it.
[95] Fix | Delete
[96] Fix | Delete
>>> C = Cookie.SmartCookie()
[97] Fix | Delete
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
[98] Fix | Delete
>>> print C
[99] Fix | Delete
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
[100] Fix | Delete
[101] Fix | Delete
Each element of the Cookie also supports all of the RFC 2109
[102] Fix | Delete
Cookie attributes. Here's an example which sets the Path
[103] Fix | Delete
attribute.
[104] Fix | Delete
[105] Fix | Delete
>>> C = Cookie.SmartCookie()
[106] Fix | Delete
>>> C["oreo"] = "doublestuff"
[107] Fix | Delete
>>> C["oreo"]["path"] = "/"
[108] Fix | Delete
>>> print C
[109] Fix | Delete
Set-Cookie: oreo=doublestuff; Path=/
[110] Fix | Delete
[111] Fix | Delete
Each dictionary element has a 'value' attribute, which gives you
[112] Fix | Delete
back the value associated with the key.
[113] Fix | Delete
[114] Fix | Delete
>>> C = Cookie.SmartCookie()
[115] Fix | Delete
>>> C["twix"] = "none for you"
[116] Fix | Delete
>>> C["twix"].value
[117] Fix | Delete
'none for you'
[118] Fix | Delete
[119] Fix | Delete
[120] Fix | Delete
A Bit More Advanced
[121] Fix | Delete
-------------------
[122] Fix | Delete
[123] Fix | Delete
As mentioned before, there are three different flavors of Cookie
[124] Fix | Delete
objects, each with different encoding/decoding semantics. This
[125] Fix | Delete
section briefly discusses the differences.
[126] Fix | Delete
[127] Fix | Delete
SimpleCookie
[128] Fix | Delete
[129] Fix | Delete
The SimpleCookie expects that all values should be standard strings.
[130] Fix | Delete
Just to be sure, SimpleCookie invokes the str() builtin to convert
[131] Fix | Delete
the value to a string, when the values are set dictionary-style.
[132] Fix | Delete
[133] Fix | Delete
>>> C = Cookie.SimpleCookie()
[134] Fix | Delete
>>> C["number"] = 7
[135] Fix | Delete
>>> C["string"] = "seven"
[136] Fix | Delete
>>> C["number"].value
[137] Fix | Delete
'7'
[138] Fix | Delete
>>> C["string"].value
[139] Fix | Delete
'seven'
[140] Fix | Delete
>>> C.output()
[141] Fix | Delete
'Set-Cookie: number=7\r\nSet-Cookie: string=seven'
[142] Fix | Delete
[143] Fix | Delete
[144] Fix | Delete
SerialCookie
[145] Fix | Delete
[146] Fix | Delete
The SerialCookie expects that all values should be serialized using
[147] Fix | Delete
cPickle (or pickle, if cPickle isn't available). As a result of
[148] Fix | Delete
serializing, SerialCookie can save almost any Python object to a
[149] Fix | Delete
value, and recover the exact same object when the cookie has been
[150] Fix | Delete
returned. (SerialCookie can yield some strange-looking cookie
[151] Fix | Delete
values, however.)
[152] Fix | Delete
[153] Fix | Delete
>>> C = Cookie.SerialCookie()
[154] Fix | Delete
>>> C["number"] = 7
[155] Fix | Delete
>>> C["string"] = "seven"
[156] Fix | Delete
>>> C["number"].value
[157] Fix | Delete
7
[158] Fix | Delete
>>> C["string"].value
[159] Fix | Delete
'seven'
[160] Fix | Delete
>>> C.output()
[161] Fix | Delete
'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string="S\'seven\'\\012p1\\012."'
[162] Fix | Delete
[163] Fix | Delete
Be warned, however, if SerialCookie cannot de-serialize a value (because
[164] Fix | Delete
it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
[165] Fix | Delete
[166] Fix | Delete
[167] Fix | Delete
SmartCookie
[168] Fix | Delete
[169] Fix | Delete
The SmartCookie combines aspects of each of the other two flavors.
[170] Fix | Delete
When setting a value in a dictionary-fashion, the SmartCookie will
[171] Fix | Delete
serialize (ala cPickle) the value *if and only if* it isn't a
[172] Fix | Delete
Python string. String objects are *not* serialized. Similarly,
[173] Fix | Delete
when the load() method parses out values, it attempts to de-serialize
[174] Fix | Delete
the value. If it fails, then it fallsback to treating the value
[175] Fix | Delete
as a string.
[176] Fix | Delete
[177] Fix | Delete
>>> C = Cookie.SmartCookie()
[178] Fix | Delete
>>> C["number"] = 7
[179] Fix | Delete
>>> C["string"] = "seven"
[180] Fix | Delete
>>> C["number"].value
[181] Fix | Delete
7
[182] Fix | Delete
>>> C["string"].value
[183] Fix | Delete
'seven'
[184] Fix | Delete
>>> C.output()
[185] Fix | Delete
'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string=seven'
[186] Fix | Delete
[187] Fix | Delete
[188] Fix | Delete
Backwards Compatibility
[189] Fix | Delete
-----------------------
[190] Fix | Delete
[191] Fix | Delete
In order to keep compatibility with earlier versions of Cookie.py,
[192] Fix | Delete
it is still possible to use Cookie.Cookie() to create a Cookie. In
[193] Fix | Delete
fact, this simply returns a SmartCookie.
[194] Fix | Delete
[195] Fix | Delete
>>> C = Cookie.Cookie()
[196] Fix | Delete
>>> print C.__class__.__name__
[197] Fix | Delete
SmartCookie
[198] Fix | Delete
[199] Fix | Delete
[200] Fix | Delete
Finis.
[201] Fix | Delete
""" #"
[202] Fix | Delete
# ^
[203] Fix | Delete
# |----helps out font-lock
[204] Fix | Delete
[205] Fix | Delete
#
[206] Fix | Delete
# Import our required modules
[207] Fix | Delete
#
[208] Fix | Delete
import string
[209] Fix | Delete
[210] Fix | Delete
try:
[211] Fix | Delete
from cPickle import dumps, loads
[212] Fix | Delete
except ImportError:
[213] Fix | Delete
from pickle import dumps, loads
[214] Fix | Delete
[215] Fix | Delete
import re, warnings
[216] Fix | Delete
[217] Fix | Delete
__all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
[218] Fix | Delete
"SmartCookie","Cookie"]
[219] Fix | Delete
[220] Fix | Delete
_nulljoin = ''.join
[221] Fix | Delete
_semispacejoin = '; '.join
[222] Fix | Delete
_spacejoin = ' '.join
[223] Fix | Delete
[224] Fix | Delete
#
[225] Fix | Delete
# Define an exception visible to External modules
[226] Fix | Delete
#
[227] Fix | Delete
class CookieError(Exception):
[228] Fix | Delete
pass
[229] Fix | Delete
[230] Fix | Delete
[231] Fix | Delete
# These quoting routines conform to the RFC2109 specification, which in
[232] Fix | Delete
# turn references the character definitions from RFC2068. They provide
[233] Fix | Delete
# a two-way quoting algorithm. Any non-text character is translated
[234] Fix | Delete
# into a 4 character sequence: a forward-slash followed by the
[235] Fix | Delete
# three-digit octal equivalent of the character. Any '\' or '"' is
[236] Fix | Delete
# quoted with a preceding '\' slash.
[237] Fix | Delete
#
[238] Fix | Delete
# These are taken from RFC2068 and RFC2109.
[239] Fix | Delete
# _LegalChars is the list of chars which don't require "'s
[240] Fix | Delete
# _Translator hash-table for fast quoting
[241] Fix | Delete
#
[242] Fix | Delete
_LegalChars = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~"
[243] Fix | Delete
_Translator = {
[244] Fix | Delete
'\000' : '\\000', '\001' : '\\001', '\002' : '\\002',
[245] Fix | Delete
'\003' : '\\003', '\004' : '\\004', '\005' : '\\005',
[246] Fix | Delete
'\006' : '\\006', '\007' : '\\007', '\010' : '\\010',
[247] Fix | Delete
'\011' : '\\011', '\012' : '\\012', '\013' : '\\013',
[248] Fix | Delete
'\014' : '\\014', '\015' : '\\015', '\016' : '\\016',
[249] Fix | Delete
'\017' : '\\017', '\020' : '\\020', '\021' : '\\021',
[250] Fix | Delete
'\022' : '\\022', '\023' : '\\023', '\024' : '\\024',
[251] Fix | Delete
'\025' : '\\025', '\026' : '\\026', '\027' : '\\027',
[252] Fix | Delete
'\030' : '\\030', '\031' : '\\031', '\032' : '\\032',
[253] Fix | Delete
'\033' : '\\033', '\034' : '\\034', '\035' : '\\035',
[254] Fix | Delete
'\036' : '\\036', '\037' : '\\037',
[255] Fix | Delete
[256] Fix | Delete
# Because of the way browsers really handle cookies (as opposed
[257] Fix | Delete
# to what the RFC says) we also encode , and ;
[258] Fix | Delete
[259] Fix | Delete
',' : '\\054', ';' : '\\073',
[260] Fix | Delete
[261] Fix | Delete
'"' : '\\"', '\\' : '\\\\',
[262] Fix | Delete
[263] Fix | Delete
'\177' : '\\177', '\200' : '\\200', '\201' : '\\201',
[264] Fix | Delete
'\202' : '\\202', '\203' : '\\203', '\204' : '\\204',
[265] Fix | Delete
'\205' : '\\205', '\206' : '\\206', '\207' : '\\207',
[266] Fix | Delete
'\210' : '\\210', '\211' : '\\211', '\212' : '\\212',
[267] Fix | Delete
'\213' : '\\213', '\214' : '\\214', '\215' : '\\215',
[268] Fix | Delete
'\216' : '\\216', '\217' : '\\217', '\220' : '\\220',
[269] Fix | Delete
'\221' : '\\221', '\222' : '\\222', '\223' : '\\223',
[270] Fix | Delete
'\224' : '\\224', '\225' : '\\225', '\226' : '\\226',
[271] Fix | Delete
'\227' : '\\227', '\230' : '\\230', '\231' : '\\231',
[272] Fix | Delete
'\232' : '\\232', '\233' : '\\233', '\234' : '\\234',
[273] Fix | Delete
'\235' : '\\235', '\236' : '\\236', '\237' : '\\237',
[274] Fix | Delete
'\240' : '\\240', '\241' : '\\241', '\242' : '\\242',
[275] Fix | Delete
'\243' : '\\243', '\244' : '\\244', '\245' : '\\245',
[276] Fix | Delete
'\246' : '\\246', '\247' : '\\247', '\250' : '\\250',
[277] Fix | Delete
'\251' : '\\251', '\252' : '\\252', '\253' : '\\253',
[278] Fix | Delete
'\254' : '\\254', '\255' : '\\255', '\256' : '\\256',
[279] Fix | Delete
'\257' : '\\257', '\260' : '\\260', '\261' : '\\261',
[280] Fix | Delete
'\262' : '\\262', '\263' : '\\263', '\264' : '\\264',
[281] Fix | Delete
'\265' : '\\265', '\266' : '\\266', '\267' : '\\267',
[282] Fix | Delete
'\270' : '\\270', '\271' : '\\271', '\272' : '\\272',
[283] Fix | Delete
'\273' : '\\273', '\274' : '\\274', '\275' : '\\275',
[284] Fix | Delete
'\276' : '\\276', '\277' : '\\277', '\300' : '\\300',
[285] Fix | Delete
'\301' : '\\301', '\302' : '\\302', '\303' : '\\303',
[286] Fix | Delete
'\304' : '\\304', '\305' : '\\305', '\306' : '\\306',
[287] Fix | Delete
'\307' : '\\307', '\310' : '\\310', '\311' : '\\311',
[288] Fix | Delete
'\312' : '\\312', '\313' : '\\313', '\314' : '\\314',
[289] Fix | Delete
'\315' : '\\315', '\316' : '\\316', '\317' : '\\317',
[290] Fix | Delete
'\320' : '\\320', '\321' : '\\321', '\322' : '\\322',
[291] Fix | Delete
'\323' : '\\323', '\324' : '\\324', '\325' : '\\325',
[292] Fix | Delete
'\326' : '\\326', '\327' : '\\327', '\330' : '\\330',
[293] Fix | Delete
'\331' : '\\331', '\332' : '\\332', '\333' : '\\333',
[294] Fix | Delete
'\334' : '\\334', '\335' : '\\335', '\336' : '\\336',
[295] Fix | Delete
'\337' : '\\337', '\340' : '\\340', '\341' : '\\341',
[296] Fix | Delete
'\342' : '\\342', '\343' : '\\343', '\344' : '\\344',
[297] Fix | Delete
'\345' : '\\345', '\346' : '\\346', '\347' : '\\347',
[298] Fix | Delete
'\350' : '\\350', '\351' : '\\351', '\352' : '\\352',
[299] Fix | Delete
'\353' : '\\353', '\354' : '\\354', '\355' : '\\355',
[300] Fix | Delete
'\356' : '\\356', '\357' : '\\357', '\360' : '\\360',
[301] Fix | Delete
'\361' : '\\361', '\362' : '\\362', '\363' : '\\363',
[302] Fix | Delete
'\364' : '\\364', '\365' : '\\365', '\366' : '\\366',
[303] Fix | Delete
'\367' : '\\367', '\370' : '\\370', '\371' : '\\371',
[304] Fix | Delete
'\372' : '\\372', '\373' : '\\373', '\374' : '\\374',
[305] Fix | Delete
'\375' : '\\375', '\376' : '\\376', '\377' : '\\377'
[306] Fix | Delete
}
[307] Fix | Delete
[308] Fix | Delete
_idmap = ''.join(chr(x) for x in xrange(256))
[309] Fix | Delete
[310] Fix | Delete
def _quote(str, LegalChars=_LegalChars,
[311] Fix | Delete
idmap=_idmap, translate=string.translate):
[312] Fix | Delete
#
[313] Fix | Delete
# If the string does not need to be double-quoted,
[314] Fix | Delete
# then just return the string. Otherwise, surround
[315] Fix | Delete
# the string in doublequotes and precede quote (with a \)
[316] Fix | Delete
# special characters.
[317] Fix | Delete
#
[318] Fix | Delete
if "" == translate(str, idmap, LegalChars):
[319] Fix | Delete
return str
[320] Fix | Delete
else:
[321] Fix | Delete
return '"' + _nulljoin( map(_Translator.get, str, str) ) + '"'
[322] Fix | Delete
# end _quote
[323] Fix | Delete
[324] Fix | Delete
[325] Fix | Delete
_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
[326] Fix | Delete
_QuotePatt = re.compile(r"[\\].")
[327] Fix | Delete
[328] Fix | Delete
def _unquote(str):
[329] Fix | Delete
# If there aren't any doublequotes,
[330] Fix | Delete
# then there can't be any special characters. See RFC 2109.
[331] Fix | Delete
if len(str) < 2:
[332] Fix | Delete
return str
[333] Fix | Delete
if str[0] != '"' or str[-1] != '"':
[334] Fix | Delete
return str
[335] Fix | Delete
[336] Fix | Delete
# We have to assume that we must decode this string.
[337] Fix | Delete
# Down to work.
[338] Fix | Delete
[339] Fix | Delete
# Remove the "s
[340] Fix | Delete
str = str[1:-1]
[341] Fix | Delete
[342] Fix | Delete
# Check for special sequences. Examples:
[343] Fix | Delete
# \012 --> \n
[344] Fix | Delete
# \" --> "
[345] Fix | Delete
#
[346] Fix | Delete
i = 0
[347] Fix | Delete
n = len(str)
[348] Fix | Delete
res = []
[349] Fix | Delete
while 0 <= i < n:
[350] Fix | Delete
Omatch = _OctalPatt.search(str, i)
[351] Fix | Delete
Qmatch = _QuotePatt.search(str, i)
[352] Fix | Delete
if not Omatch and not Qmatch: # Neither matched
[353] Fix | Delete
res.append(str[i:])
[354] Fix | Delete
break
[355] Fix | Delete
# else:
[356] Fix | Delete
j = k = -1
[357] Fix | Delete
if Omatch: j = Omatch.start(0)
[358] Fix | Delete
if Qmatch: k = Qmatch.start(0)
[359] Fix | Delete
if Qmatch and ( not Omatch or k < j ): # QuotePatt matched
[360] Fix | Delete
res.append(str[i:k])
[361] Fix | Delete
res.append(str[k+1])
[362] Fix | Delete
i = k+2
[363] Fix | Delete
else: # OctalPatt matched
[364] Fix | Delete
res.append(str[i:j])
[365] Fix | Delete
res.append( chr( int(str[j+1:j+4], 8) ) )
[366] Fix | Delete
i = j+4
[367] Fix | Delete
return _nulljoin(res)
[368] Fix | Delete
# end _unquote
[369] Fix | Delete
[370] Fix | Delete
# The _getdate() routine is used to set the expiration time in
[371] Fix | Delete
# the cookie's HTTP header. By default, _getdate() returns the
[372] Fix | Delete
# current time in the appropriate "expires" format for a
[373] Fix | Delete
# Set-Cookie header. The one optional argument is an offset from
[374] Fix | Delete
# now, in seconds. For example, an offset of -3600 means "one hour ago".
[375] Fix | Delete
# The offset may be a floating point number.
[376] Fix | Delete
#
[377] Fix | Delete
[378] Fix | Delete
_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
[379] Fix | Delete
[380] Fix | Delete
_monthname = [None,
[381] Fix | Delete
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
[382] Fix | Delete
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
[383] Fix | Delete
[384] Fix | Delete
def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
[385] Fix | Delete
from time import gmtime, time
[386] Fix | Delete
now = time()
[387] Fix | Delete
year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
[388] Fix | Delete
return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % \
[389] Fix | Delete
(weekdayname[wd], day, monthname[month], year, hh, mm, ss)
[390] Fix | Delete
[391] Fix | Delete
[392] Fix | Delete
#
[393] Fix | Delete
# A class to hold ONE key,value pair.
[394] Fix | Delete
# In a cookie, each such pair may have several attributes.
[395] Fix | Delete
# so this class is used to keep the attributes associated
[396] Fix | Delete
# with the appropriate key,value pair.
[397] Fix | Delete
# This class also includes a coded_value attribute, which
[398] Fix | Delete
# is used to hold the network representation of the
[399] Fix | Delete
# value. This is most useful when Python objects are
[400] Fix | Delete
# pickled for network transit.
[401] Fix | Delete
#
[402] Fix | Delete
[403] Fix | Delete
class Morsel(dict):
[404] Fix | Delete
# RFC 2109 lists these attributes as reserved:
[405] Fix | Delete
# path comment domain
[406] Fix | Delete
# max-age secure version
[407] Fix | Delete
#
[408] Fix | Delete
# For historical reasons, these attributes are also reserved:
[409] Fix | Delete
# expires
[410] Fix | Delete
#
[411] Fix | Delete
# This is an extension from Microsoft:
[412] Fix | Delete
# httponly
[413] Fix | Delete
#
[414] Fix | Delete
# This dictionary provides a mapping from the lowercase
[415] Fix | Delete
# variant on the left to the appropriate traditional
[416] Fix | Delete
# formatting on the right.
[417] Fix | Delete
_reserved = { "expires" : "expires",
[418] Fix | Delete
"path" : "Path",
[419] Fix | Delete
"comment" : "Comment",
[420] Fix | Delete
"domain" : "Domain",
[421] Fix | Delete
"max-age" : "Max-Age",
[422] Fix | Delete
"secure" : "secure",
[423] Fix | Delete
"httponly" : "httponly",
[424] Fix | Delete
"version" : "Version",
[425] Fix | Delete
}
[426] Fix | Delete
[427] Fix | Delete
_flags = {'secure', 'httponly'}
[428] Fix | Delete
[429] Fix | Delete
def __init__(self):
[430] Fix | Delete
# Set defaults
[431] Fix | Delete
self.key = self.value = self.coded_value = None
[432] Fix | Delete
[433] Fix | Delete
# Set default attributes
[434] Fix | Delete
for K in self._reserved:
[435] Fix | Delete
dict.__setitem__(self, K, "")
[436] Fix | Delete
# end __init__
[437] Fix | Delete
[438] Fix | Delete
def __setitem__(self, K, V):
[439] Fix | Delete
K = K.lower()
[440] Fix | Delete
if not K in self._reserved:
[441] Fix | Delete
raise CookieError("Invalid Attribute %s" % K)
[442] Fix | Delete
dict.__setitem__(self, K, V)
[443] Fix | Delete
# end __setitem__
[444] Fix | Delete
[445] Fix | Delete
def isReservedKey(self, K):
[446] Fix | Delete
return K.lower() in self._reserved
[447] Fix | Delete
# end isReservedKey
[448] Fix | Delete
[449] Fix | Delete
def set(self, key, val, coded_val,
[450] Fix | Delete
LegalChars=_LegalChars,
[451] Fix | Delete
idmap=_idmap, translate=string.translate):
[452] Fix | Delete
# First we verify that the key isn't a reserved word
[453] Fix | Delete
# Second we make sure it only contains legal characters
[454] Fix | Delete
if key.lower() in self._reserved:
[455] Fix | Delete
raise CookieError("Attempt to set a reserved key: %s" % key)
[456] Fix | Delete
if "" != translate(key, idmap, LegalChars):
[457] Fix | Delete
raise CookieError("Illegal key value: %s" % key)
[458] Fix | Delete
[459] Fix | Delete
# It's a good key, so save it.
[460] Fix | Delete
self.key = key
[461] Fix | Delete
self.value = val
[462] Fix | Delete
self.coded_value = coded_val
[463] Fix | Delete
# end set
[464] Fix | Delete
[465] Fix | Delete
def output(self, attrs=None, header = "Set-Cookie:"):
[466] Fix | Delete
return "%s %s" % ( header, self.OutputString(attrs) )
[467] Fix | Delete
[468] Fix | Delete
__str__ = output
[469] Fix | Delete
[470] Fix | Delete
def __repr__(self):
[471] Fix | Delete
return '<%s: %s=%s>' % (self.__class__.__name__,
[472] Fix | Delete
self.key, repr(self.value) )
[473] Fix | Delete
[474] Fix | Delete
def js_output(self, attrs=None):
[475] Fix | Delete
# Print javascript
[476] Fix | Delete
return """
[477] Fix | Delete
<script type="text/javascript">
[478] Fix | Delete
<!-- begin hiding
[479] Fix | Delete
document.cookie = \"%s\";
[480] Fix | Delete
// end hiding -->
[481] Fix | Delete
</script>
[482] Fix | Delete
""" % ( self.OutputString(attrs).replace('"',r'\"'), )
[483] Fix | Delete
# end js_output()
[484] Fix | Delete
[485] Fix | Delete
def OutputString(self, attrs=None):
[486] Fix | Delete
# Build up our result
[487] Fix | Delete
#
[488] Fix | Delete
result = []
[489] Fix | Delete
RA = result.append
[490] Fix | Delete
[491] Fix | Delete
# First, the key=value pair
[492] Fix | Delete
RA("%s=%s" % (self.key, self.coded_value))
[493] Fix | Delete
[494] Fix | Delete
# Now add any defined attributes
[495] Fix | Delete
if attrs is None:
[496] Fix | Delete
attrs = self._reserved
[497] Fix | Delete
items = self.items()
[498] Fix | Delete
items.sort()
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function