diff --git a/extra/cgi/authors.txt b/extra/cgi/authors.txt new file mode 100644 index 0000000000..e091bb8164 --- /dev/null +++ b/extra/cgi/authors.txt @@ -0,0 +1 @@ +John Benediktsson diff --git a/extra/cgi/cgi-docs.factor b/extra/cgi/cgi-docs.factor new file mode 100644 index 0000000000..75561912b3 --- /dev/null +++ b/extra/cgi/cgi-docs.factor @@ -0,0 +1,12 @@ +! Copyright (C) 2009-2012 John Benediktsson +! See http://factorcode.org/license.txt for BSD license +USING: assocs help.markup help.syntax ; +IN: cgi + +HELP: +{ $values { "assoc" assoc } } +{ $description "Parse a CGI request into an " { $link assoc } ". Multiple parameters are passed as a list for each key." } ; + +HELP: +{ $values { "assoc" assoc } } +{ $description "Parse a CGI request into an " { $link assoc } ". Only the first parameter is kept, if multiple parameters are passed." } ; diff --git a/extra/cgi/cgi-tests.factor b/extra/cgi/cgi-tests.factor new file mode 100644 index 0000000000..80c0f29d1a --- /dev/null +++ b/extra/cgi/cgi-tests.factor @@ -0,0 +1,20 @@ +! Copyright (C) 2009 John Benediktsson +! See http://factorcode.org/license.txt for BSD license + +USING: cgi cgi.private kernel tools.test ; + +[ t ] [ H{ } "" (query-string) = ] unit-test + +[ t ] [ H{ { "a" { "1" } } { "b" { "2" } } } + "a=1&b=2" (query-string) = ] unit-test + +[ t ] [ H{ { "a" { "1" } } { "b" { "2" "3" } } } + "a=1&b=2&b=3" (query-string) = ] unit-test + +[ t ] [ "text/html" (content-type) + [ H{ } = ] [ "text/html" = ] bi* and ] unit-test + +[ t ] [ "text/html; charset=utf-8" (content-type) + [ H{ { "charset" { "utf-8" } } } = ] + [ "text/html" = ] bi* and ] unit-test + diff --git a/extra/cgi/cgi.factor b/extra/cgi/cgi.factor new file mode 100644 index 0000000000..9030c00e99 --- /dev/null +++ b/extra/cgi/cgi.factor @@ -0,0 +1,53 @@ +! Copyright (C) 2009-2012 John Benediktsson +! See http://factorcode.org/license.txt for BSD license + +USING: arrays assocs combinators environment io kernel +math.parser regexp sequences splitting strings unicode.case +urls.encoding ; + +IN: cgi + +assoc [ nip ] assoc-filter [ + [ [ CHAR: \s = ] trim ] + [ dup string? [ 1array ] when ] bi* + ] assoc-map ; + +: parse-get ( -- assoc ) + "QUERY_STRING" os-env "" or (query-string) ; + +: (content-type) ( string -- params media/type ) + ";" split unclip [ + [ H{ } clone ] [ first (query-string) ] if-empty + ] dip ; + +: (multipart) ( -- assoc ) + "multipart unsupported" throw ; + +: (urlencoded) ( -- assoc ) + "CONTENT_LENGTH" os-env "0" or string>number + read [ "" ] [ "&" append ] if-empty + "QUERY_STRING" os-env [ append ] when* (query-string) ; + +: parse-post ( -- assoc ) + "CONTENT_TYPE" os-env "" or (content-type) { + { "multipart/form-data" [ (multipart) ] } + { "application/x-www-form-urlencoded" [ (urlencoded) ] } + [ drop parse-get ] + } case nip ; + +PRIVATE> + +: ( -- assoc ) + "REQUEST_METHOD" os-env "GET" or >upper { + { "GET" [ parse-get ] } + { "POST" [ parse-post ] } + [ "Unknown request method" throw ] + } case ; + +: ( -- assoc ) + [ first ] assoc-map ; + + diff --git a/extra/cgi/summary.txt b/extra/cgi/summary.txt new file mode 100644 index 0000000000..6e304e8b70 --- /dev/null +++ b/extra/cgi/summary.txt @@ -0,0 +1 @@ +Support using Factor in CGI scripts