3

I've seen multiple posts all over Internet about different methods, but still I didn't find a proper answer.

The problem: my CGI application is running in an embedded web server, the language I'm using is C, and what I'm trying to do is to process a file sent with a POST request of a form.

The application has been doing everything so far without the use of any libraries, but now I need to add this function and I don't really know which library can I use to do so. And doing it from scratch seems way too complicate for such a simple objective. Maybe not so much for the technical implications, but specially for the possible deviations between browsers.

Any advice about it?

EDIT: I want to be able to POST files from a browser, and I want to avoid the multipart content type, because it's overhead...

Community
  • 1
  • 1
opalenzuela
  • 3,139
  • 21
  • 41
  • -[This](http://stackoverflow.com/questions/8659808/how-does-http-file-upload-work)- may be a help, and rfc given as an answer there is a must-read. – VoidPointer Jul 23 '13 at 15:59
  • Yeah.. this is the difficult way I was expecting. Is there any other way, for instance using a third-party library that takes care of the boundaries? – opalenzuela Jul 23 '13 at 16:03
  • Try -[this](http://stackoverflow.com/questions/175507/c-c-web-server-library)- and -[this](http://stackoverflow.com/questions/1486818/c-c-any-good-web-server-library)-. Looks _SO_ has all answers within itself!! – VoidPointer Jul 23 '13 at 16:07
  • No, I don't need a webserver; I have a good one already. What I need is a lightweight CGI library to do the parameter processing for my application. – opalenzuela Jul 23 '13 at 16:09
  • Parameter parsing is as easy as converting the url encodings back to ascii, and looking for = signs. All stuff that is done easily with string.h. – KrisSodroski Jul 23 '13 at 16:12
  • Yes, it would be, if I could send several KB in the URL. But I can't, so I need to fall back to the multipart crap... :( – opalenzuela Jul 23 '13 at 16:14
  • If you're using POST, you're not sending it in the URL, that's already been told to you. Its being sent in the packet in the POST format described below. If you notice, the url below is /path/script.cgi, and lacks any variables/data in the url. All the data is in the data section (which is part of POst). So why can't you use POST? Apache by default is configured to accept 20 MB through post. If you wrote your own server, you can accept how ever much data you want. – KrisSodroski Jul 23 '13 at 16:15
  • Mmm, you are right. Do I need to specify any special parameters in the form to be sent this way? Do you have the html fragment of that sample form? Thanks! – opalenzuela Jul 23 '13 at 16:24
  • I've tried this method, and the browser refuses to send any file by POST if I'm not using the multipart. I've tried with Chrome and Firefox. Which browser are you using? EDIT: I see in another comment that you are using RAW sockets. Well, I'm afraid this cannot be used here... so the question is still unanswered. – opalenzuela Jul 24 '13 at 15:43

2 Answers2

2

To upload a file in a browser using <input type="file">, you must use enctype="multipart/form-data". This is not negotiable -- file inputs simply don't work with the default form encoding (application/x-www-form-urlencoded).

I'd strongly recommend using something like Perl's CGI module to parse the upload if you can. If you're absolutely stuck with C, though, you might want to try something like https://github.com/iafonov/multipart-parser-c.

  • Thank you. I wasn't sure, but now it's confirmed. So I will have a look at this parser, to see if it fits with our CGI. – opalenzuela Jul 25 '13 at 07:39
0

I've written a server that does just this. The packets you will receive from this post request will just be data. It will be formatted as POST, which means there will be some information like

HTTP: POST Some stuff like version Data: your data

You just scan till you see Data: or some header that denotes the post request, and then you copy this data. That will be your file/arguments/whatever is sent in post. It will not be in the url (which has its own header section)

Edit: Post Header example

 POST /path/script.cgi HTTP/1.0
 From: frog@jmarshall.com
 User-Agent: HTTPTool/1.0
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 32

 home=Mosby&favorite+flavor=flies  -> This is your data (this happens to be arguments home and favoriteflavor
KrisSodroski
  • 2,796
  • 3
  • 24
  • 39
  • Nice (and quick!). Could you provide some documents or examples about how to do it? – opalenzuela Jul 23 '13 at 15:55
  • 1
    I think file upload is little more complex than this. – VoidPointer Jul 23 '13 at 15:58
  • Its not. Its just appended to the POST data. I do it all the time. When the server sends you a file, all its doing is sending you data too. Same exact transport method on upload. If you send it in Get, you can even see the data in the url! – KrisSodroski Jul 23 '13 at 15:58
  • 1
    What if the file is several KBs long? It's also encoded in the URL? I need to send small files, but easily over 10KB. I'm afraid this solution might not work then :( – opalenzuela Jul 23 '13 at 16:00
  • No, there's a limit on the URL. If the file is small enough, you an send it as GET. If not, you must use POST or AJAX. You can configure accepted POST length on your server. If you're writing it using raw sockets (like I did), there's no limit on POSt except what your browser enforces (I wrote my own browser). If you're writing hte client side, you're the one creating the messages, which is as simple as creating an array with the correct headers above, appending the data to the right place, and then just reading it on the other side. Since its just a byte stream, the server side is easy – KrisSodroski Jul 23 '13 at 16:01
  • @Magn3s1um _AJAX_ is a technique and not kind of _HTTP method_ I afraid. – VoidPointer Jul 23 '13 at 16:09
  • So? He could still use it for file upload asynchronously. I do it all the time, and then I don't have to worry about http semantics, and can just send the file in any format/encoding that I want. Are you so offended by my mentioning it? – KrisSodroski Jul 23 '13 at 16:11