diff -ur -x '*.fasl' -x '.*' -x '*.patch' -x 'test*' -x '#*' -x 'sbcl*' ../drakma-1.1.0/cookies.lisp ./cookies.lisp --- ../drakma-1.1.0/cookies.lisp 2009-12-01 17:06:56.000000000 -0500 +++ ./cookies.lisp 2010-04-07 11:26:32.000000000 -0400 @@ -258,6 +258,14 @@ (push (list (car name/value) (cdr name/value) parameters) result)))) (nreverse result))) +(defvar *remove-duplicate-cookies-p* T + "Determines how duplicate cookies are handled. Valid values are: + * nil - duplicates will not be removed + * (T :KEEP-LAST) - for duplicates, only the last cookie value will be kept, + based on the order of the response header + * :KEEP-FIRST - for duplicates, only the first cookie value will be kept, + based on the order of the response header") + (defun get-cookies (headers uri) "Returns a list of COOKIE objects corresponding to the `Set-Cookie' header as found in HEADERS \(an alist as returned by @@ -281,7 +289,13 @@ (parse-cookie-date expires)) :domain domain :securep (not (not (parameter-present-p "secure" parameters))) - :http-only-p (not (not (parameter-present-p "HttpOnly" parameters)))))) + :http-only-p (not (not (parameter-present-p "HttpOnly" parameters)))) + into new-cookies + finally (return (ccase *remove-duplicate-cookies-p* + ((nil) new-cookies) + ((:keep-last t) (delete-duplicates new-cookies :test #'cookie=)) + (:keep-first (delete-duplicates new-cookies :test #'cookie= + :from-end T)))))) (defun update-cookies (new-cookies cookie-jar) "Updates the cookies in COOKIE-JAR by replacing those which are diff -ur -x '*.fasl' -x '.*' -x '*.patch' -x 'test*' -x '#*' -x 'sbcl*' ../drakma-1.1.0/doc/index.html ./doc/index.html --- ../drakma-1.1.0/doc/index.html 2009-12-01 17:44:55.000000000 -0500 +++ ./doc/index.html 2010-04-07 11:29:26.000000000 -0400 @@ -86,6 +86,7 @@
  • delete-old-cookies
  • *allow-dotless-cookie-domains-p*
  • *ignore-unparseable-cookie-dates-p* +
  • *remove-duplicate-cookies-p*
  • Headers
      @@ -1323,6 +1324,59 @@ + + + +


      [Special variable]
      *remove-duplicate-cookies-p* +


      +Determines how duplicate cookies in the response are handled, defaults +to T. Cookies are considered duplicate using +COOKIE=. + +Valid values are: +
        +
      • NIL - duplicates will not be removed
      • +
      • T - for duplicates, only the last cookie value will + be kept, based on the order of the response header
      • +
      • :KEEP-LAST - for duplicates, only the last cookie + value will be kept, based on the order of the response header
      • +
      • :KEEP-FIRST - for duplicates, only the first cookie + value will be kept, based on the order of the response header
      • +
      + +Misbehaving servers may send duplicate cookies back in the same +Set-Cookie header: +
      +HTTP/1.1 200  OK
      +Server: My-hand-rolled-server
      +Date: Wed, 07 Apr 2010 15:12:30 GMT
      +Connection: Close
      +Content-Type: text/html
      +Content-Length: 82
      +Set-Cookie: a=1; Path=/; Secure, a=2; Path=/; Secure
      +
      +

      +In this case Drakma has to choose whether cookie "a" has the value +"1" or "2". By default, Drakma will choose the last value specified, +in this case "2". +

      +

      +By default, Drakma conforms to RFC2109 HTTP State +Management Mechanism, section 4.3.3 Cookie Management: +

      +If a user agent receives a Set-Cookie response header whose NAME is +the same as a pre-existing cookie, and whose Domain and Path +attribute values exactly (string) match those of a pre-existing +cookie, the new cookie supersedes the old. +
      +

      + +
      + + + + +

      Headers

      This section assembles a couple of convenience functions which can be diff -ur -x '*.fasl' -x '.*' -x '*.patch' -x 'test*' -x '#*' -x 'sbcl*' ../drakma-1.1.0/packages.lisp ./packages.lisp --- ../drakma-1.1.0/packages.lisp 2009-02-09 09:53:01.000000000 -0500 +++ ./packages.lisp 2010-04-07 11:32:04.000000000 -0400 @@ -36,6 +36,7 @@ (:shadow :syntax-error :parameter-error) (:export :*allow-dotless-cookie-domains-p* :*body-format-function* + :*remove-duplicate-cookies-p* :*drakma-default-external-format* :*header-stream* :*ignore-unparseable-cookie-dates-p*