unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* Patch for guile-www-2.9 (www cgi), multiple fixes
@ 2005-04-12  1:09 Alan Grover
  0 siblings, 0 replies; only message in thread
From: Alan Grover @ 2005-04-12  1:09 UTC (permalink / raw)


Fixes the following:
* Change a use-module statement to (ice-9 optargs) instead of (ice-9 
optargs-kw). Not deeply investigated.
* Tolerates query-strings without a "=" for empty names. Thus: 
http://gnu.org?a=1&b will give two names (a and b), where b has the 
value "".
* Tolerates query-strings where the name is empty. Thus: 
http:/gnu.org?=b will give a key of "" whose value is b.
* Applies url-decode to each name. Thus: http://gnu.org?x%26y=1 will 
give a name of "x=y" whose value is 1.
* Adds the variable cgi:names-values which holds the parsed name/value 
pairs in the same order as found in the query-string: ("a" . 1) ("b" . 
2), etc. If a name repeats, it also repeats in the list.
* Should be more friendly for mod-list/fastcgi style use. The "cgi:init" 
function should re-initialize the module completely (not thoroughly 
tested: works for query-string parsing).

This incorporates fixes to bugs reported by awgrover@mail.msen on 11 
April 2005:
* guile-www-2.9 (www cgi) names in query-string not url-decoded
* guile-www-2.9 (www cgi) form-data loses original order
* guile-www-2.9 (www cgi) bad cgi:values when a name has no "="
* guile-www-2.9 (www cgi) does not support mod-lisp/fastcgi style uses
* guile-www uses obsolete optargs-kw

Notes:
* Does not use shared-substrings (these are deprecated).
* I did not concern myself with time/space optimization since 
query-string parsing happens only once per request, and the query-string 
is typically of reasonable size. Instead of append!, one could cons onto 
the head and reverse later. No doubt other optimizations can be done.

Patch:

cgi.scm

<   #:use-module (ice-9 optargs-kw))
<
---
 >   #:use-module (srfi srfi-1)
 >   #:use-module (ice-9 optargs))
42c42,44
< (define *env-alist*
---
 > (define *env-alist* #f)
 > (define (make-env-alist)
 >  (set! *env-alist*
97c99
<                                 #\, types)))))))))
---
 >                                 #\, types))))))))))
116a119,120
 >   (make-env-alist)
 >   (set! form-variables '())
178a183,187
 > ;; Return the key-value pairs (as cons), in the
 > ;; order they appeared. Thus, you can exactly reconstruct the 
query-string.
 > ;;
 > (define-public cgi:names-values #f) ; Stable order of name-value pairs
 >
179a189
 > ;; At least '(). It is possible for a name to be "".
273,290c283,336
< (define (parse-form raw-data)
<   ;; get-name and get-value are used to parse individual `name=value' 
pairs.
<   ;; Values are URL-encoded, so each must be decoded.
<   (define (get-name pair)
<     (let ((p (string-index pair #\=)))
<       (and p (subs pair 0 p))))
<   (define (get-value pair)
<     (let ((p (string-index pair #\=)))
<       (and p (url-coding:decode (subs pair (+ p 1))))))
<   (for-each (lambda (pair)
<               (let* ((name (get-name pair))
<                      (value (get-value pair))
<                      (old-value (cgi:values name)))
<                 (set! form-variables
<                       (assoc-set! form-variables
<                                   name
<                                   (cons value (or old-value '()))))))
<             (separate-fields-discarding-char #\& raw-data)))
---
 > ; The results are nearly stable. cgi:names will give
 > ; the names back as they are left-to-right in the query-string,
 > ; and the cgi:values will be in the original left-to-right order.
 > ; Except, if a name appears more than once in the query-string,
 > ; it will only appear once in cgi:names, in the first position.
 > ;
 >
 > (define (parse-form qstring)
 >   "url-decoded (key . values), values is "" if no value. updates 
form-variables"
 >   (set! cgi:names-values '())
 >   (let* (
 >     (dictionary '()) ; alist for key . (values)
 >     (key-value-strings
 >       (filter (lambda (x) (not (eq? x '())))  ; remove empties (e.g. 
"&&")
 >         (string-split qstring #\& )))  ; split on &
 >     (split-to-key-value (lambda (kv-string)
 >       (let* (
 >         (index-of-equals (string-index kv-string #\=)) ; find '='
 >         (key ; key part
 >           (begin
 >             (if index-of-equals
 >               (if (> index-of-equals 0)
 >                 (substring kv-string 0 index-of-equals )
 >                 "")  ; '=' at beginning
 >               (if (> (string-length kv-string) 0)
 >                 kv-string
 >                 #f))))  ; 0 length, which shouldn't happen here
 >         (value ; value part (as list) or #f
 >           (if (and key index-of-equals (< index-of-equals (- 
(string-length kv-string) 1)))
 >             (substring kv-string (+ index-of-equals 1))
 >             #f))
 >         )
 >         (if key
 >           (cons (url-coding:decode key) (if value (url-coding:decode 
value) #f))
 >           #f))))
 >     (update-dictionary (lambda (kv)
 >       "The assoc list is kept in order of query-string, append entry 
or value"
 >       (let* (
 >         (key (car kv))  ; don't call with #f for key
 >         (value (cdr kv))
 >         (current-entry (assoc key dictionary))
 >         )
 >         (if current-entry
 >           (append! (cdr current-entry) (list value))
 >
 >           (set! dictionary (append! dictionary (list (cons key (list 
(or value  "")))))))
 >         )))
 >     )
 >     (begin
 >       (for-each update-dictionary   ; insert into dictionary (or 
append values)
 >         (filter identity ; remove empty key-value, e.g. "="
 >           (map split-to-key-value
 >             key-value-strings )))  ; get "k=v"
 >       (set! form-variables dictionary))))
-- 
Alan Grover
awgrover@mail.msen.com
+1.734.476.0969


_______________________________________________
Bug-guile mailing list
Bug-guile@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-guile


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-04-12  1:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-12  1:09 Patch for guile-www-2.9 (www cgi), multiple fixes Alan Grover

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).