summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstanley lieber <stanley.lieber@gmail.com>2012-10-11 16:37:48 -0500
committerstanley lieber <stanley.lieber@gmail.com>2012-10-11 16:37:48 -0500
commitb786ff0544385a1219fb33a39fa6f0e15f49b846 (patch)
tree9e06a0a92ce1e04343e759bedb3d5cfcb0b280c1
parent5cddd21627fe67864fadd44e75cc3a5ab181fbb2 (diff)
downloadplan9front-b786ff0544385a1219fb33a39fa6f0e15f49b846.tar.xz
add /rc/bin/formpost; add formpost to hget(1) man page
-rwxr-xr-xrc/bin/formpost191
-rw-r--r--sys/man/1/hget107
2 files changed, 296 insertions, 2 deletions
diff --git a/rc/bin/formpost b/rc/bin/formpost
new file mode 100755
index 000000000..c60e1d002
--- /dev/null
+++ b/rc/bin/formpost
@@ -0,0 +1,191 @@
+#!/bin/rc
+rfork e
+argv0=$0
+fn usage {
+ echo usage: $argv0 '[-d] [-M] [ -u url ] [ -g action | -p action | -m action ] [ name:value | name:@value ]' ... >[1=2]
+ exit usage
+}
+d=()
+g=()
+M=()
+m=()
+p=()
+u=()
+while(~ $1 -*){
+ switch($1){
+ case -d
+ d=1
+ case -g
+ g=1
+ a=$2
+ shift
+ case -M
+ M=1
+ case -m
+ m=1
+ a=$2
+ shift
+ case -p
+ p=1
+ a=$2
+ shift
+ case -u
+ u=$2
+ shift
+ case *
+ usage
+ }
+ shift
+}
+if(~ $#M 0 && ~ $#u 0)
+ usage
+fn geth{
+ hget $u |
+ sed 's/ACTION\=/action\=/g;
+ s/ENCTYPE\=/enctype\=/g;
+ s/FORM/form/g;
+ s/INPUT/input/g;
+ s/METHOD\=/method\=/g;
+ s/NAME\=/name\=/g;
+ s/OPTION/option/g;
+ s/SELECT/select/g;
+ s/TEXTAREA/textarea/g;
+ s/TYPE\=/type\=/g' |
+ awk '/<([ ]|[ ])*form/,/<\/form>/ {print}' |
+ sed 's/<\/form>/&\nHJFORMEND\n/g;
+ s/<([ ]|[ ])*/HJBOUNDARY/g;
+ s/>(\n)*([ ]|[ ])*HJBOUNDARY/\n/g;
+ s/([ ]|[ ])*HJBOUNDARY//g;
+ s/^form/HJFORMSTART\n&/g' |
+ grep -e '(^HJFORM|^form|^input|^option|^select|^textarea)' >$1
+}
+fn getf{
+ a=`{grep -e '^form' $1 | sed 's/^.*action\=//g; s/^(\''|\"|[ ]*)//g; s/(\''|\"|[ ]|>).*$//g'}
+ e=`{grep -e '^form' $1 | sed 's/^.*enctype\=//g; s/^(\''|\"|[ ]*)//g; s/(\''|\"|[ ]|>).*$//g'}
+ m=`{grep -e '^form' $1 | sed 's/^.*method\=//g; s/^(\''|\"|[ ]*)//g; s/(\''|\"|[ ]|>).*$//g'}
+ f=$a
+ if(~ $#f 0)
+ f=/
+ if(~ $e multipart/form-data)
+ f=($f m)
+ if not if(~ $m post)
+ f=($f p)
+ if not
+ f=($f g)
+ ifs='
+' {
+ for(j in `{grep -e '(^input|^select|^textarea)' $1}){
+ if(~ $d 1)
+ echo $"j >>formpost.log #debug
+ if(~ $j *name'='*)
+ jname=`{echo $"j |
+ sed 's/^.*name\=//g;
+ s/^(\''|\"|[ ]*)//g;
+ s/(\''|\"|[ ]|>).*$//g;
+ s/^.*\=.*$//g'}
+ if(~ $j *value'='*)
+ jvalue=`{echo $"j |
+ sed 's/^.*value\=//g;
+ s/^(\''|\"|[ ]*)//g;
+ s/(\''|\"|[ ]|>).*$//g;
+ s/^.*\=.*$//g;
+ s/[ ]/HJSPACE/g'}
+ ff=`{echo $"jname':'$"jvalue |
+ sed 's/^.*\=.*:/:/g;
+ s/:.*\=.*$/:/g'}
+ if(! ~ $ff :*)
+ f=($"f $"ff)
+ jname=()
+ jvalue=()
+ }
+}
+ echo $"f
+}
+fn mencode{
+ f=()
+ cr=`{echo x | tr x \015}
+ while(! ~ $#1 0){
+ switch($1){
+ case *:*
+ f=($f $1)
+ case *
+ usage
+ }
+ shift
+ }
+ for(i in $f){
+ echo '--HJBOUNDARY'^$"cr
+ fname=`{echo $"i | awk -F ':' '{print $1}'}
+ fvalue=`{echo $"i | awk -F ':' '{print $2}'}
+ if(~ $fvalue @*){
+ fvalue=`{echo $"fvalue | sed 's/@//g'}
+ echo 'Content-Disposition: form-data; name="'$"fname'"; filename="'^`{basename $fvalue}^'"'$"cr
+ echo Content-Type: `{file -m $fvalue}^$"cr
+ echo $cr
+ cat $fvalue
+ echo $cr
+ }
+ if not{
+ echo 'Content-Disposition: form-data; name="'$"fname'"'$"cr
+ echo $"cr
+ echo $"fvalue^$"cr
+ }
+ }
+ echo '--HJBOUNDARY--'$"cr
+}
+fn uencode{
+ f=()
+ for(i){
+ fname=`{echo $"i | awk -F ':' '{print $1}'}
+ fvalue=`{echo $"i | awk -F ':' '{$1=""; print substr($0, 2)}' |
+ sed 's/HJSPACE/ /g' |
+ urlencode |
+ sed 's/%0A$//g'}
+ f=$"f^$"fname'='$"fvalue
+ if(! ~ $"i $*($#*))
+ f=$"f^'&'
+ }
+ echo $"f
+}
+fn print{
+ if(~ $d 1)
+ echo $"f >>formpost.log #debug
+ a=`{echo $"a | sed 's/^\///g'}
+ if(~ $a http*)
+ u=$a
+ if not
+ u=$"u/$"a
+ if(~ $M 1)
+ mencode `{for(i in $f){echo $"i}}
+ if not if(~ $m 1)
+ echo formpost -M `{for(i in $f){echo ''''$"i''''}} '| hget -P -r ''Content-Type: multipart/form-data, boundary=HJBOUNDARY''' $"u
+ if not if(~ $p 1)
+ echo 'hget -p '''^`{uencode $f}^''' '^$"u
+ if not
+ echo hget ''''$"u^'?'^`{uencode $f}^''''
+}
+if(~ $#M 0 && ~ $#g 0 && ~ $#m 0 && ~ $#p 0){
+ file=/tmp/formpost.$pid
+ geth $file
+ while(grep -s -e '^HJFORMSTART$' $file){
+ f=`{getf $file}
+ a=$f(1)
+ if(~ $f(2) g)
+ g=1
+ if not if(~ $f(2) m)
+ m=1
+ if not if(~ $f(2) p)
+ p=1
+ f=$f(3-)
+ print
+ { echo /HJFORMSTART/,/HJFORMEND/d
+ echo w
+ echo q
+ } | sam -d $file >[2]/dev/null
+ }
+ rm -f $file
+}
+if not{
+ f=$*
+ print
+}
diff --git a/sys/man/1/hget b/sys/man/1/hget
index daddb1ac6..cccfcfc73 100644
--- a/sys/man/1/hget
+++ b/sys/man/1/hget
@@ -1,6 +1,6 @@
.TH HGET 1
.SH NAME
-hget \- retrieve a web page corresponding to a url
+hget, formpost \- retrieve, post to a web page corresponding to a url
.SH SYNOPSIS
.B hget
[
@@ -22,6 +22,30 @@ hget \- retrieve a web page corresponding to a url
.I baseurl
]
.I url
+.PP
+.B formpost
+[
+.B -d
+] [
+.B -M
+] [
+.B -u
+.I url
+] [
+.B -g
+.I action
+] [
+.B -p
+.I action
+] [
+.B -m
+.I action
+] [
+.I name:value
+|
+.I name:@value
+]
+.I ...
.SH DESCRIPTION
.I Hget
retrieves the web page specified by the URL
@@ -72,10 +96,84 @@ sends an arbitrary HTTP
Option
.B -m
overrides the HTTP method used for the request.
+.PP
+.I Formpost
+retrieves the web page specified by the URL
+.I url,
+parses its HTML for form data, then prints
+.I hget
+commands to submit forms to the
+.I url.
+If the
+.B -M, -g, -p
+or
+.B -m
+flags are set, the
+.I hget
+commands are assembled without first retrieving and interpreting the
+target HTML.
+.PP
+If the
+.B -d
+flag is specified, debugging information is written
+to the file
+.B formpost.log
+in the current directory.
+.PP
+The
+.B -M
+flag applies multipart/form-data encoding to the
+remaining arguments and prints the result on
+the standard output.
+.PP
+The
+.B -u
+flag sets the target URL to
+.I url.
+.PP
+The
+.B -g
+and
+.B -p
+flags set the the form method to GET and POST, respectively. The
+.B -m
+flag sets the form method to POST and its enctype to multipart/form-data.
+In all cases, the form action is set to
+.I action.
+.PP
+The remaining arguments of the form
+.B name:value
+are interpreted as form field names and values to be submitted along
+with the form. An argument of the form
+.B name:@value
+is interpreted as a file upload, with the information following the
+.B @
+symbol treated as the full path to the location of the file.
+.SH EXAMPLES
+Retrieve the
+.I hget
+command needed to submit a form, which may then be
+edited and sent.
+.IP
+.EX
+% formpost -u http://p.intma.in
+hget -p 'text=' http://p.intma.in/paste.cgi
+.EE
+.PP
+Manually specify options to be sent to a given
+.I url.
+Note: The target HTML is not fetched and interpreted.
+.IP
+.EX
+% formpost -u http://p.intma.in -p paste.cgi 'text:test post'
+hget -p 'text=test+post' http://p.intma.in/paste.cgi
+.EE
.SH SOURCE
.B /rc/bin/hget
+.br
+.B /rc/bin/formpost
.SH "SEE ALSO"
-.IR webfs (4),
+.IR webfs (4) ,
.IR ftpfs (4)
.SH DIAGNOSTICS
.I Hget
@@ -84,3 +182,8 @@ requires
service mounted on
.B /mnt/web
to work.
+.SH BUGS
+.I Formpost
+does not attempt to insert default values for
+.B <select>
+tags.