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