Hello Nimians!
I'm well into making a CMS/site builder using Guildenstern, but i'm just now getting around to needing forms that upload files. I'm trying to use Guildenstern's streamingserver[1] and the receiveInChunks() iterator in an example program just to try and get it working. The Guildenstern examples stop short of actually showing you how to grab and save the file, AFAICT. If i echo the body(:string) of a POST request, i get something like this.
(This output is from an attempt without a file upload. If i would have added a file, in the second chunk it would have had a filename, a different Content-Type, and after that a bunch of gibberish which would have been the uploaded file itself (base64 encoded?).
-----------------------------416231406732801938054063358022
Content-Disposition: form-data; name="msg"
hello, nimians!
-----------------------------416231406732801938054063358022
Content-Disposition: form-data; name="file"; filename=""
Content-Type: application/octet-stream
-----------------------------416231406732801938054063358022--
Is there something in the standard library to parse this string "format" to grab the data i need? Or what approach would you take? I've always had a request object with fields in the past, so i'm not sure what i'm supposed to be looking into. :)
Thanks in advance
I don't know Guildenstern but what you see here is a "MIME" document, you could either find a mime parser, or you look into other webserver that already implement this:
https://github.com/guzba/mummy/blob/master/src/mummy/multipart.nim
thanks @enthusiast.
in an ideal world, shouldn't the std lib[1] have a parser for this mime doc type? It looks like rust has it[2]. I think i saw one for julia too. Or there's some reason it should be implemented by each http server project, or at the web framework level above the http server?
Multiparty body parsing is surprisingly hard to do because the format is so stupid. I would wrap or rewrite something like this https://github.com/iafonov/multipart-parser-c
This is something I'm going to implement in my parser lib, eventually
Go has one in the std lib: https://pkg.go.dev/mime/multipart
Python has one that is not server/framework specific: https://github.com/defnull/multipart
^ Temporary files on disk for big uploads.
PHP has a generic one as well: https://github.com/Riverline/multipart-parser
Hello (Guildenstern author here)
In my modest open source contributions, I am inspired by the "do one thing and do it well" -philosophy. I admit that it moves some complexity from maintainer to the user (you have to compose your own system).
Anyway, multipart/form data is a standard, so I agree that a decent HTTP server should support it out of the box. Where I draw the line is that Guildenstern will never include so called middleware features (routing etc.).
Now, the bad news is that I am quite busy with my real work duties, so I don't necessarily have the time to implement any particular feature soon (PR's welcome). Good news is that I am anyway eating our collective dog food on a daily basis (Nim in general, and Guildenstern in particular), so I definitely have a stake in all this ("all in" since Nim 0.13, you know...).
#[
What's in a name?
Guildenstern originates from Rosencrantz which comes from Jester which might be inspired by Nym. (I guess Shakespeare used a lot of puns in his plays)
]#
I'm glad to hear you are dogfooding Guildenstern and Nim. I'm now fairly invested in Guildenstern as well, as i just spent the last few months porting the beginnings of my current project to Guildenstern and working on it from there.
I think i prefer your philosophy for Guildenstern, even if it makes me a little nervous at times if i haven't implemented something from scratch before. I've already implemented (at POC state) routing, form input validation, form errors and old input, "flash" messages, cookie-based sessions and authentication with xsrf protection, and whatever else. I'm already using sqliteral for all my DB stuff in this app, thanks to your previous help with that. Now, i need to upload files locally, preferably in a way that scales for a multi-user app.
I see i asked you about this here: https://forum.nim-lang.org/t/10433#69528 and you said file upload works with streaming server. Maybe you were being more specific than i realized, because file upload does work, i just don't know how to parse it from the response and save it. My understanding is that i need to write, or use, some multipart parsing code for that, but maybe i just don't understand the Guildenstern examples fully. I've got some multipart info to read still, like the link you just posted.
I will follow up in the Guildenstern issue tracker (soon) for now. Thanks for the reply.