Greg Slepak avatar Greg Slepak committed 5f79687

fixed and improved the url-decoding and encoding functions in Request

Comments (0)

Files changed (4)

   * added new add-to-load-path and wrap-func functions to utils.lsp
   * added CGI-like route to the inactive plugins. Move to the active
     active plugins folder if you want to use it.
+  * added utf8-urlencode/decode functions to Request, they handle foreign characters perfectly.
 
 Version 0.51
 

example-site/dragonfly-api/index.html

 <p>Provides convenient logging facility for all of Dragonfly.</p>
 <a href="log.lsp.html#Dragonfly_log-func">log-func</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-debug">log-debug</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-info">log-info</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-warn">log-warn</a>&nbsp; &nbsp; <a href="log.lsp.html#Dragonfly_log-err">log-err</a>&nbsp; &nbsp; <a href="request.lsp.html"><br/><br/><h2>Module:&nbsp;request.lsp</h2></a>
 <p></p>
-<a href="request.lsp.html#_$GET">$GET</a>&nbsp; &nbsp; <a href="request.lsp.html#_$POST">$POST</a>&nbsp; &nbsp; <a href="request.lsp.html#_$FILES">$FILES</a>&nbsp; &nbsp; <a href="request.lsp.html#_$COOKIES">$COOKIES</a>&nbsp; &nbsp; <a href="request.lsp.html#_$BINARY">$BINARY</a>&nbsp; &nbsp; <a href="response.lsp.html"><br/><br/><h2>Module:&nbsp;response.lsp</h2></a>
+<a href="request.lsp.html#_$GET">$GET</a>&nbsp; &nbsp; <a href="request.lsp.html#_$POST">$POST</a>&nbsp; &nbsp; <a href="request.lsp.html#_$FILES">$FILES</a>&nbsp; &nbsp; <a href="request.lsp.html#_$COOKIES">$COOKIES</a>&nbsp; &nbsp; <a href="request.lsp.html#_$BINARY">$BINARY</a>&nbsp; &nbsp; <a href="request.lsp.html#_utf8-urlencode">utf8-urlencode</a>&nbsp; &nbsp; <a href="request.lsp.html#_utf8-urldecode">utf8-urldecode</a>&nbsp; &nbsp; <a href="response.lsp.html"><br/><br/><h2>Module:&nbsp;response.lsp</h2></a>
 <p></p>
 <a href="response.lsp.html#Response_status">status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_header">header</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_cookie">cookie</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers">send-headers</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_redirect">redirect</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_send-headers-with-status">send-headers-with-status</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_content-type">content-type</a>&nbsp; &nbsp; <a href="response.lsp.html#Response_extension->type">extension->type</a>&nbsp; &nbsp; <a href="utils.lsp.html"><br/><br/><h2>Module:&nbsp;utils.lsp</h2></a>
 <p></p>

example-site/dragonfly-api/request.lsp.html

 
 
 
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_utf8-urlencode"></a><h3><font color=#CC0000>utf8-urlencode</font></h3>
+<b>syntax: (<font color=#CC0000>utf8-urlencode</font> <em>str</em> [<em>bool-everything</em>])</b><br/>
+<b>parameter: </b>str - the string to encode<br/>
+<b>parameter: </b>bool-everything - whether to escape the entire string or just most of the "non-ascii friendly" parts.<br/>
+ <p>Use this function to safely encode data that might have foreign characters in it, or simply
+ characters that should be placed into URLs:</p>
+ <b>example:</b>
+ <pre> (utf8-urlencode "What time is it?")  => "What%20time%20is%20it%3F"</pre>
+
+<br/><br/><center>- &sect; -</center><br/>
+<a name="_utf8-urldecode"></a><h3><font color=#CC0000>utf8-urldecode</font></h3>
+<b>syntax: (<font color=#CC0000>utf8-urldecode</font> <em>str</em>)</b><br/>
+ <p>Decodes a utf8-urlencoded string. Converts '+'&apos;s to spaces.</p>
+
+
 
 
 

example-site/dragonfly-framework/lib/request.lsp

 (context 'Request)
 
 ;===============================================================================
+; !UTF8 Compatible URL encoding/decoding
+;===============================================================================
+
+(constant 'REGEX_HTTP_SPECIAL_STR (regex-comp {([^.0-9a-z]+)} 1))
+(constant 'REGEX_HEX_ENCODED_CHAR (regex-comp {%([0-9A-F][0-9A-F])} 1))
+
+(define (hex-encode-str str , cnvrt)
+	(setf cnvrt	(dup "%%%X" (length str)))
+	(eval (append '(format cnvrt) (unpack (dup "b" (length str)) str)))
+)
+
+;; @syntax (utf8-urlencode <str> [<bool-everything>])
+;; @param str the string to encode
+;; @param bool-everything whether to escape the entire string or just most of the "non-ascii friendly" parts.
+;; <p>Use this function to safely encode data that might have foreign characters in it, or simply
+;; characters that should be placed into URLs:</p>
+;; <b>example:</b>
+;; <pre> (utf8-urlencode "What time is it?")  => "What%20time%20is%20it%3F"</pre>
+(define (utf8-urlencode str everything)
+	(if everything
+		(hex-encode-str str)
+		(replace REGEX_HTTP_SPECIAL_STR str (hex-encode-str $1) 0x10000)
+	)
+)
+
+;; @syntax (utf8-urldecode <str>)
+;; <p>Decodes a utf8-urlencoded string. Converts '+'&apos;s to spaces.</p>
+(define (utf8-urldecode str)
+	(replace "+" str " ")
+	(replace REGEX_HEX_ENCODED_CHAR str (pack "b" (int $1 nil 16)) 0x10000)
+)
+
+;===============================================================================
 ; !Private Functions
 ;===============================================================================
 
-; (url-decode "What+time+is+it%3f")  => "What time is it?"
-(constant 'REGEX_HEX_ENCODED_CHAR (regex-comp {%([0-9A-F][0-9A-F])} 1))
-
-(define (url-decode str)
-   (replace "+" str " ")
-   (replace REGEX_HEX_ENCODED_CHAR str (char (int (string "0x" $1))) 0x10000)
-)
-
 (constant 'REGEX_QUERY (regex-comp {&([^&=]+)=?([^&=]*?)(?=&|$)} 1))
 
 (define (parse-query query)
 	(when (starts-with query "?") (pop query))
 	(push "&" query)
-	(find-all REGEX_QUERY query (list (url-decode $1) (url-decode $2)) 0x10000)
+	(find-all REGEX_QUERY query (list (utf8-urldecode $1) (utf8-urldecode $2)) 0x10000)
 )
 
 (define (regex-captcha regex-str str (options 0) (captcha 1))
 ; !$COOKIES
 ;===============================================================================
 
-; we do *NOT* want to use url-decode on the value
+; we do *NOT* want to use utf8-urldecode on the value
 ; that's something the user can do if they want to
 (when HTTP_COOKIE
 	(dolist (cookie (parse HTTP_COOKIE "; *" 0))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.