Multipart form data

I’m trying to write a minimal wiki for fun. GET a page and you’re served its contents decorated in HTML with an “Edit” link. GET that “Edit” link and you’re served HTML forms offering file upload or text editing in an HTML textarea. Would be a great pedagogical project but I’m stuck on something simple…

I’ve found the multipart_form, multipart-form-data and http-multipart-formdata libraries but, thus far, failed to get anything working when a user uploads a file. The multipart_form library looks like the most promising one but, for some reason, when I give it the content-type from cohttp it rejects it with the error “Error ‘Non-terminating unstrctured form’ creating content type”. Despite the docs warning that it doesn’t work properly with files I tried the multipart-form-data library but it dies with the internal error “Invalid_argument iter_multipart” which appears to be a parse error at a “–” boundary. Finally I tried http-multipart-formdata but I couldn’t even figure out how to call its API.

Please can someone advise how I should proceed?

Also, I’ve developed cohttp+lwt, cohttp+async, httpaf+lwt and httpaf+async versions of this code trying to find any combination that works but to no avail, e.g. I switched from async to lwt because I saw multipart-form-data supports lwt and not async out-of-the-box. I also tried opium and ocsigen but found them overwhelming, e.g. the amount of new operators. What is the simplest way to write a minimal wiki in OCaml?

2 Likes

Try Dream, it’s pretty full-fledged: Dream — Tidy, feature-complete web framework

1 Like

when I give it the content-type from cohttp it rejects it with the error “Error ‘Non-terminating unstrctured form’ creating content type”

Hi, if you put ^ "\r\n" at the end of the content-type value, it should be fine :+1: . And yeah, the documentation is not clear about that, you can add an issue into the repository and I will be happy to improve the library.

4 Likes

I needed an upload form for my sticker-distributing endeavor 🐫 OCaml Stickers via 🐌 ✉️ – and didn’t accept any complexity not targeted at solving the task at hand.

So I used my https://mro.name/form2xhtml that can not only collect form posts with a mere 30-line bash script (dump.cgi), but also could extract e.g. the binaries from those posts. As I send letters with hand-written adresses on them, I need no other processing but the mere dump + cat + handwriting + rm.

1 Like

It works! Fantastic, thank you.

1 Like

Never heard of it but the worked examples look superb. Thanks!

2 Likes

As a general bit of advice when trying to deal with stuff like this:

  1. “wireshark” is your friend. When not in HTTPS, you can capture TCP streams, reassemble into text, and … well, yknow, see exactly what went over the wire.
  2. Perl and Python have extensive libraries: I often would just use one of those to do the analogous thing, and compare wirelines (again in wireshark) until I figured out what was wrong. This was back in the early Java days, but I’m sure the same would work for OCaml.
  3. IIRC, wireshark supports using certs, so if you have control of the server, you can decrypt SSL.
1 Like

No prob :slight_smile: Incidentally, here’s dinosaure’s trick in Dream: https://github.com/aantron/dream/blob/fa3cf53492cf23c1d315de83d458422b5efa92d3/src/middleware/upload.ml#L65

1 Like