| 
									
										
										
										
											2010-07-06 00:55:36 -04:00
										 |  |  | ! Copyright (C) 2008, 2010 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  | USING: arrays ascii assocs combinators combinators.short-circuit | 
					
						
							| 
									
										
										
										
											2015-11-04 11:36:56 -05:00
										 |  |  | fry io.encodings.string io.encodings.utf8 kernel linked-assocs | 
					
						
							|  |  |  | make math math.parser present sequences splitting strings ;
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | IN: urls.encoding | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : url-quotable? ( ch -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [ letter? ] | 
					
						
							|  |  |  |         [ LETTER? ] | 
					
						
							|  |  |  |         [ digit? ] | 
					
						
							| 
									
										
										
										
											2010-07-06 00:55:36 -04:00
										 |  |  |         [ "-._~/:" member? ] | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |     } 1|| ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-01 05:40:07 -04:00
										 |  |  | ! see http://tools.ietf.org/html/rfc3986#section-2.2 | 
					
						
							|  |  |  | : gen-delim? ( ch -- ? )
 | 
					
						
							|  |  |  |     ":/?#[]@" member? ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sub-delim? ( ch -- ? )
 | 
					
						
							|  |  |  |     "!$&'()*+,;=" member? ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reserved? ( ch -- ? )
 | 
					
						
							|  |  |  |     [ gen-delim? ] [ sub-delim? ] bi or ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! see http://tools.ietf.org/html/rfc3986#section-2.3 | 
					
						
							|  |  |  | : unreserved? ( ch -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [ letter? ] | 
					
						
							|  |  |  |         [ LETTER? ] | 
					
						
							|  |  |  |         [ digit? ] | 
					
						
							|  |  |  |         [ "-._~" member? ] | 
					
						
							|  |  |  |     } 1|| ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : push-utf8 ( ch -- )
 | 
					
						
							|  |  |  |     1string utf8 encode | 
					
						
							| 
									
										
										
										
											2009-07-03 02:18:49 -04:00
										 |  |  |     [ CHAR: % , >hex >upper 2 CHAR: 0 pad-head % ] each ;
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  | : (url-encode) ( str quot: ( ch -- ? ) -- encoded )
 | 
					
						
							|  |  |  |     '[ [ dup @ [ , ] [ push-utf8 ] if ] each ] "" make ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : url-encode ( str -- encoded )
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  |     [ url-quotable? ] (url-encode) ;
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-01 05:40:07 -04:00
										 |  |  | : url-encode-full ( str -- encoded )
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  |     [ unreserved? ] (url-encode) ;
 | 
					
						
							| 
									
										
										
										
											2008-11-01 05:40:07 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : url-decode-hex ( index str -- )
 | 
					
						
							|  |  |  |     2dup length 2 - >= [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  |         [ 1 + dup 2 + ] dip subseq hex> [ , ] when*
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : url-decode-iter ( index str -- )
 | 
					
						
							|  |  |  |     2dup length >= [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         2dup nth dup CHAR: % = [ | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  |             drop 2dup url-decode-hex [ 3 + ] dip
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |         ] [ | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |             , [ 1 + ] dip
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |         ] if url-decode-iter | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : url-decode ( str -- decoded )
 | 
					
						
							|  |  |  |     [ 0 swap url-decode-iter ] "" make utf8 decode ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : query-decode ( str -- decoded )
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:22:54 -05:00
										 |  |  |     "+" split "%20" join url-decode ;
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-query-param ( value key assoc -- )
 | 
					
						
							| 
									
										
										
										
											2009-04-10 05:01:59 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2014-12-01 00:33:48 -05:00
										 |  |  |             { [ dup string? ] [ swap 2array ] } | 
					
						
							|  |  |  |             { [ dup array? ] [ swap suffix ] } | 
					
						
							|  |  |  |             { [ dup not ] [ drop ] } | 
					
						
							| 
									
										
										
										
											2009-04-10 05:01:59 -04:00
										 |  |  |         } cond
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:33:48 -05:00
										 |  |  |     ] change-at ;
 | 
					
						
							| 
									
										
										
										
											2009-04-10 05:01:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : query>assoc ( query -- assoc )
 | 
					
						
							|  |  |  |     dup [ | 
					
						
							| 
									
										
										
										
											2015-11-04 11:36:56 -05:00
										 |  |  |         "&;" split <linked-hash> [ | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |             [ | 
					
						
							|  |  |  |                 [ "=" split1 [ dup [ query-decode ] when ] bi@ swap ] dip
 | 
					
						
							|  |  |  |                 add-query-param | 
					
						
							|  |  |  |             ] curry each
 | 
					
						
							|  |  |  |         ] keep
 | 
					
						
							|  |  |  |     ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : assoc>query ( assoc -- str )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2014-12-01 00:33:48 -05:00
										 |  |  |         [ | 
					
						
							|  |  |  |             [ url-encode-full ] dip [ | 
					
						
							|  |  |  |                 dup array? [ 1array ] unless
 | 
					
						
							|  |  |  |                 [ present url-encode-full "=" glue , ] with each
 | 
					
						
							|  |  |  |             ] [ , ] if*
 | 
					
						
							| 
									
										
										
										
											2008-09-29 20:43:04 -04:00
										 |  |  |         ] assoc-each
 | 
					
						
							|  |  |  |     ] { } make "&" join ;
 |