21
21
from django .test import SimpleTestCase
22
22
from django .utils import six
23
23
from django .utils ._os import upath
24
- from django .utils .encoding import force_text , smart_str
24
+ from django .utils .encoding import force_str , force_text , smart_str
25
25
from django .utils .functional import lazy
26
26
27
27
lazystr = lazy (force_text , six .text_type )
@@ -657,6 +657,8 @@ def test_decode(self):
657
657
c2 = SimpleCookie ()
658
658
c2 .load (c .output ()[12 :])
659
659
self .assertEqual (c ['test' ].value , c2 ['test' ].value )
660
+ c3 = parse_cookie (c .output ()[12 :])
661
+ self .assertEqual (c ['test' ].value , c3 ['test' ])
660
662
661
663
def test_decode_2 (self ):
662
664
"""
@@ -667,6 +669,8 @@ def test_decode_2(self):
667
669
c2 = SimpleCookie ()
668
670
c2 .load (c .output ()[12 :])
669
671
self .assertEqual (c ['test' ].value , c2 ['test' ].value )
672
+ c3 = parse_cookie (c .output ()[12 :])
673
+ self .assertEqual (c ['test' ].value , c3 ['test' ])
670
674
671
675
def test_nonstandard_keys (self ):
672
676
"""
@@ -680,6 +684,52 @@ def test_repeated_nonstandard_keys(self):
680
684
"""
681
685
self .assertIn ('good_cookie' , parse_cookie ('a:=b; a:=c; good_cookie=yes' ).keys ())
682
686
687
+ def test_python_cookies (self ):
688
+ """
689
+ Test cases copied from Python's Lib/test/test_http_cookies.py
690
+ """
691
+ self .assertEqual (parse_cookie ('chips=ahoy; vienna=finger' ), {'chips' : 'ahoy' , 'vienna' : 'finger' })
692
+ # Here parse_cookie() differs from Python's cookie parsing in that it
693
+ # treats all semicolons as delimiters, even within quotes.
694
+ self .assertEqual (
695
+ parse_cookie ('keebler="E=mc2; L=\\ "Loves\\ "; fudge=\\ 012;"' ),
696
+ {'keebler' : '"E=mc2' , 'L' : '\\ "Loves\\ "' , 'fudge' : '\\ 012' , '' : '"' }
697
+ )
698
+ # Illegal cookies that have an '=' char in an unquoted value.
699
+ self .assertEqual (parse_cookie ('keebler=E=mc2' ), {'keebler' : 'E=mc2' })
700
+ # Cookies with ':' character in their name.
701
+ self .assertEqual (parse_cookie ('key:term=value:term' ), {'key:term' : 'value:term' })
702
+ # Cookies with '[' and ']'.
703
+ self .assertEqual (parse_cookie ('a=b; c=[; d=r; f=h' ), {'a' : 'b' , 'c' : '[' , 'd' : 'r' , 'f' : 'h' })
704
+
705
+ def test_cookie_edgecases (self ):
706
+ # Cookies that RFC6265 allows.
707
+ self .assertEqual (parse_cookie ('a=b; Domain=example.com' ), {'a' : 'b' , 'Domain' : 'example.com' })
708
+ # parse_cookie() has historically kept only the last cookie with the
709
+ # same name.
710
+ self .assertEqual (parse_cookie ('a=b; h=i; a=c' ), {'a' : 'c' , 'h' : 'i' })
711
+
712
+ def test_invalid_cookies (self ):
713
+ """
714
+ Cookie strings that go against RFC6265 but browsers will send if set
715
+ via document.cookie.
716
+ """
717
+ # Chunks without an equals sign appear as unnamed values per
718
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=169091
719
+ self .assertIn ('django_language' , parse_cookie ('abc=def; unnamed; django_language=en' ).keys ())
720
+ # Even a double quote may be an unamed value.
721
+ self .assertEqual (parse_cookie ('a=b; "; c=d' ), {'a' : 'b' , '' : '"' , 'c' : 'd' })
722
+ # Spaces in names and values, and an equals sign in values.
723
+ self .assertEqual (parse_cookie ('a b c=d e = f; gh=i' ), {'a b c' : 'd e = f' , 'gh' : 'i' })
724
+ # More characters the spec forbids.
725
+ self .assertEqual (parse_cookie ('a b,c<>@:/[]?{}=d " =e,f g' ), {'a b,c<>@:/[]?{}' : 'd " =e,f g' })
726
+ # Unicode characters. The spec only allows ASCII.
727
+ self .assertEqual (parse_cookie ('saint=André Bessette' ), {'saint' : force_str ('André Bessette' )})
728
+ # Browsers don't send extra whitespace or semicolons in Cookie headers,
729
+ # but parse_cookie() should parse whitespace the same way
730
+ # document.cookie parses whitespace.
731
+ self .assertEqual (parse_cookie (' = b ; ; = ; c = ; ' ), {'' : 'b' , 'c' : '' })
732
+
683
733
def test_httponly_after_load (self ):
684
734
"""
685
735
Test that we can use httponly attribute on cookies that we load
0 commit comments