> > Before I have a go at putting together a solution for this
> >myself, has anyone else already been there done that?
>
> That would be a valuable addition to JHP.
Well I've put something together that seems to work. It is very verbose
and certainly not as elegant as the rest of JHP, but hopefully it can
act as a starting point. Please feel free to tear it apart - I'm happy
to learn!
In its present form, uploaded files are parsed from stdin and saved into
the ~CGI/tmp folder. I'm not certain how I'd present this to the "user"
differently. Oleg, when you were talking about "presenting info to the
'user'" is the user the web-page designer, the web-page viewer, or the
JHP server administrator?
The changes I made to jhp.ijs were to extended qkeys yet further and to
add the verb qmparse:
qkeys=: 3 : 0
if. -.isnoun 'CGIKEYS' do.
select. env 'REQUEST_METHOD'
case. 'GET' do.
q=. env 'QUERY_STRING'
'CGIKEYS CGIVALS'=: a:"_`(<"1@|:)@.(0<#) qsparse q
case. 'POST' do.
q=. stdin ''
select. (]{.~';'i.~]) env 'CONTENT_TYPE'
case. 'application/x-www-form-urlencoded' do.
'CGIKEYS CGIVALS'=: a:"_`(<"1@|:)@.(0<#) qsparse q
case. 'multipart/form-data' do.
'CGIKEYS CGIVALS CGIISFL CGIFNMS CGICTPS'=:
a:"_`(<"1@|:)@.(0<#) qmparse q
case. do.
NB. signal invalid CONTENT_TYPE
end.
case. do.
NB. signal invalid Method
end.
end.
CGIKEYS
)
qmparse=: 3 : 0
(env 'CONTENT_TYPE') qmparse y
:
bd=. x ([}.~[:>:i.) '=' NB. get boundary
dat=. (#bd)}.each (bd E. y) <;.1 y NB. box each section
ndx=. {.each I. each (<CRLF,CRLF) E. each dat NB. find header/body
split
dat=. (0&<@:>ndx)#dat NB. drop out non-fields
ndx=. (0&<@:>ndx)# ndx
dat=. ndx split each dat NB. split header/body
hdrs=. 0{::each dat
dat=. 1{::each dat
s=. 'name='
ndx=. {.each I. each (<s) E. each hdrs NB. find string starts
ndx=. (<#s) + each ndx NB. add string lengths
keys=. ndx }.each hdrs NB. drop til after
keys=. (*./\each -. each keys e. each <';',CR)# each keys NB. drop
everything from ; or CR
keys=. keys-.each <'"' NB. remove "s
s=. 'filename='
ndx=. {.each I. each (<s) E. each hdrs
isfile=. 0&<@:>ndx NB. is section a file?
ndx=. (<#s) + each isfile#ndx
fnmes=. ndx }. each isfile#hdrs
fnmes=. (*./\each -. each fnmes e. each <';',CR)# each fnmes
fnmes=. fnmes-.each <'"'
s=. 'Content-Type: '
ndx=. {.each I. each (<s) E. each isfile#hdrs
ndx=. (<#s)+each ndx
contypes=. ndx }. each isfile#hdrs
contypes=. (*./\each -. each contypes e. each <';',CR)# each contypes
contypes=. contypes-.each <'" '
dat=. _4}.each 4}.each dat NB. drop 2CRLFs at start and CRLF-- at
end
fdat=. isfile#dat
dat=. fnmes (I.isfile) }dat NB. for files replace value with
filename
isfull=. 0&<@:>#each fdat
if. +./isfull do. NB. write files if data exists
tp=. jpath '~CGI/tmp/' NB. path for temp folder
NB. *** add handling of multiple users uploading similar filenames
fnmes=. (<tp), each isfull#fnmes NB. new filenames to write
b=. (isfull#fdat) fwrite each isfull#fnmes NB. write files to temp
folder
dat=. fnmes (isfull#I.isfile) }dat NB. if file data not empty,
replace dat with written filename
end.
fnmes=. isfile expand ,.fnmes
contypes=. isfile expand ,.contypes
keys,.dat,.(<@>isfile),.fnmes,.contypes
)
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm