Yes, RabbitWeb can made some thing more easy. It enables a sort of server-side
scripting system like PHP in your Rabbit module. But it is memory and CPU-time
consuming. And web pages with forms must be resident inside the firmware (with
the #ximport directive) because they need to be processed by the server before
served to client who requests it. In this case "client" must be a web browser
application that display the page and then post back data to server.
In the other way, the cgi function acts like a sort of web service and client
should be a browser again but also a Java/Delphi/C# standalone client for remote
administration, for example.
At the end you should decide the way based on how you intend to send data and
how you process them then.
Reply by Tom Collins●May 9, 20132013-05-09
It sounds like you (original poster) might be going through a lot of unnecessary
work. Take a look at the RabbitWeb samples if you're dealing with forms,
and some of the HTTP Upload samples for file uploads.
There's a lot of code already in Dynamic C to make it easy to do forms and
uploads. Trying to reinvent that through the CGI interface will be difficult
and time consuming.
-Tom
Reply by markreds81●May 9, 20132013-05-09
It depends how data is encoded in the http form post. If the form mime type is
"application/x-www-form-urlencoded" the body of the request is one giant query
string (name/value pairs separated by the ampersand '&', and names
separated from values by equal '='). For example:
var1=value1&var2=value2&var3=value3
Values are encoded to be compatible with some special characters so you need to
decode. This is a HTTP specification so I suggest to search on the web for more
informations about this. Dynamic C libraries has http_urldecode().
Else if the mime type is multipart/form-data each field of the form is enclosed
between boundaries. In this case you can post binary data of an arbitrary
length.
In the CGI_DATA you can obtain the name of the field by the http_getField(),
value and its length in bytes by http_getData() and http_getDataLenth(). Take a
look in the Dynamic C TCP/IP Reference Manual Vol.2.
Response must be sent ONLY when you have received all data submitted from the
client because you have to write it on the same socket buffer (and if you write
on that buffer while client is still sending its data, it will lost your
response). So you should do this in CGI_EOF.
Read the Dynamic C TCP/IP Reference Manual Vol.2, more specifically the chapter
about HTTP server. You will find all that you need. The chapter introduces the
old style cgi, then talk about the new style for posting bynary data and save to
file (file uploading), but essentially it is the same: you have a HTTP form with
some fields with values (string, int, ecc, all treates as binary data). Encoding
is set by the client (mime parameter) but the Dynamic C HTTP library process all
this for you and call your function only when data are processed and ready to
you. It is your task how to interprete/save these values.
Reply by racqueldesign●May 9, 20132013-05-09
Thanks Mark,
But how under which http_getAction(state) action is data parse? Is it CGI_DATA?
Also do I respond to client under this same action? Example of http post data
is:
{
"sensor 2": 1,
"name": "contact sensor",
"username": "sandy",
"password": "access",
"msg": [{"update"}]
}
Reply by markreds81●May 9, 20132013-05-09
It depends how did you set your initialization. To enable cgi funtions (in the
new style, as your example) your have to:
1) #define USE_HTTP_UPLOAD
2) register the MIME type in your static table
3) register the function in the HTTP web server (with authentication, if you
want)
rc = 0;
switch (http_getAction(state)) {
case CGI_START:
// see manual reference for see what you can do here
break;
case CGI_DATA:
// here you get a chunk of data, you can process or save in local
buffer or FAT file
case CGI_END:
// end of POST data, see manual reference
break;
..
..
case CGI_EOF:
// when you finish, remember to send to client at least a
// header HTTP response (HTTP 1.0 200 OK). You can do this
// with this function, see HTTP.LIB
http_genHeader(state, http_getData(state), HTTP_MAXBUFFER, 200, NULL,
0, NULL);
// then tell to HTTP server that you have finished to process the
request and do not call this function anymore.
rc = CGI_SEND_DONE;
break;
}
return rc;
}
If you want you can also send to client an entire page or existing FAT file by
switching/redirecting to. You can also produce the entire response in another
cgi.
In your example you should return 0 only if you haven't finished to process
the request so the HTTP server will call your function again with another chunk
of data, or another state. But at the end return something else (1, CGI_DONE,
CGI_SEND_DONE...). Or else you client will wait until a socket time-out will
occurs.
I hope this can help you.
Reply by racqueldesign●May 8, 20132013-05-08
Hi,
I need help with uploading(maybe posting is the proper word) data to my HTTP
server. I have read the document on uploading files but this is a simple data
upload and the skeleton example isn't working me. Can someone please tell
me what I am doing wrong.
The HTTP Server doesn't have a webpage to accept FORM. It simple respond to
upload data. Example of the data in the body of the HTTP request i am require
to upload is :
{
"sensor 2": 1,
"name": "contact sensor",
"username": "sandy",
"password": "access",
"msg": [{"update"}]
}
--------------------skeleton example in the document-------------
int my_CGI(HttpState * s)
{
switch(http_getAction(s)) {
case CGI_START:
break;
case CGI_DATA:
break;
case CGI_END:
break;
case CGI_EOF:
break;
case CGI_ABORT:
break;
}
return 0;
}