urbit/pkg/garden/lib/multipart.hoon
fang 51f4c83352
multipart: more lenient content-type parsing
It's not uncommon for files to have mime types like `image/svg+xml`.
The + in there was tripping up the strictly-`@ta` parser for the content-type.

Here we change the parser to accept +, and all the other characters that the
`@t` parser accepts. This is perhaps a bit overkill, but we primarily care
about getting the parsed request to the caller. If any further validation is
required, it can happen upstream.

Fixes #5282.
2021-10-01 15:22:22 +02:00

50 lines
1.6 KiB
Plaintext

:: multipart: multipart/form-data request decoding
::
|%
+$ part
$: file=(unit @t) :: filename
type=(unit mite) :: content-type
code=(unit @t) :: content-transfer-encoding
body=@t :: content
==
::
++ de-request
|= [=header-list:http body=(unit octs)]
^- (unit (list [@t part]))
?~ body ~
?~ cot=(get-header:http 'content-type' header-list) ~
?. =('multipart/form-data; boundary=' (end 3^30 u.cot)) ~
%+ rush q.u.body
(dep (rsh 3^30 u.cot))
::
++ dep
|= del=@t
|^
%+ knee *(list [@t part]) |. ~+
;~ pose (cold ~ (full tip)) :: end, or
;~ pfix dim nip :: section start
;~ plug ;~ plug :: containing:
(ifix [cof doq] nom) :: name
(punt (ifix [cup doq] nod)) :: filename
(punt ;~(pfix nip cut nab)) :: content-type
(punt ;~(pfix nip cue nom)) :: con-tra-encoding
(ifix [sip nip] nag) :: content
== ^$ == == ==
::
++ cof (jest 'Content-Disposition: form-data; name="')
++ cue (jest 'Content-Transfer-Encoding: ')
++ cup (jest '; filename="')
++ cut (jest 'Content-Type: ')
++ dim (jest (cat 3 '--' del))
++ nip (jest '\0d\0a')
++ nab (more fas (cook (cury rap 3) (plus qit)))
++ nag (dine ;~(less ;~(plug nip dim) next))
++ nod (dine ;~(less doq next))
++ nom (dine alp)
++ sip ;~(plug nip nip)
++ tip ;~(plug dim hep hep nip)
::
++ dine |*(r=rule (cook (cury rep 3) (star r)))
--
--