    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/test/org/apache/commons/httpclient/cookie/TestCookieRFC2109Spec.java,v 1.3 2004/06/05 16:49:20 olegk Exp $
    3    * $Revision: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    5    * ====================================================================
    6    *
    7    *  Licensed to the Apache Software Foundation (ASF) under one or more
    8    *  contributor license agreements.  See the NOTICE file distributed with
    9    *  this work for additional information regarding copyright ownership.
    10   *  The ASF licenses this file to You under the Apache License, Version 2.0
    11   *  (the "License"); you may not use this file except in compliance with
    12   *  the License.  You may obtain a copy of the License at
    13   *
    14   *      http://www.apache.org/licenses/LICENSE-2.0
    15   *
    16   *  Unless required by applicable law or agreed to in writing, software
    17   *  distributed under the License is distributed on an "AS IS" BASIS,
    18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    19   *  See the License for the specific language governing permissions and
    20   *  limitations under the License.
    21   * ====================================================================
    22   *
    23   * This software consists of voluntary contributions made by many
    24   * individuals on behalf of the Apache Software Foundation.  For more
    25   * information on the Apache Software Foundation, please see
    26   * <http://www.apache.org/>.
    27   *
    28   */
    29
    30  package org.apache.commons.httpclient.cookie;
    31
    32  import junit.framework.Test;
    33  import junit.framework.TestSuite;
    34
    35  import org.apache.commons.httpclient.Cookie;
    36  import org.apache.commons.httpclient.Header;
    37  import org.apache.commons.httpclient.NameValuePair;
    38
    39  /**
    40   * Test cases for RFC2109 cookie spec
    41   *
    42   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    43   *
    44   * @version $Revision: 480424 $
    45   */
    46  public class TestCookieRFC2109Spec extends TestCookieBase {
    47
    48
    49      // ------------------------------------------------------------ Constructor
    50
    51      public TestCookieRFC2109Spec(String name) {
    52          super(name);
    53      }
    54
    55      // ------------------------------------------------------- TestCase Methods
    56
    57      public static Test suite() {
    58          return new TestSuite(TestCookieRFC2109Spec.class);
    59      }
    60
    61      public void testParseAttributeInvalidAttrib() throws Exception {
    62          CookieSpec cookiespec = new RFC2109Spec();
    63          try {
    64              cookiespec.parseAttribute(null, null);
    65              fail("IllegalArgumentException must have been thrown");
    66          } catch (IllegalArgumentException expected) {
    67          }
    68      }
    69
    70      public void testParseAttributeInvalidCookie() throws Exception {
    71          CookieSpec cookiespec = new RFC2109Spec();
    72          try {
    73              cookiespec.parseAttribute(new NameValuePair("name", "value"), null);
    74              fail("IllegalArgumentException must have been thrown");
    75          } catch (IllegalArgumentException expected) {
    76          }
    77      }
    78
    79      public void testParseAttributeNullPath() throws Exception {
    80          CookieSpec cookiespec = new RFC2109Spec();
    81          try {
    82              Cookie cookie = new Cookie();
    83              cookiespec.parseAttribute(new NameValuePair("path", null), cookie);
    84              fail("MalformedCookieException must have been thrown");
    85          } catch (MalformedCookieException expected) {
    86          }
    87      }
    88
    89      public void testParseAttributeBlankPath() throws Exception {
    90          CookieSpec cookiespec = new RFC2109Spec();
    91          try {
    92              Cookie cookie = new Cookie();
    93              cookiespec.parseAttribute(new NameValuePair("path", "   "), cookie);
    94              fail("MalformedCookieException must have been thrown");
    95          } catch (MalformedCookieException expected) {
    96          }
    97      }
    98
    99      public void testParseAttributeNullVersion() throws Exception {
    100         CookieSpec cookiespec = new RFC2109Spec();
    101         try {
    102             Cookie cookie = new Cookie();
    103             cookiespec.parseAttribute(new NameValuePair("version", null), cookie);
    104             fail("MalformedCookieException must have been thrown");
    105         } catch (MalformedCookieException expected) {
    106         }
    107     }
    108
    109     public void testParseAttributeInvalidVersion() throws Exception {
    110         CookieSpec cookiespec = new RFC2109Spec();
    111         try {
    112             Cookie cookie = new Cookie();
    113             cookiespec.parseAttribute(new NameValuePair("version", "nonsense"), cookie);
    114             fail("MalformedCookieException must have been thrown");
    115         } catch (MalformedCookieException expected) {
    116         }
    117     }
    118
    119     public void testParseVersion() throws Exception {
    120         Header header = new Header("Set-Cookie","cookie-name=cookie-value; version=1");
    121
    122         CookieSpec cookiespec = new RFC2109Spec();
    123         Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, header);
    124         assertEquals("Found 1 cookie.",1,parsed.length);
    125         assertEquals("Name","cookie-name",parsed[0].getName());
    126         assertEquals("Value","cookie-value",parsed[0].getValue());
    127         assertEquals("Version",1,parsed[0].getVersion());
    128     }
    129
    130     /**
    131      * Test domain equals host
    132      */
    133     public void testParseDomainEqualsHost() throws Exception {
    134         Header header = new Header("Set-Cookie",
    135             "cookie-name=cookie-value; domain=www.b.com; version=1");
    136
    137         CookieSpec cookiespec = new RFC2109Spec();
    138         Cookie[] parsed = cookieParse(cookiespec, "www.b.com", 80, "/", false, header);
    139         assertNotNull(parsed);
    140         assertEquals(1, parsed.length);
    141         assertEquals("www.b.com", parsed[0].getDomain());
    142     }
    143
    144     /**
    145      * Domain does not start with a dot
    146      */
    147     public void testParseWithIllegalDomain1() throws Exception {
    148         Header header = new Header("Set-Cookie",
    149             "cookie-name=cookie-value; domain=a.b.com; version=1");
    150
    151         CookieSpec cookiespec = new RFC2109Spec();
    152         try {
    153             Cookie[] parsed = cookieParse(cookiespec, "www.a.b.com", 80, "/", false, header);
    154             fail("MalformedCookieException should have been thrown");
    155         } catch (MalformedCookieException e) {
    156             // expected
    157         }
    158     }
    159
    160     /**
    161      * Domain must have alt least one embedded dot
    162      */
    163     public void testParseWithIllegalDomain2() throws Exception {
    164         Header header = new Header("Set-Cookie",
    165             "cookie-name=cookie-value; domain=.com; version=1");
    166
    167         CookieSpec cookiespec = new RFC2109Spec();
    168         try {
    169             Cookie[] parsed = cookieParse(cookiespec, "b.com", 80, "/", false, header);
    170             fail("MalformedCookieException should have been thrown");
    171         } catch (MalformedCookieException e) {
    172             // expected
    173         }
    174     }
    175     /**
    176      * Domain must have alt least one embedded dot
    177      */
    178     public void testParseWithIllegalDomain3() throws Exception {
    179         Header header = new Header("Set-Cookie",
    180             "cookie-name=cookie-value; domain=.com.; version=1");
    181
    182         CookieSpec cookiespec = new RFC2109Spec();
    183         try {
    184             Cookie[] parsed = cookieParse(cookiespec, "b.com", 80, "/", false, header);
    185             fail("HttpException exception should have been thrown");
    186         } catch (MalformedCookieException e) {
    187             // expected
    188         }
    189     }
    190
    191     /**
    192      * Host minus domain may not contain any dots
    193      */
    194     public void testParseWithIllegalDomain4() throws Exception {
    195         Header header = new Header("Set-Cookie",
    196             "cookie-name=cookie-value; domain=.c.com; version=1");
    197
    198         CookieSpec cookiespec = new RFC2109Spec();
    199         try {
    200             Cookie[] parsed = cookieParse(cookiespec, "a.b.c.com", 80, "/", false, header);
    201             fail("MalformedCookieException should have been thrown");
    202         } catch (MalformedCookieException e) {
    203             // expected
    204         }
    205     }
    206
    207     /**
    208      * Tests if that invalid second domain level cookie gets
    209      * rejected in the strict mode, but gets accepted in the
    210      * browser compatibility mode.
    211      */
    212     public void testSecondDomainLevelCookie() throws Exception {
    213         Cookie cookie = new Cookie(".sourceforge.net", "name", null, "/", null, false);
    214         cookie.setDomainAttributeSpecified(true);
    215         cookie.setPathAttributeSpecified(true);
    216
    217         CookieSpec cookiespec = new RFC2109Spec();
    218         try {
    219             cookiespec.validate("sourceforge.net", 80, "/", false, cookie);
    220             fail("MalformedCookieException should have been thrown");
    221         } catch (MalformedCookieException e) {
    222             // Expected
    223         }
    224     }
    225
    226     public void testSecondDomainLevelCookieMatch() throws Exception {
    227         Cookie cookie = new Cookie(".sourceforge.net", "name", null, "/", null, false);
    228         cookie.setDomainAttributeSpecified(true);
    229         cookie.setPathAttributeSpecified(true);
    230
    231         CookieSpec cookiespec = new RFC2109Spec();
    232         assertFalse(cookiespec.match("sourceforge.net", 80, "/", false, cookie));
    233     }
    234
    235     public void testParseWithWrongPath() throws Exception {
    236         Header header = new Header("Set-Cookie",
    237             "cookie-name=cookie-value; domain=127.0.0.1; path=/not/just/root");
    238
    239         CookieSpec cookiespec = new RFC2109Spec();
    240         try {
    241             Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, header);
    242             fail("HttpException exception should have been thrown");
    243         } catch (MalformedCookieException e) {
    244             // expected
    245         }
    246     }
    247
    248     /**
    249      * Tests if cookie constructor rejects cookie name containing blanks.
    250      */
    251     public void testCookieNameWithBlanks() throws Exception {
    252         Header setcookie = new Header("Set-Cookie", "invalid name=");
    253         CookieSpec cookiespec = new RFC2109Spec();
    254         try {
    255             Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
    256             fail("MalformedCookieException exception should have been thrown");
    257         } catch (MalformedCookieException e) {
    258             // expected
    259         }
    260     }
    261
    262
    263     /**
    264      * Tests if cookie constructor rejects cookie name starting with $.
    265      */
    266     public void testCookieNameStartingWithDollarSign() throws Exception {
    267         Header setcookie = new Header("Set-Cookie", "$invalid_name=");
    268         CookieSpec cookiespec = new RFC2109Spec();
    269         try {
    270             Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
    271             fail("MalformedCookieException exception should have been thrown");
    272         } catch (MalformedCookieException e) {
    273             // expected
    274         }
    275     }
    276
    277     /**
    278      * Tests if default cookie validator rejects cookies originating from a host without domain
    279      * where domain attribute does not match the host of origin
    280      */
    281     public void testInvalidDomainWithSimpleHostName() throws Exception {
    282         CookieSpec cookiespec = new RFC2109Spec();
    283         Header header = new Header("Set-Cookie",
    284             "name=\"value\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\"");
    285         Cookie[]cookies = cookiespec.parse("host", 80, "/", false, header );
    286         try {
    287             cookiespec.validate("host", 80, "/", false, cookies[0]);
    288             fail("MalformedCookieException must have thrown");
    289         }
    290         catch(MalformedCookieException expected) {
    291         }
    292         header = new Header("Set-Cookie",
    293             "name=\"value\"; version=\"1\"; path=\"/\"; domain=\"host1\"");
    294         cookies = cookiespec.parse("host2", 80, "/", false, header );
    295         try {
    296             cookiespec.validate("host2", 80, "/", false, cookies[0]);
    297             fail("MalformedCookieException must have thrown");
    298         }
    299         catch(MalformedCookieException expected) {
    300         }
    301     }
    302
    303     /**
    304      * Tests if cookie values with embedded comma are handled correctly.
    305      */
    306     public void testCookieWithComma() throws Exception {
    307         Header header = new Header("Set-Cookie", "a=b,c");
    308
    309         CookieSpec cookiespec = new RFC2109Spec();
    310         Cookie[] cookies = cookiespec.parse("localhost", 80, "/", false, header);
    311         assertEquals("number of cookies", 2, cookies.length);
    312         assertEquals("a", cookies[0].getName());
    313         assertEquals("b", cookies[0].getValue());
    314         assertEquals("c", cookies[1].getName());
    315         assertEquals(null, cookies[1].getValue());
    316     }
    317
    318     public void testFormatInvalidCookies() throws Exception {
    319         CookieSpec cookiespec = new RFC2109Spec();
    320         try {
    321             String s = cookiespec.formatCookie(null);
    322             fail("IllegalArgumentException nust have been thrown");
    323         } catch (IllegalArgumentException expected) {
    324         }
    325     }
    326
    327     /**
    328      * Tests RFC 2109 compiant cookie formatting.
    329      */
    330     public void testRFC2109CookieFormatting() throws Exception {
    331         CookieSpec cookiespec = new RFC2109Spec();
    332         Header header = new Header("Set-Cookie",
    333             "name=\"value\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\"");
    334         Cookie[] cookies  = cookiespec.parse("myhost.mydomain.com", 80, "/", false, header );
    335         cookiespec.validate("myhost.mydomain.com", 80, "/", false, cookies[0]);
    336         String s1 = cookiespec.formatCookie(cookies[0]);
    337         assertEquals(s1, "$Version=\"1\"; name=\"value\"; $Path=\"/\"; $Domain=\".mydomain.com\"");
    338
    339         header = new Header( "Set-Cookie",
    340             "name=value; path=/; domain=.mydomain.com");
    341         cookies = cookiespec.parse("myhost.mydomain.com", 80, "/", false, header );
    342         cookiespec.validate("myhost.mydomain.com", 80, "/", false, cookies[0]);
    343         String s2 = cookiespec.formatCookie(cookies[0]);
    344         assertEquals(s2, "$Version=0; name=value; $Path=/; $Domain=.mydomain.com");
    345     }
    346
    347     public void testRFC2109CookiesFormatting() throws Exception {
    348         CookieSpec cookiespec = new RFC2109Spec();
    349         Header header = new Header("Set-Cookie",
    350             "name1=value1; path=/; domain=.mydomain.com, " +
    351             "name2=\"value2\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\"");
    352         Cookie[] cookies = cookieParse(cookiespec, "myhost.mydomain.com", 80, "/", false, header);
    353         assertNotNull(cookies);
    354         assertEquals(2, cookies.length);
    355         String s1 = cookiespec.formatCookies(cookies);
    356         assertEquals(s1,
    357             "$Version=0; name1=value1; $Path=/; $Domain=.mydomain.com; " +
    358             "name2=value2; $Path=/; $Domain=.mydomain.com");
    359
    360         header = new Header("Set-Cookie",
    361             "name1=value1; version=1; path=/; domain=.mydomain.com, " +
    362             "name2=\"value2\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\"");
    363         cookies = cookieParse(cookiespec, "myhost.mydomain.com", 80, "/", false, header);
    364         assertNotNull(cookies);
    365         assertEquals(2, cookies.length);
    366         String s2 = cookiespec.formatCookies(cookies);
    367         assertEquals(s2,
    368             "$Version=\"1\"; name1=\"value1\"; $Path=\"/\"; $Domain=\".mydomain.com\"; " +
    369             "name2=\"value2\"; $Path=\"/\"; $Domain=\".mydomain.com\"");
    370     }
    371
    372     /**
    373      * Tests if null cookie values are handled correctly.
    374      */
    375     public void testNullCookieValueFormatting() {
    376         Cookie cookie = new Cookie(".whatever.com", "name", null, "/", null, false);
    377         cookie.setDomainAttributeSpecified(true);
    378         cookie.setPathAttributeSpecified(true);
    379
    380         CookieSpec cookiespec = new RFC2109Spec();
    381         String s = cookiespec.formatCookie(cookie);
    382         assertEquals("$Version=0; name=; $Path=/; $Domain=.whatever.com", s);
    383
    384         cookie.setVersion(1);
    385         s = cookiespec.formatCookie(cookie);
    386         assertEquals("$Version=\"1\"; name=\"\"; $Path=\"/\"; $Domain=\".whatever.com\"", s);
    387     }
    388
    389     public void testCookieNullDomainNullPathFormatting() {
    390         Cookie cookie = new Cookie(null, "name", null, "/", null, false);
    391         cookie.setDomainAttributeSpecified(true);
    392         cookie.setPathAttributeSpecified(true);
    393
    394         CookieSpec cookiespec = new RFC2109Spec();
    395         String s = cookiespec.formatCookie(cookie);
    396         assertEquals("$Version=0; name=; $Path=/", s);
    397
    398         cookie.setDomainAttributeSpecified(false);
    399         cookie.setPathAttributeSpecified(false);
    400         s = cookiespec.formatCookie(cookie);
    401         assertEquals("$Version=0; name=", s);
    402     }
    403
    404 }
    405