formpost becomes hpost
This commit is contained in:
parent
45c0c41280
commit
143fcc0a42
3 changed files with 246 additions and 243 deletions
191
rc/bin/formpost
191
rc/bin/formpost
|
@ -1,191 +0,0 @@
|
|||
#!/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
|
||||
}
|
207
rc/bin/hpost
Executable file
207
rc/bin/hpost
Executable file
|
@ -0,0 +1,207 @@
|
|||
#!/bin/rc
|
||||
rfork e
|
||||
argv0=$0
|
||||
url=()
|
||||
at=() # text fields
|
||||
af=() # file fields
|
||||
|
||||
fn usage {
|
||||
echo $argv0 '[ -u ] url [ -[gpm] action ] [ field:value | field@file ... ]' >[1=2]
|
||||
exit usage
|
||||
}
|
||||
|
||||
# tired of typing -u
|
||||
if(~ $1 http://* https://*){
|
||||
url=$1
|
||||
shift
|
||||
}
|
||||
|
||||
while(! ~ $#* 0){
|
||||
switch($1){
|
||||
case -u; shift; url=$1
|
||||
case -g; shift; action=$1; method=mget
|
||||
case -p; shift; action=$1; method=mpost
|
||||
case -m; shift; action=$1; method=multi
|
||||
case *:*@*; at=($1 $at)
|
||||
case *@*; af=($1 $af)
|
||||
case *:*; at=($1 $at)
|
||||
case *; usage
|
||||
}
|
||||
shift
|
||||
}
|
||||
|
||||
if(~ $#url 0)
|
||||
usage
|
||||
|
||||
fn uenc {
|
||||
f=$1
|
||||
for(i in $at){
|
||||
echo -n $"f`{urlencode /env/i | sed 's!%3A!=!; s!%00$!!'}
|
||||
f='&'
|
||||
}
|
||||
for(i in $af){
|
||||
echo -n $"f`{urlencode /env/i | sed 's!@.*$!=!'}
|
||||
urlencode `{sed 's!^[^@]+@!!' /env/i}
|
||||
f='&'
|
||||
}
|
||||
}
|
||||
fn menc {
|
||||
f=$1
|
||||
cr=`{echo x | tr x \015}
|
||||
for(i in $at){
|
||||
k=`{sed 's!:.*$!!' /env/i}
|
||||
echo '--'$"f$"cr
|
||||
echo 'Content-Disposition: form-data; name="'$"k'"'$"cr
|
||||
echo $"cr
|
||||
i=$"i$"cr
|
||||
sed 's!^[^:]+:!!' /env/i
|
||||
}
|
||||
for(i in $af){
|
||||
k=`{sed 's!@.*$!!' /env/i}
|
||||
v=`{sed 's!^[^@]+@!!' /env/i}
|
||||
t=`{file -m $v}
|
||||
n=`{basename $v}
|
||||
echo '--'$"f$"cr
|
||||
echo 'Content-Disposition: form-data; name="'$"k'"; filename="'$"n'"'$"cr
|
||||
echo 'Content-Type: '$"t$"cr
|
||||
echo $"cr
|
||||
cat $v
|
||||
echo $"cr
|
||||
}
|
||||
echo '--'$"f'--'$"cr
|
||||
}
|
||||
|
||||
fn mget {
|
||||
a=`{uenc '?'}
|
||||
action=$"action$"a
|
||||
hget -b $url $action
|
||||
}
|
||||
fn mpost {
|
||||
uenc | hget -b $url -P $action
|
||||
}
|
||||
fn multi {
|
||||
f='HJBOUNDARY'
|
||||
menc $"f | hget -r 'Content-Type: multipart/form-data, boundary='$"f -b $url -P $action
|
||||
}
|
||||
|
||||
if(! ~ $action ''){
|
||||
$method
|
||||
exit
|
||||
}
|
||||
|
||||
# serialize $at and $af into a0=... a1=... for awk
|
||||
# to preserve newlines and other special characters
|
||||
n=()
|
||||
for(i in $at $af){
|
||||
a$#n=$i
|
||||
n=(1 $n)
|
||||
}
|
||||
a$#n=''
|
||||
|
||||
hget $url | uhtml | sed '
|
||||
s!^(TAG|ATT)! \1!g; # escape our inline signaling
|
||||
s!<[ ]*!\nTAG !g; # find starttags, mark with TAG name ...
|
||||
s!>[^>"'']*$!!g; # remove garbage after the tag
|
||||
# find attributes, mark with ATT name value
|
||||
s!([a-zA-Z][a-zA-Z0-9:_]*)=("[^"]*"?|''[^'']*''?|[ ]*[^> ]+)!\nATT \1 \2!g;
|
||||
' | awk -v 'argv0='$"argv0 -v 'url='$"url '
|
||||
BEGIN{
|
||||
for(i=0; ENVIRON["a"i]!=""; i++){
|
||||
s=ENVIRON["a"i]
|
||||
x=index(s, ":"); y=index(s, "@")
|
||||
if(y > 1 && (x < 1 || x > y))
|
||||
x = y
|
||||
n=substr(s, 1, x-1)
|
||||
ainput[n]=substr(s, x+1, length(s))
|
||||
atypes[n]=substr(s, x, 1);
|
||||
}
|
||||
}
|
||||
function qw(s){
|
||||
if(s !~ /[\n\\#;\|\^$=`''{}\(\)<> ]/)
|
||||
return s
|
||||
gsub(/''/, "''''", s)
|
||||
return "''"s"''"
|
||||
}
|
||||
function uq(s){
|
||||
q=substr(s, 1, 1)
|
||||
if(q=="\"" || q=="''"){
|
||||
s=substr(s, 2, length(s))
|
||||
x=index(s, q)
|
||||
if(x > 0) s=substr(s,1,x-1)
|
||||
}
|
||||
return s
|
||||
}
|
||||
function emitform(){
|
||||
if(action!=""){
|
||||
printf argv0
|
||||
if(url!="") printf " -u %s", qw(url)
|
||||
if(method=="post"){
|
||||
if(enctype=="multipart/form-data")
|
||||
printf " -m %s", qw(action)
|
||||
else
|
||||
printf " -p %s", qw(action)
|
||||
} else
|
||||
printf " -g %s", qw(action)
|
||||
for(n in ainput)
|
||||
printf " %s%s%s", n, atypes[n], qw(ainput[n])
|
||||
for(n in input)
|
||||
if(!(n in ainput))
|
||||
printf " %s%s%s", n, types[n], qw(input[n])
|
||||
printf "\n"
|
||||
}
|
||||
delete input
|
||||
delete types
|
||||
action=""
|
||||
method=""
|
||||
enctype=""
|
||||
}
|
||||
function endtag(){
|
||||
if(tag=="form"){
|
||||
action=attr["action"]
|
||||
method=tolower(attr["method"])
|
||||
enctype=tolower(attr["enctype"])
|
||||
}
|
||||
if(tag=="select")
|
||||
selectname=attr["name"]
|
||||
if(tag=="option" && selectname!=""){
|
||||
if(attr["selected"]!=""){
|
||||
input[selectname]=attr["value"]
|
||||
selectname=""
|
||||
}
|
||||
}
|
||||
if(tag=="input" || tag=="textarea" || tag=="submit"){
|
||||
n=attr["name"]
|
||||
if(n!=""){
|
||||
if(tolower(attr["type"])=="file"){
|
||||
input[n]="/dev/null"
|
||||
types[n]="@"
|
||||
} else {
|
||||
input[n]=attr["value"]
|
||||
types[n]=":"
|
||||
}
|
||||
}
|
||||
}
|
||||
delete attr
|
||||
tag=""
|
||||
}
|
||||
/^TAG \//{
|
||||
etag=tolower(substr($2, 2, length(etag)-1))
|
||||
endtag()
|
||||
if(etag=="form")
|
||||
emitform()
|
||||
}
|
||||
/^TAG [^\/]/{
|
||||
endtag()
|
||||
tag=tolower($2)
|
||||
if(tag=="form")
|
||||
emitform()
|
||||
}
|
||||
/^ATT/{
|
||||
for(i=4; i<=NF; i++) $3=$3" "$i
|
||||
attr[tolower(uq($2))]=uq($3)
|
||||
}
|
||||
END{
|
||||
endtag()
|
||||
emitform()
|
||||
}
|
||||
'
|
|
@ -1,6 +1,6 @@
|
|||
.TH HGET 1
|
||||
.SH NAME
|
||||
hget, formpost \- retrieve, post to a web page corresponding to a url
|
||||
hget, hpost \- retrieve, post to a web page corresponding to a url
|
||||
.SH SYNOPSIS
|
||||
.B hget
|
||||
[
|
||||
|
@ -23,15 +23,12 @@ hget, formpost \- retrieve, post to a web page corresponding to a url
|
|||
]
|
||||
.I url
|
||||
.PP
|
||||
.B formpost
|
||||
.B hpost
|
||||
[
|
||||
.B -d
|
||||
] [
|
||||
.B -M
|
||||
] [
|
||||
.B -u
|
||||
]
|
||||
.I url
|
||||
] [
|
||||
[
|
||||
.B -g
|
||||
.I action
|
||||
] [
|
||||
|
@ -43,7 +40,7 @@ hget, formpost \- retrieve, post to a web page corresponding to a url
|
|||
] [
|
||||
.I name:value
|
||||
|
|
||||
.I name:@value
|
||||
.I name@file
|
||||
]
|
||||
.I ...
|
||||
.SH DESCRIPTION
|
||||
|
@ -97,39 +94,33 @@ Option
|
|||
.B -m
|
||||
overrides the HTTP method used for the request.
|
||||
.PP
|
||||
.I Formpost
|
||||
.I Hpost
|
||||
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
|
||||
.IR rc (1)
|
||||
commands to submit the forms with default field
|
||||
values.
|
||||
If an
|
||||
.I action
|
||||
URL is provided with the
|
||||
.B -g, -p
|
||||
or
|
||||
.B -m
|
||||
flags are set, the
|
||||
flags, then
|
||||
.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.
|
||||
is invoked to execute the transaction submitting the form data.
|
||||
.PP
|
||||
The
|
||||
.B -u
|
||||
flag sets the target URL to
|
||||
.I url.
|
||||
As the
|
||||
.I url
|
||||
parameter is always required, it can be optionally specified
|
||||
in the first argument without the
|
||||
.B -u
|
||||
flag.
|
||||
.PP
|
||||
The
|
||||
.B -g
|
||||
|
@ -137,49 +128,50 @@ and
|
|||
.B -p
|
||||
flags set 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
|
||||
flag sets the form method to POST and its enctype to
|
||||
.B multipart/form-data.
|
||||
In all cases, the form action URL 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. An
|
||||
are interpreted as text form field names and values to be submitted. An
|
||||
argument of the form
|
||||
.B name:@value
|
||||
.B name@file
|
||||
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
|
||||
Download a file from the web.
|
||||
.IP
|
||||
.EX
|
||||
% hget http://9front.org/img/nix-on.jpg >/tmp/nix-on.jpg
|
||||
.EE
|
||||
.PP
|
||||
Retrieve the commands 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
|
||||
% hpost http://p.intma.in
|
||||
/bin/hpost -u http://p.intma.in -p paste.cgi text:
|
||||
.EE
|
||||
.PP
|
||||
Manually specify options to be sent to a given
|
||||
Manually specify fields to be sent to a given
|
||||
.I url.
|
||||
.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
|
||||
% hpost -u http://p.intma.in -p paste.cgi text:'test post'
|
||||
.EE
|
||||
.PP
|
||||
Upload a file.
|
||||
.IP
|
||||
.EX
|
||||
% formpost -M file:@/tmp/screen.png | \\
|
||||
hget -P \\
|
||||
-r 'Content-Type: multipart/form-data, boundary=HJBOUNDARY' \\
|
||||
http://i.intma.in/up.cgi
|
||||
% hpost http://i.intma.in file@/tmp/screen.png | rc >/dev/null
|
||||
.EE
|
||||
.SH SOURCE
|
||||
.B /rc/bin/hget
|
||||
.br
|
||||
.B /rc/bin/formpost
|
||||
.B /rc/bin/hpost
|
||||
.SH "SEE ALSO"
|
||||
.IR webfs (4) ,
|
||||
.IR ftpfs (4)
|
||||
|
@ -190,8 +182,3 @@ requires
|
|||
service mounted on
|
||||
.B /mnt/web
|
||||
to work.
|
||||
.SH BUGS
|
||||
.I Formpost
|
||||
does not attempt to insert default values for
|
||||
.B <select>
|
||||
tags.
|
||||
|
|
Loading…
Reference in a new issue