Revision: 4488
Author: edi
URL: http://bknr.net/trac/changeset/4488
Get rid of *within-request-p*
U trunk/thirdparty/hunchentoot/doc/index.xml
U trunk/thirdparty/hunchentoot/packages.lisp
U trunk/thirdparty/hunchentoot/request.lisp
U trunk/thirdparty/hunchentoot/specials.lisp
Modified: trunk/thirdparty/hunchentoot/doc/index.xml
===================================================================
--- trunk/thirdparty/hunchentoot/doc/index.xml 2009-12-14 20:26:57 UTC (rev 4487)
+++ trunk/thirdparty/hunchentoot/doc/index.xml 2009-12-22 22:14:35 UTC (rev 4488)
@@ -953,7 +953,7 @@
a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">function
designator</a> for a unary function. In this case, the
handler will be returned
- by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref> ,
+ by <clix:ref>DISPATCH-EASY-HANDLERS</clix:ref>,
if <clix:arg>uri</clix:arg> is a string and
the <a href="#script-name">script name</a> of the current
request is <clix:arg>uri</clix:arg>, or
@@ -2897,7 +2897,6 @@
</clix:description>
</clix:function>
- <clix:special-variable name="*tmp-directory*">
<clix:function name='within-request-p'>
<clix:lambda-list>
</clix:lambda-list>
@@ -2907,6 +2906,7 @@
</clix:description>
</clix:function>
+ <clix:special-variable name="*tmp-directory*">
<clix:description>
This should be a pathname denoting a directory where temporary
files can be stored. It is used for <a href="#upload">file
Modified: trunk/thirdparty/hunchentoot/packages.lisp
===================================================================
--- trunk/thirdparty/hunchentoot/packages.lisp 2009-12-14 20:26:57 UTC (rev 4487)
+++ trunk/thirdparty/hunchentoot/packages.lisp 2009-12-22 22:14:35 UTC (rev 4488)
@@ -64,7 +64,6 @@
"*METHODS-FOR-POST-PARAMETERS*"
"*REPLY*"
"*REQUEST*"
- "WITHIN-REQUEST-P"
"*REWRITE-FOR-SESSION-URLS*"
"*SESSION*"
"*SESSION-GC-FREQUENCY*"
Modified: trunk/thirdparty/hunchentoot/request.lisp
===================================================================
--- trunk/thirdparty/hunchentoot/request.lisp 2009-12-14 20:26:57 UTC (rev 4487)
+++ trunk/thirdparty/hunchentoot/request.lisp 2009-12-22 22:14:35 UTC (rev 4488)
@@ -224,8 +224,7 @@
(let (*tmp-files* *headers-sent*)
(unwind-protect
(with-mapped-conditions ()
- (let* ((*request* request)
- (*within-request-p* t))
+ (let* ((*request* request))
(multiple-value-bind (body error)
(catch 'handler-done
(invoke-process-request-with-error-handling
@@ -253,7 +252,7 @@
(defun within-request-p ()
"True if we're in the context of a request, otherwise nil."
- *within-request-p*)
+ (and (boundp '*request*) *request*))
(defun parse-multipart-form-data (request external-format)
"Parse the REQUEST body as multipart/form-data, assuming that its
Modified: trunk/thirdparty/hunchentoot/specials.lisp
===================================================================
--- trunk/thirdparty/hunchentoot/specials.lisp 2009-12-14 20:26:57 UTC (rev 4487)
+++ trunk/thirdparty/hunchentoot/specials.lisp 2009-12-22 22:14:35 UTC (rev 4488)
@@ -234,11 +234,6 @@
(defvar-unbound *request*
"The current REQUEST object while in the context of a request.")
-(defvar *within-request-p* nil
- "True while in the context of a request (while *request* is bound),
-otherwise nil. Outside callers should use exported function
-within-request-p to test this.")
-
(defvar-unbound *reply*
"The current REPLY object while in the context of a request.")
Revision: 4487
Author: edi
URL: http://bknr.net/trac/changeset/4487
Parameters without values
U trunk/thirdparty/drakma/CHANGELOG.txt
U trunk/thirdparty/drakma/doc/index.html
U trunk/thirdparty/drakma/request.lisp
U trunk/thirdparty/drakma/util.lisp
Modified: trunk/thirdparty/drakma/CHANGELOG.txt
===================================================================
--- trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:49:53 UTC (rev 4486)
+++ trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-14 20:26:57 UTC (rev 4487)
@@ -1,3 +1,5 @@
+Allow for GET/POST parameters without a value (seen on Lotus webservers)
+
Version 1.1.0
2009-12-01
Allowed additional headers to be function designators (suggested by Xiangjun Wu)
Modified: trunk/thirdparty/drakma/doc/index.html
===================================================================
--- trunk/thirdparty/drakma/doc/index.html 2009-12-01 22:49:53 UTC (rev 4486)
+++ trunk/thirdparty/drakma/doc/index.html 2009-12-14 20:26:57 UTC (rev 4487)
@@ -789,7 +789,10 @@
each being a string) which denotes the parameters which are added to
the query part of the URI or (in the case of a POST request) comprise
the request body. (But
-see <a href="#content"><code><i>content</i></code></a> below.) The
+see <a href="#content"><code><i>content</i></code></a> below.)
+The values can also be
+<code>NIL</code> in which case only the name (without an equal sign) is used in
+the query string. The
name/value pairs
are <a
href="http://www.blooberry.com/indexdot/html/topics/urlencoding.htm">URL-encoded</a>
Modified: trunk/thirdparty/drakma/request.lisp
===================================================================
--- trunk/thirdparty/drakma/request.lisp 2009-12-01 22:49:53 UTC (rev 4486)
+++ trunk/thirdparty/drakma/request.lisp 2009-12-14 20:26:57 UTC (rev 4487)
@@ -237,19 +237,20 @@
PARAMETERS is an alist of name/value pairs \(the car and the cdr each
being a string) which denotes the parameters which are added to the
query part of the URL or \(in the case of a POST request) comprise the
-body of the request. (But see CONTENT below.) The name/value pairs
-are URL-encoded using the FLEXI-STREAMS external format
-EXTERNAL-FORMAT-OUT before they are sent to the server unless
-FORM-DATA is true in which case the POST request body is sent as
-`multipart/form-data' using EXTERNAL-FORMAT-OUT. The values of the
-PARAMETERS alist can also be pathnames, open binary input streams,
-unary functions, or lists where the first element is of one of the
-former types. These values denote files which should be sent as part
-of the request body. If files are present in PARAMETERS, the content
-type of the request is always `multipart/form-data'. If the value is
-a list, the part of the list behind the first element is treated as a
-plist which can be used to specify a content type and/or a filename
-for the file, i.e. such a value could look like, e.g.,
+body of the request. (But see CONTENT below.) The values can also be
+NIL in which case only the name \(without an equal sign) is used in
+the query string. The name/value pairs are URL-encoded using the
+FLEXI-STREAMS external format EXTERNAL-FORMAT-OUT before they are sent
+to the server unless FORM-DATA is true in which case the POST request
+body is sent as `multipart/form-data' using EXTERNAL-FORMAT-OUT. The
+values of the PARAMETERS alist can also be pathnames, open binary
+input streams, unary functions, or lists where the first element is of
+one of the former types. These values denote files which should be
+sent as part of the request body. If files are present in PARAMETERS,
+the content type of the request is always `multipart/form-data'. If
+the value is a list, the part of the list behind the first element is
+treated as a plist which can be used to specify a content type and/or
+a filename for the file, i.e. such a value could look like, e.g.,
\(#p\"/tmp/my_file.doc\" :content-type \"application/msword\"
:filename \"upload.doc\").
@@ -406,7 +407,10 @@
(setq proxy (list proxy 80))))
;; make sure we don't get :CRLF on Windows
(let ((*default-eol-style* :lf)
- (file-parameters-p (find-if-not #'stringp parameters :key #'cdr))
+ (file-parameters-p (find-if-not (lambda (thing)
+ (or (stringp thing)
+ (null thing)))
+ parameters :key #'cdr))
parameters-used-p)
(when (and file-parameters-p (not (eq method :post)))
(parameter-error "Don't know how to handle parameters in ~S, as this is not a POST request."
Modified: trunk/thirdparty/drakma/util.lisp
===================================================================
--- trunk/thirdparty/drakma/util.lisp 2009-12-01 22:49:53 UTC (rev 4486)
+++ trunk/thirdparty/drakma/util.lisp 2009-12-14 20:26:57 UTC (rev 4487)
@@ -111,18 +111,19 @@
(defun alist-to-url-encoded-string (alist external-format)
"ALIST is supposed to be an alist of name/value pairs where both
-names and values are strings. This function returns a string where
-this list is represented as for the content type
-`application/x-www-form-urlencoded', i.e. the values are URL-encoded
-using the external format EXTERNAL-FORMAT, the pairs are joined with a
-#\\& character, and each name is separated from its value with a #\\=
-character."
+names and values are strings \(or, for values, NIL). This function
+returns a string where this list is represented as for the content
+type `application/x-www-form-urlencoded', i.e. the values are
+URL-encoded using the external format EXTERNAL-FORMAT, the pairs are
+joined with a #\\& character, and each name is separated from its
+value with a #\\= character. If the value is NIL, no #\\= is used."
(with-output-to-string (out)
(loop for first = t then nil
for (name . value) in alist
unless first do (write-char #\& out)
- do (format out "~A=~A"
+ do (format out "~A~:[~;=~A~]"
(url-encode name external-format)
+ value
(url-encode value external-format)))))
(defun default-port (uri)
Revision: 4486
Author: edi
URL: http://bknr.net/trac/changeset/4486
::rollseyes::
U trunk/thirdparty/chunga/doc/index.html
Modified: trunk/thirdparty/chunga/doc/index.html
===================================================================
--- trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:48:48 UTC (rev 4485)
+++ trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:49:53 UTC (rev 4486)
@@ -548,7 +548,7 @@
<p><br>[Function]<br><a class=none name='token-char-p'><b>token-char-p</b> <i>char</i> => <i>generalized-boolean</i></a>
<blockquote><br>
-Returns a true value if the Lisp character <code><i>CHAR</i></code> is a token constituent
+Returns a true value if the Lisp character <code><i>char</i></code> is a token constituent
according to
<a href="http://www.rfc.net/rfc2616.html">RFC 2616</a>.
Revision: 4485
Author: edi
URL: http://bknr.net/trac/changeset/4485
Typo
U trunk/thirdparty/chunga/doc/index.html
Modified: trunk/thirdparty/chunga/doc/index.html
===================================================================
--- trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:45:24 UTC (rev 4484)
+++ trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:48:48 UTC (rev 4485)
@@ -548,7 +548,7 @@
<p><br>[Function]<br><a class=none name='token-char-p'><b>token-char-p</b> <i>char</i> => <i>generalized-boolean</i></a>
<blockquote><br>
-Returns a true value if the Lisp character CHAR is a token constituent
+Returns a true value if the Lisp character <code><i>CHAR</i></code> is a token constituent
according to
<a href="http://www.rfc.net/rfc2616.html">RFC 2616</a>.
Revision: 4483
Author: edi
URL: http://bknr.net/trac/changeset/4483
Release 1.1.0
U trunk/thirdparty/drakma/CHANGELOG.txt
U trunk/thirdparty/drakma/doc/index.html
U trunk/thirdparty/drakma/drakma.asd
Modified: trunk/thirdparty/drakma/CHANGELOG.txt
===================================================================
--- trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:41:49 UTC (rev 4482)
+++ trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:44:55 UTC (rev 4483)
@@ -1,3 +1,5 @@
+Version 1.1.0
+2009-12-01
Allowed additional headers to be function designators (suggested by Xiangjun Wu)
Be more liberal when parsing cookies (thanks to Andrei Stebakov)
Added HTTP method PATCH (thanks to Xiangjun Wu)
Modified: trunk/thirdparty/drakma/doc/index.html
===================================================================
--- trunk/thirdparty/drakma/doc/index.html 2009-12-01 22:41:49 UTC (rev 4482)
+++ trunk/thirdparty/drakma/doc/index.html 2009-12-01 22:44:55 UTC (rev 4483)
@@ -654,13 +654,13 @@
Drakma together with this documentation can be downloaded
from <a href="http://weitz.de/files/drakma.tar.gz">http://weitz.de/files/drakma.tar.gz</a>.
-The current version is 1.0.0. Drakma can be installed
+The current version is 1.1.0. Drakma can be installed
via <a href="http://www.cliki.net/asdf">ASDF</a> and depends on the
open source
libraries <a href="http://www.cliki.net/cl-base64">CL-BASE64</a> (use
3.3.2 or higher to avoid an unneeded dependency
on <a href="http://www.cliki.net/kmrcl">KMRCL</a>), <a href="http://www.cliki.net/Puri">Puri</a>, <a href="http://weitz.de/flexi-streams/">FLEXI-STREAMS</a>,
-and <a href="http://weitz.de/chunga/">Chunga</a> (1.0.0 or higher).
+and <a href="http://weitz.de/chunga/">Chunga</a> (1.1.0 or higher).
If you're <em>not</em> using LispWorks, you'll also
need <a href="http://www.cliki.net/usocket">usocket</a> (0.3.2 or
newer) and (except
Modified: trunk/thirdparty/drakma/drakma.asd
===================================================================
--- trunk/thirdparty/drakma/drakma.asd 2009-12-01 22:41:49 UTC (rev 4482)
+++ trunk/thirdparty/drakma/drakma.asd 2009-12-01 22:44:55 UTC (rev 4483)
@@ -38,7 +38,7 @@
(in-package :drakma-asd)
-(defvar *drakma-version-string* "1.0.0"
+(defvar *drakma-version-string* "1.1.0"
"Drakma's version number as a string.")
;; we export its name so we can import it later
Revision: 4481
Author: edi
URL: http://bknr.net/trac/changeset/4481
Release 1.1.0
U trunk/thirdparty/chunga/CHANGELOG.txt
U trunk/thirdparty/chunga/chunga.asd
U trunk/thirdparty/chunga/doc/index.html
Modified: trunk/thirdparty/chunga/CHANGELOG.txt
===================================================================
--- trunk/thirdparty/chunga/CHANGELOG.txt 2009-12-01 22:36:55 UTC (rev 4480)
+++ trunk/thirdparty/chunga/CHANGELOG.txt 2009-12-01 22:41:14 UTC (rev 4481)
@@ -1,3 +1,5 @@
+Version 1.1.0
+2009-12-01
Exported TOKEN-CHAR-P
Allowed START and END keyword arguments for TRIM-WHITESPACE
Simplified cookie value parsing
Modified: trunk/thirdparty/chunga/chunga.asd
===================================================================
--- trunk/thirdparty/chunga/chunga.asd 2009-12-01 22:36:55 UTC (rev 4480)
+++ trunk/thirdparty/chunga/chunga.asd 2009-12-01 22:41:14 UTC (rev 4481)
@@ -29,7 +29,7 @@
(asdf:defsystem :chunga
:serial t
- :version "1.0.0"
+ :version "1.1.0"
:depends-on (:trivial-gray-streams)
:components ((:file "packages")
(:file "specials")
Modified: trunk/thirdparty/chunga/doc/index.html
===================================================================
--- trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:36:55 UTC (rev 4480)
+++ trunk/thirdparty/chunga/doc/index.html 2009-12-01 22:41:14 UTC (rev 4481)
@@ -108,7 +108,7 @@
Chunga together with this documentation can be downloaded
from <a href="http://weitz.de/files/chunga.tar.gz">http://weitz.de/files/chunga.tar.gz</a>. The
-current version is 1.0.0. (This version is <b>not</b> compatible with
+current version is 1.1.0. (This version is <b>not</b> compatible with
pre-2009 releases
of <a href="http://weitz.de/hunchentoot/">Hunchentoot</a>
or <a href="http://weitz.de/drakma/">Drakma</a>.) Chunga will only
Revision: 4480
Author: edi
URL: http://bknr.net/trac/changeset/4480
Allow additional headers to be functions
U trunk/thirdparty/drakma/CHANGELOG.txt
U trunk/thirdparty/drakma/doc/index.html
U trunk/thirdparty/drakma/request.lisp
Modified: trunk/thirdparty/drakma/CHANGELOG.txt
===================================================================
--- trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:06:56 UTC (rev 4479)
+++ trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:36:55 UTC (rev 4480)
@@ -1,3 +1,4 @@
+Allowed additional headers to be function designators (suggested by Xiangjun Wu)
Be more liberal when parsing cookies (thanks to Andrei Stebakov)
Added HTTP method PATCH (thanks to Xiangjun Wu)
Don't send GET parameters again when redirecting (reported by Eugene Ossintsev)
Modified: trunk/thirdparty/drakma/doc/index.html
===================================================================
--- trunk/thirdparty/drakma/doc/index.html 2009-12-01 22:06:56 UTC (rev 4479)
+++ trunk/thirdparty/drakma/doc/index.html 2009-12-01 22:36:55 UTC (rev 4480)
@@ -935,11 +935,15 @@
<a class=none name="proxy-basic-authorization"><code><i>proxy-basic-authorization</i></code></a> is used like <code><i>basic-authorization</i></code>, but for
the proxy, and only if <code><i>proxy</i></code> is true.
<p>
-<a class=none name="additional-headers"><code><i>additional-headers</i></code></a> is a
-name/value <a
-href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a>
-(like <code><i>parameters</i></code>) of additional HTTP headers which
-should be sent with the request.
+<a class=none
+name="additional-headers"><code><i>additional-headers</i></code></a>
+is a
+name/value <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a>
+of additional HTTP headers which should be sent with the request.
+Unlike in <code><i>parameters</i></code>, the cdrs can not only be
+strings but also designators for unary functions (which should in turn
+return a string) in which case the function is called each time the
+header is written.
<p>
If <a name="redirect" class=none><code><i>redirect</i></code></a> is
not <code>NIL</code>, it must be a non-negative integer
Modified: trunk/thirdparty/drakma/request.lisp
===================================================================
--- trunk/thirdparty/drakma/request.lisp 2009-12-01 22:06:56 UTC (rev 4479)
+++ trunk/thirdparty/drakma/request.lisp 2009-12-01 22:36:55 UTC (rev 4480)
@@ -321,8 +321,11 @@
BASIC-AUTHORIZATION, but for the proxy, and only if PROXY is
true.
-ADDITIONAL-HEADERS is a name/value alist \(like PARAMETERS) of
-additional HTTP headers which should be sent with the request.
+ADDITIONAL-HEADERS is a name/value alist of additional HTTP headers
+which should be sent with the request. Unlike in PARAMETERS, the cdrs
+can not only be strings but also designators for unary functions
+\(which should in turn return a string) in which case the function is
+called each time the header is written.
If REDIRECT is not NIL, it must be a non-negative integer or T.
If REDIRECT is true, Drakma will follow redirects \(return codes
@@ -543,7 +546,10 @@
(setq must-close close)
(write-header "Connection" "close"))
(loop for (name . value) in additional-headers
- do (write-header name "~A" value))
+ do (write-header name "~A"
+ (cond ((or (functionp value) (symbolp value))
+ (funcall value))
+ (t value))))
(when content
(when content-type
(write-header "Content-Type" "~A" content-type))
Revision: 4479
Author: edi
URL: http://bknr.net/trac/changeset/4479
Be more liberal when parsing cookies
U trunk/thirdparty/drakma/CHANGELOG.txt
U trunk/thirdparty/drakma/cookies.lisp
U trunk/thirdparty/drakma/util.lisp
Modified: trunk/thirdparty/drakma/CHANGELOG.txt
===================================================================
--- trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 21:58:01 UTC (rev 4478)
+++ trunk/thirdparty/drakma/CHANGELOG.txt 2009-12-01 22:06:56 UTC (rev 4479)
@@ -1,3 +1,4 @@
+Be more liberal when parsing cookies (thanks to Andrei Stebakov)
Added HTTP method PATCH (thanks to Xiangjun Wu)
Don't send GET parameters again when redirecting (reported by Eugene Ossintsev)
Solidify feature expressions (thanks to Joshua Taylor)
Modified: trunk/thirdparty/drakma/cookies.lisp
===================================================================
--- trunk/thirdparty/drakma/cookies.lisp 2009-12-01 21:58:01 UTC (rev 4478)
+++ trunk/thirdparty/drakma/cookies.lisp 2009-12-01 22:06:56 UTC (rev 4479)
@@ -249,20 +249,14 @@
of three-element lists where each one contains the name of the
cookie, the value of the cookie, and an attribute/value list for
the optional cookie parameters."
- (with-sequence-from-string (stream string)
- (loop with *current-error-message* = (format nil "While parsing cookie header ~S:" string)
- for first = t then nil
- for next = (and (skip-whitespace stream)
- (or first (assert-char stream #\,))
- (skip-whitespace stream)
- (skip-more-commas stream))
- for name/value = (and next (read-name-value-pair stream
- :cookie-syntax t))
- for parameters = (and name/value (read-name-value-pairs stream
- :value-required-p nil
- :cookie-syntax t))
- while name/value
- collect (list (car name/value) (cdr name/value) parameters))))
+ (let ((*current-error-message* (format nil "While parsing cookie header ~S:" string))
+ result)
+ (dolist (substring (split-set-cookie-string string))
+ (with-sequence-from-string (stream substring)
+ (let* ((name/value (read-name-value-pair stream :cookie-syntax t))
+ (parameters (read-name-value-pairs stream :value-required-p nil :cookie-syntax t)))
+ (push (list (car name/value) (cdr name/value) parameters) result))))
+ (nreverse result)))
(defun get-cookies (headers uri)
"Returns a list of COOKIE objects corresponding to the
Modified: trunk/thirdparty/drakma/util.lisp
===================================================================
--- trunk/thirdparty/drakma/util.lisp 2009-12-01 21:58:01 UTC (rev 4478)
+++ trunk/thirdparty/drakma/util.lisp 2009-12-01 22:06:56 UTC (rev 4479)
@@ -279,4 +279,49 @@
WITH-INPUT-FROM-STRING, but creates a sequence of octets that works
with CHUNGA::PEEK-CHAR* and friends."
`(flex:with-input-from-sequence (,stream (map 'list #'char-code ,string))
- ,@body))
\ No newline at end of file
+ ,@body))
+
+(defun split-set-cookie-string (string)
+ "Splits the string STRING which is assumed to be the value of a
+`Set-Cookie' into parts corresponding to individual cookies and
+returns a list of these parts \(substrings).
+
+The string /should/ be split at commas, but heuristical approach is
+used instead which doesn't split at commas which are followed by what
+cannot be recognized as the start of the next cookie. This is
+necessary because servers send headers containing unquoted commas
+which are not meant as separators."
+ ;; this would of course be a lot easier with CL-PPCRE's SPLIT
+ (let ((cookie-start 0)
+ (string-length (length string))
+ search-start
+ result)
+ (tagbody
+ ;; at this point we know that COOKIE-START is the start of a new
+ ;; cookie (at the start of the string or behind a comma)
+ next-cookie
+ (setq search-start cookie-start)
+ ;; we reach this point if the last comma didn't separate two
+ ;; cookies or if there was no previous comma
+ skip-comma
+ (unless (< search-start string-length)
+ (return-from split-set-cookie-string (nreverse result)))
+ ;; look is there's a comma
+ (let* ((comma-pos (position #\, string :start search-start))
+ ;; and if so, look for a #\= behind the comma
+ (equals-pos (and comma-pos (position #\= string :start comma-pos)))
+ ;; check that (except for whitespace) there's only a token
+ ;; (the name of the next cookie) between #\, and #\=
+ (new-cookie-start-p (and equals-pos
+ (every 'token-char-p
+ (trim-whitespace string
+ :start (1+ comma-pos)
+ :end equals-pos)))))
+ (when (and comma-pos (not new-cookie-start-p))
+ (setq search-start (1+ comma-pos))
+ (go skip-comma))
+ (let ((end-pos (or comma-pos string-length)))
+ (push (trim-whitespace (subseq string cookie-start end-pos)) result)
+ (setq cookie-start (1+ end-pos))
+ (go next-cookie))))))
+