An HTTP (Hypertext Transfer Protocol) server makes HTML (Hypertext Markup Language) documents and other documents available to clients, i.e., web browsers. HTTP is implemented by
HTTP.LIB.4.1 HTTP Server Data Structures
There are four data structures in
HTTP.LIBof interest to developers of HTTP servers.4.1.1 HttpSpec
The data structure
HttpSpeccontains all the files, variables, and functions the Web server has access to. The structureServerSpecfromZSERVER.LIBmay be instead.
typedef struct {
word type;
char name[HTTP_MAXNAME];
long data;
void* addr;
word vartype;
char* format;
HttpRealm* realm;
} HttpSpec;
4.1.1.1 HttpSpec fields
type
This field tells the server if the entry is a file, variable or function (
HTTPSPEC_FILE,HTTPSPEC_VARIABLEorHTTPSPEC_FUNCTION, respectively).name
This field specifies a unique name for referring to the entry. The Web server recognizes "
/index.html" as the entity that matches "http://someurl.com/index.html", and delivers the entry's content based on the value oftype(the first field).data
The third field is the physical address of the entity.
addr
The fourth field is a short pointer to the entity. Either the third field or the fourth field is valid, not both. All files must use the physical address, variables and functions use the short pointer.
vartype
This field describes the type of variable. Supported types are :
INT8INT16,PTR16,INT32, andFLOAT32.format
The format field describes the
printfformat specifier used to display the variable.realm
This field is the name and password required to access the entity.
4.1.2 HttpType
The structure
HttpTypeassociates a file extension with a MIME type (Multipurpose Internet Mail Extension) and a function which handles the MIME type. Users can overrideHTTP_MAXNAME(which defaults to 20 characters) in their source file.If the function pointer given isNULL, then the default handler (which sends the content verbatim) is used.
typedef struct {
char extension[10];
char type[HTTP_MAXNAME];
int (*fptr)(/* HttpState* */);
} HttpType;
4.1.3 HttpRealm
The structure
HttpRealmholds user-ID and password pairs for partitions called realms. These realms allow the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database.
typedef struct {
char username[HTTP_MAXNAME];
char password[HTTP_MAXNAME];
char realm[HTTP_MAXNAME];
} HttpRealm;
HTTP/1.0 Basic authentication is used. This scheme is not a secure method of user authentication across an insecure network (e.g., the Internet). HTTP/1.0 does not, however, prevent additional authentication schemes and encryption mechanisms from being employed to increase security.
In the
HttpSpecstructure, there is a pointer to a structure of typeHttpRealm. To password-protect the entity, add the name, password, and realm desired. If you do not want to password-protect the entity, leave the realm pointer in theHttpSpecstructureNULL.4.1.4 HttpState
Use of this structure is necessary for CGI functions. Some of the fields are off-limits to developers. The field that are available for use are described in Section 4.1.4.1 HttpState Fields.
4.1.4.1 HttpState Fields
The fields discussed here are available for developers to use in their application programs.
s
This is the socket associated with the given HTTP server. A developer can use this in a CGI function to output dynamic data. Any of the TCP functions can be used.
substate
subsubstateThese are intended to be used to hold the current state of a state machine for a CGI function. That is, if a CGI function relinquishes control back to the HTTP server, then the values in these variables will be preserved for the next
http_handler()call, in which the CGI function will be called again. These variables are initialized to 0 before the CGI function is called for the first time. Hence, the first state of a state machine using substate should be 0.timeout
This value can be used by the CGI function to implement an internal timeout.
main_timeout
This value holds the timeout that is used by the web server. The web server checks against this timeout on every call of
http_handler(). When the web server changes states, it resetsmain_timeout. When it has stayed in one state for too long, it cancels the current processing for the server and goes back to the initial state. Hence, a CGI function may want to reset this timeout if it needs more processing time (but care should be taken to make sure that the server is not locked up forever). This can be achieved like this:
state->main_timeout = set_timeout(HTTP_TIMEOUT);HTTP_TIMEOUTis the number of seconds until the web server will time out. It is 16 seconds by default.buffer[]
A buffer that the developer can use to put data to be transmitted over the socket. It is of size
HTTP_MAXBUFFER.p
Pointer into the buffer given above.
method
This should be treated as read-only. It holds the method by which the web request was submitted. The value is either
HTTP_METHOD_GETorHTTP_METHOD_POST, for the GET and POST request methods, respectively.url[]
This should be treated as read-only. It holds the URL by which the current web request was submitted. . If there is GET-style form information, then that information will follow the first
NULLbyte in the url array. The form information will itself beNULL-terminated. If the information in the url array is truncated toHTTP_MAXURLbytes, the truncated information is alsoNULL-terminated.version
This should be treated as read-only. This holds the version of the HTTP request that was made. It can be
HTTP_VER_09,HTTP_VER_10, orHTTP_VER_11for 0.9, 1.0, or 1.1 requests, respectively.content_type[]
This should be treated as read-only. This buffer holds the value from the Content-Type header sent by the client.
content_length
This should be treated as read-only. This variable holds the length of the content sent by the client. It matches the value of the Content-Length header sent by the client.
has_form
This should be treated as read-only. If the value is 1 there is a GET style form, after the \0 byte in
url[].abort_notify
Set to
!0in user-defined formprolog function to indicate that the formepilog function needs to be called on an abort condition. If the epilog function is reached normally, this field must be set to zero. This prevents the formepilog function from being called one more time on a connection abort.cancel
This should be treated as read-only. It is intended for when the user-defined functions, which may be called before and after an HTML form is submitted, are used for locking resources.
If the formprolog function was called and then the connection is aborted before the formepilog function can be called,
cancelis set to 1 and the formepilog function is called exactly once. If the epilog function was already called but returned zero (not finished yet), then it is called again if the connection is aborted, except ifcgi_redirectto()has been called from the epilog function. In that case the epilog function is not called after an abort.username[]
Read-only buffer has username of the user making the request, if authentication took place.
password[]
Read-only buffer has password of the user making the request, if authentication took place.
cookie[]
Read-only buffer contains the value of the cookie "DCRABBIT" (see
http_setcookie()for more information).headerlen
headeroffThese variables can be used together to cause the web server to flush data from the
buffer[]array in theHttpStatestructure.headerlenshould be set to the amount of data inbuffer[], andheaderoffshould be set to 0 (to indicate the offset into the array). The next time the CGI function is called the data inbuffer[]will be flushed to the socket.cond[]
Support for conditional SSI (error feedback etc).
userdata[]
This field is included if
HTTP_USERDATA_SIZEis defined. It is an optional user data area. The area is cleared to zero when the structure is initialized, otherwise it is not touched. Its size must be greater than zero.4.2 Configuration Macros
The following macros are available in
HTTP.LIB:HTTP_MAX_COND
Support for conditional SSI (error feedback etc). It defaults to 4.
HTTP_MAXNAME
This is the maximum length for a name in the
HttpSpecstructure. This defaults to 20 characters. Without overriding this value, the maximum length of any name is 19 characters because one character is used for theNULLtermination.HTTP_MAXRAMSPEC
This is the maximum number of
HttpSpecentries that can be added at runtime. This macro overridesSSPEC_MAXSPEC.HTTP_MAXSERVERS
This is the maximum number of HTTP servers listening on port 80. The default is two. You may increase this value to the maximum number of independent entities on your page. For example, for a Web page with four pictures, two of which are the same, set
HTTP_MAXSERVERSto four: one for the page, one for the duplicate images, and one for each of the other two images. By default, each server takes 2500 bytes of RAM. This RAM usage can be changed by the macroSOCK_BUF_SIZE(ortcp_MaxBufSizewhich is deprecated as of Dynamic C ver. 6.57). Another option is to use thetcp_reserveport()function and a smaller number of sockets.HTTP_PORT
This macro allows the user to override the default port. Define it before the line
#use http.lib.HTTP_USERDATA_SIZE
Defining this macro causes "char userdata[]" to be added to the HttpState structure. Define your structure before
#use http.libstruct UserStateData { char name[50]; int floor; int model; };
#define HTTP_USERDATA_SIZE (sizeof(struct UserStateData))
#use http.libIn your own code, access it like:
mystate = (struct UserStateData *) state->userdata;TIMEZONE
This macro specifies the distance in hours you are from Coordinated Universal Time (UTC), which is 5 hours ahead of Eastern Standard Time (EST). The default
TIMEZONEis -8, which represents Pacific Standard Time. You can use thetm_wr()function to set the clock to the correct value. If you lose power and don't have the battery-backup option, the time will need to be reset.4.2.1 Customizing HTTP headers
The callback macro,
HTTP_CUSTOM_HEADERS, will be called whenever HTTP headers are being sent. To be used, it must be defined as a function with the following prototype:void my_headers(HttpState* state, char* buffer, int bytes);state
Pointer to the state structure for the calling web server.
buffer
The buffer in which the header(s) can be written.
bytes
The number of bytes available in the buffer.
Typically, the macro would be defined by the user before
http.libis used, like in the following:#define HTTP_CUSTOM_HEADERS(state, buffer, bytes) \
my_headers(state, buffer, bytes)Then, for the above to work, the
my_headers()function must be defined by the user, like the following:void my_headers(HttpState* state, char* buffer, int bytes)
{
strcpy(buffer, "Fake-Header: Hello Z-World!\r\n");
printf("bytes: %d\n", bytes);
}Of course, in the real world, the user may need to check the number of bytes available to be sure they don't overwrite the buffer. The buffer must end with "\r\n", and be
NULL-terminated.4.3 Sample Programs
Sample programs demonstrating HTTP are in the
\Samples\Tcpip\Httpdirectory. There is a configuration block at the beginning of each sample program. Unless you are using BOOTP/DHCP, the macros in this block need to be changed to reflect your network settings. For most HTTP programs, you will be concerned withTIMEZONEand the IP address macros:MY_IPADDRESS,MY_NETMASK,MY_GATEWAY.4.3.1 Serving Static Web Pages
The sample program,
Static.c, initializesHTTP.LIBand then sets up a basic static web page. It is assumed you are on the same subnet as the controller. The code forStatic.cis explained in the following pages.From Dynamic C, compile and run the program. You will see the LNK light on the board come on after a couple of seconds. Point your internet browser at the controller (e.g., http://10.10.6.100/). The ACT light will flash a couple of times and your browser will display the page.
Program Name: Static.c
This program serves the
static.htmlfile and therabbit1.giffile to any user contacting the controller. If you want to change the file that is served by the controller, modify this line inStatic.c:
#ximport "samples/tcpip/http/pages/static.html" index_html4.3.1.1 Adding Files to Display
Adding additional files to the controller to serve as web pages is slightly more complicated. First, add an
#ximportline with the filename as the first parameter, and a symbol that references it in Dynamic C as the second parameter.
#ximport "samples/tcpip/http/pages/static.html" index_html
#ximport "samples/tcpip/http/pages/newfile.html" newfile_htmlNext, find these lines in
Static.c:Insert the name of your new file, preceded by "/", into this structure, using the same format as the other lines. Compile and run the program. Open up your browser to the new page (e.g. "http://10.10.6.100/newfile.html"), and your new page will be displayed by the browser.
4.3.1.2 Adding Files with Different Extensions
If you are adding a file with an extension that is not html or gif, you will need to make an entry in the
HttpTypestructure for the new extension. The first field is the extension and the second field describes the MIME type for that extension. You can find a list of MIME types at:ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/media-typesIn the media-types document located there, the text in the type column would precede the "/", and the subtype column would directly follow. Find the type subtype entry that matches your extension and add it to the
http_typestable.
HttpType http_types[] =
{
{ ".html", "text/html", NULL},
{ ".gif", "image/gif", NULL}
};
4.3.1.3 Handling of Files With No Extension
The entry "/" and files without an extension are dealt with by the handler specified in the first entry in
http_types[].4.3.2 Dynamic Web Pages Without HTML Forms
Serving a dynamic web page without the use of HTML forms is done by sample program
ssi.c. This program displays four 'lights' and four buttons to toggle them. Users can browse to the device and change the status of the lights.Program Name: samples/tcpip/http/ssi.c
Program Name: ssi.c (continued)
Program Name: ssi.c (continued)
When you compile and run
ssi.c, you see the LNK light on the board come on. Point your browser at the controller (e.g., http://10.10.6.100/). The ACT light will flash a couple of times and your browser will display the page.This program displays pictures of LEDs. Their state is toggled by pressing the image of a BUTTON. This program uses Server Side Includes (SSI) and the Common Gateway Interface (CGI).
4.3.2.1 SSI Feature
SSI commands are an extension of the HTML comment command (<!--This is a comment -->). They allow dynamic changes to HTML files and are resolved at the server side, so the client never sees them. HTML files that need to be parsed because they contain SSI commands, are recognized by the HTTP server by the file extension shtml.
The supported SSI commands are:
They are used by inserting the command into an HTML file:
<!--#include file="anyfile" -->The server replaces the command,
#include file, with the contents ofanyfile.
#exec cmdexecutes a command and replaces the SSI command with the output.Dynamically changing a variable on a web page
The
Ssi.shtmlfile, located in the/Samples/Tcpip/Http/Pagesfolder, gives an example of dynamically changing a variable on a web page using#echo var.
<img SRC="<!--#echo var="led1" -->">
In an shtml file, the "
<!--#echo var="led1" -->" is replaced by the value of the variableled1from thehttp_flashspecstructure.
HttpSpec http_flashspec[] =
{
//...
{ HTTPSPEC_VARIABLE, "led1", 0, led1, PTR16, "%s", NULL}
//...
};
shtml_handlerlooks upled1and replaces it with the text output from:
printf("%s",(char*)led1);
The
led1variable is eitherledon.giforledoff.gif.When the browser loads the page, it replaces
<img SRC="<!--#echo var="led1"-->">This causes the browser to load the appropriate image file.
4.3.2.2 CGI Feature
Ssi.calso demonstrates the Common Gateway Interface. CGI is a standard for interfacing external applications with HTTP servers. Each time a client requests an URL corresponding to a CGI program, the server will execute the CGI program in real-time.For increased flexibility, a CGI function is responsible for outputting its own HTTP headers. Information about HTTP headers can be found at:
http://deesse.univ-lemans.fr:8003/Connected/RFC/1945/In the
Ssi.shtmlfile, this line creates the clickable button viewable from the browser.
<TD> <A HREF="/led1tog.cgi"> <img SRC="button.gif"> </A> </TD>
When the user clicks on the button, the browser will request the
/led1tog.cgientity. This causes the HTTP server to examine the contents of thehttp_flashspecstructure looking for/led1tog.cgi. It finds it and notices thatled1toggle()needs to be called.The
led1togglefunction changes the value of theled1variable, then redirects the browser back to the original page. When the original page is reloaded by the browser, the LED image will have changed states to reflect the user's action.4.3.2.2.1 Connection Abort Condition
There are two fields in the
HttpStatestructure that allow a CGI function to appropriately respond to a connection abort condition. The user may set the fieldabort_notifyto!0in a CGI function to request that the CGI function be called one more time with thecancelfield set to one if a connection abort occurs.4.3.3 Web Pages With HTML Forms
With a web browser, HTML forms enable users to input values. With a CGI program, those values can be sent back to the server and processed. The FORM and INPUT tags are used to create forms in HTML.
The FORM tag specifies which elements constitute a single form and what CGI program to call when the form is submitted. The FORM tag has an option called ACTION. This option defines what CGI program is called when the form is submitted (when the "Submit" button is pressed). The FORM tag also has an option called METHOD that defines the method used to return the form information to the web server. In Section 4.3.3.1, "Sample HTML Page," on page 187, the POST method is used, which will be described later. All of the HTML between the <FORM> and </FORM> tags define what is contained within a form.
The INPUT tag defines a specific form element, the individual input fields in a form. For example, a text box in which the user may type in a value, or a pull-down menu from which the user may choose an item. The TYPE parameter defines what type of input field is being used. In the following example, in the first two cases , it is the text input field, which is a single-line text entry box. The NAME parameter defines what the name of that particular input variable is, so that when the information is returned to the server, then the server can associate it with a particular variable. The VALUE parameter defines the current value of the parameter. The SIZE parameter defines how long the text entry box is (in characters).
At the end of the HTML page in our example, the Submit and Reset buttons are defined with the INPUT tag. These use the special types "submit" and "reset", since these buttons have special purposes. When the submit button is pressed, the form is submitted by calling the CGI program "
myform".4.3.3.1 Sample HTML Page
An HTML page that includes a form may look like the following:
<HTML>
<HEAD><TITLE>ACME Thermostat Settings</TITLE></HEAD>
<BODY>
<H1>ACME Thermostat Settings</H1>
<FORM ACTION="myform.html" METHOD="POST">
<TABLE BORDER>
<TR>
<TD>Name</TD>
<TD>Value</TD>
<TD>Description</TD>
</TR><TR>
<TD>High Temp</TD>
<TD><INPUT TYPE="text" NAME="temphi" VALUE="80"
SIZE="5"></TD>
<TD>Maximum in temperature range (°F)</TD>
</TR><TR>
<TD>Low Temp</TD>
<TD><INPUT TYPE="text" NAME="templo" VALUE="65"
SIZE="5"></TD>
<TD>Minimum in temperature range (°F)</TD>
</TR></TABLE>
<P>
<INPUT TYPE="submit" VALUE="Submit">
<INPUT TYPE="reset" Value="Reset"></FORM></BODY>
</HTML>The form might display as follows:
When the form is displayed by a browser, the user can change values in the form. But how does this changed data get back to the HTTP server? By using the HTTP
POSTcommand. When the user presses the "Submit" button, the browser connects to the HTTP server and makes the following request:POST myform HTTP/1.0
.
. (some header information)
.
Content-Length: 19where "
myform" is the CGI program that was specified in the ACTION attribute of the FORM tag andPOSTis the METHOD attribute of the FORM tag. "Content-Length" defines how many bytes of information are being sent to the server (not including the request line and the headers).Then, the browser sends a blank line followed by the form information in the following manner:
temphi=80&templo=65That is, it sends back name and value pairs, separated by the `&' character. (There can be some further encoding done here to represent special characters, but we will ignore that in this explanation.) The server must read in the information, decode it, parse it, and then handle it in some fashion. It will check the validity of the new values, and then assign them to the appropriate C variable if they are valid.
4.3.3.2 POST-style form submission
If an HTML file specifies a POST-style form submission (i.e.,
METHOD="POST"), the form will still be waiting on the socket when the CGI handler is called. Therefore, it is the job of the CGI handler to read this data off the socket and parse it in a meaningful way. The sample filesPost.candPost2.cin the\Samples\Tcpip\Httpfolder show how to do this.The HTTP
POSTcommand can put any kind of data onto the network. There are many known encoding schemes currently used, but we will only look at URL-encoded data in this document. Other encoding schemes can be handled in a similar manner.4.3.3.3 URL-encoded Data
URL-encoded data is of the form "name1=value1&name2=value2," and is similar to the CGI form submission type passed in normal URLs. This has to be parsed to
name=valuepairs. The rest of this section details an extensible way to do this.
This initializes two possible HTML form entries to be received, and a place to store the results.
#define MAX_FORMSIZE 64
typedef struct {
char *name;
char value[MAX_FORMSIZE];
} FORMType;
FORMType FORMSpec[2];
void init_forms(void) {
FORMSpec[0].name = "user_name";
FORMSpec[1].name = "user_email";
}Reading & Storing URL-encoded Data
parse_post()reads URL-encoded data off the network. and callsparse_token()to store the data inFORMSpec[]. These code snippets are from/samples/tcpip/http/post.c.
4.3.3.4 Sample of a CGI Handler
This next function is the CGI handler. It is a state-machine-based handler that generates the page. It calls
parse_post()and references the structure that is now filled with the parsed data we wanted. This function is from/samples/tcpip/http/post.c.4.3.4 HTML Forms Using Zserver.lib
In this section, we will step through an example program,
/samples/tcpip/http/form1.c, that uses HTML forms. Through this step-by-step explanation, the method of using the functions inzserver.libwill become clearer.These lines are part of the standard TCP/IP configuration. You must change them to whatever your local IP address and netmask are. Contact your network administrator for these numbers.
#define MY_IP_ADDRESS "10.10.6.112"
#define MY_NETMASK "255.255.255.0"
Defining
FORM_ERROR_BUFis required in order to use the HTML form functionality inZserver.lib. The value represents the number of bytes that will be reserved in root memory for the buffer which will be used for form processing. This buffer must be large enough to hold the name and value for each variable, plus four bytes for each variable. Since we are building a small form, 256 bytes is sufficient.
#define FORM_ERROR_BUF 256
Since we will not be using the
http_flashspecarray, then we can define the following macro, which removes some code for handling this array from the web server.
#define HTTP_NO_FLASHSPEC
These lines are part of the standard TCP/IP configuration.
#memmap xmem
#use "dcrtcp.lib"
#use "http.lib"const HttpType http_types[] =
{
{ ".html", "text/html", NULL}
};
These are the declarations of the variables that will be included in the form.
int temphi;
int tempnow;
int templo;
float humidity;
char fail[21];
An array of type
FormVarmust be declared to hold information about the form variables. Be sure to allocate enough entries in the array to hold all of the variables that will go in the form. If more forms are needed, then more of these arrays can be allocated.
FormVar myform[5];
These variables will hold the indices in the TCP/IP servers' object list for the form and the form variables.
int var;
int form;
This array holds the possible values for the fail variable. The fail variable will be used to make a pulldown menu in the HTML form.
const char* const fail_options[] = {
"Email",
"Page",
"Email and page",
"Nothing"
};
These lines initialize the form variables.
temphi = 80;
tempnow = 72;
templo = 65;
humidity = 0.3;
strcpy(fail, "Page");
The next line adds a form to the TCP/IP servers' object list. The first parameter gives the name of the form. Hence, when a browser requests the page "
myform.html", the HTML form is generated and presented to the browser. The second parameter gives the developer-declared array in which form information will be saved. The third parameter gives the number of entries in themyformarray (this number should match the one given in themyformdeclaration above). The fourth parameter indicates that this form should only be accessible to the HTTP server, and not the FTP server.SERVER_HTTPshould always be given for HTML forms. The return value is the index of the newly created form in the TCP/IP servers' object list.
form = sspec_addform("myform.html", myform, 5, SERVER_HTTP);
This line sets the title of the form. The first parameter is the form index ( the return value of
sspec_addform()), and the second parameter is the form title. This title will be displayed as the title of the HTML page and as a large heading in the HTML page.
sspec_setformtitle(form, "ACME Thermostat Settings");
The following line adds a variable to the TCP/IP servers' object list. It must be added to the TCP/IP servers' object list before being added to the form. The first parameter is the name to be given to the variable, the second is the address of the variable, the third is the type of variable (this can be
INT8,INT16,INT32,FLOAT32, orPTR16), the fourth is a printf-style format specifier that indicates how the variable should be printed, and the fifth is the server for which this variable is accessible. The return value is the index of the variable in the TCP/IP servers' object list.
var = sspec_addvariable("temphi", &temphi, INT16, "%d", SERVER_HTTP);
The following line adds a variable to a form. The first parameter is the index of the form to add the variable to ( the return value of
sspec_addform()), and the second parameter is the index of the variable ( the return value ofsspec_addvariable()). The return value is the index of the variable within the developer-declaredFormVararray,myform.
var = sspec_addfv(form, var);
This function sets the name of a form variable that will be displayed in the first column of the form table. If this name is not set, it defaults to the name for the variable in the TCP/IP servers' object list ("temphi", in this case). The first parameter is the form in which the variable is located, the second parameter is the variable index within the form, and the third parameter is the name for the form variable.
sspec_setfvname(form, var, "High Temp");
This function sets the description of the form variable, which is displayed in the third column of the form table.
sspec_setfvdesc(form, var, "Maximum in temperature range
(60 - 90 °F)");
This function sets the length of the string representation of the form variable. In this case, the text box for the form variable in the HTML form will be 5 characters long. If the user enters a value longer than 5 characters, the extra characters will be ignored.
sspec_setfvlen(form, var, 5);
This function sets the range of values for the given form variable. The variable must be within the range of 60 to 90, inclusive, or an error will be generated when the form is submitted.
sspec_setfvrange(form, var, 60, 90);
This concludes setting up the first variable. The next five lines set up the second variable, which represents the current temperature.
Since the value of the second variable should not be modifiable via the HTML form (by default variables are modifiable,) the following line is necessary and makes the given form variable read-only when the third parameter is 1. The variable will be displayed in the form table, but can not be modified within the form.
sspec_setfvreadonly(form, var, 1);
These lines set up the low temperature variable. It is set up in much the same way as the high temperature variable.
This code begins setting up the string variable that specifies what to do in case of air conditioning failure. Note that the variable is of type
PTR16, and that the address of the variable is not given tosspec_addvariable(), since the variablefailalready represents an address.This line associates an option list with a form variable. The third parameter gives the developer-defined option array, and the fourth parameter gives the length of the array. The form variable can now only take on values listed in the option list.
sspec_setfvoptlist(form, var, fail_options, 4);
This function sets the type of form element that is used to represent the variable. The default is
HTML_FORM_TEXT, which is a standard text entry box. This line sets the type toHTML_FORM_PULLDOWN, which is a pull-down menu.
sspec_setfventrytype(form, var, HTML_FORM_PULLDOWN);
Finally, this code sets up the last variable. Note that it is a float, so
FLOAT32is given in thesspec_addvariable()call. The last function call issspec_setfvfloatrange()instead ofsspec_setfvrange(), since this is a floating point variable.
These calls create aliases in the TCP/IP servers' object list for the HTML form. That is, the same form can now be generated by requesting "
index.html" or "/". Note thatsspec_aliasspec()should be called after the form has already been set up. The aliasing is done by creating a new entry in the TCP/IP servers' object list and copying the original entry into the new entry. Note that aliasing can also be done for files and other types of server objects.
sspec_aliasspec(form, "index.html");
sspec_aliasspec(form, "/");
These lines complete the sample program. They initialize the TCP/IP stack and web server, and run the web server.
sock_init();
http_init();
while (1) {
http_handler();
}
}
This is the form that is generated:
4.4 Function Reference
cgi_redirectto
void cgi_redirectto(HttpState* state, char* url);Description
This utility function may be called in a CGI function to redirect the user to another page. It sends a user to the URL stored in
url. You should immediately issue a "return 0;" after calling this function. The CGI is considered finished when you call this, and will be in an undefined state.Parameters
state
Current server struct, as received by the CGI function.
url
Fully qualified URL to redirect to.
Return value
None - sets the state, so the CGI must immediately return with a value of
0.Library
See also
cgi_sendstring
void cgi_sendstring(HttpState* state, char* str);Description
Sends a string to the user. You should immediately issue a "
return 0;" after calling this function. The CGI is considered finished when you call this, and will be in an undefined state. This function greatly simplifies a CGI handler because it allows you to generate your page in a buffer, and then let the library handle writing it to the network.Parameters
state
Current server struct, as received by the CGI function.
str
Return value
None - sets the state, so the CGI must immediately return with a value of
0.Library
See also
http_addfile
int http_addfile(char* name, long location);Description
Adds a file to the TCP/IP servers' object list.
Parameters
name
Name of the file (e.g., "
/index.html").location
Address of the file data. (from
#ximport)Return value
Library
See also
http_contentencode
char *http_contentencode(char *dest, const char *src, int len);Description
Converts a string to include HTTP transfer-coding ''tokens'' (such as @ (decimal) for at-sign) where appropriate. Encodes these characters: ''<>@%#&''
Source string is
NULL-byte terminated. Destination buffer is bounded bylen. This function is reentrant.Parameters
dest
Buffer where encoded string is stored.
src
Buffer holding original string (not changed)
len
Return value
dest: There was room for all conversions.NULL: Not enough room.Library
See also
http_date_str
char *http_date_str(char *buf);Description
Print the date (time zone adjusted) into the given buffer. This assumes there is room!
Parameters
buf
The buffer to write the date into. This requires at least 30 bytes in the destination buffer.
Return Value
Library
See Also
http_delfile
int http_delfile(char* name);Description
Deletes a file from TCP/IP servers' object list.
Parameters
name
Name of the file, as passed to
http_addfile.Return value
0: Success;1: Failure (not found).Library
See also
http_finderrbuf
char* http_finderrbuf(char* name);Description
Finds the occurrence of the given variable in the HTML form error buffer, and returns its location.
Parameters
name
Return value
NULL: Failure.!NULL: Success, location of the variable in the error buffer.Library
http_findname
HttpSpecAll http_findname(char* name);Description
Finds a spec entry, searching first in RAM, then in FLASH.
Parameters
name
Name, in text, of the spec to find.
Return Value
Library
http_handler
void http_handler();Description
This is the basic control function for the HTTP server, a tick function to run the HTTP daemon. It must be called periodically for the daemon to work. It parses the requests and passes control to the other handlers, either
html_handler,shtml_handler, or to the developer-defined CGI handler based on the request's extension.Library
See also
http_init
int http_init(void);Description
Return value
Library
See also
http_nextfverr
void http_nextfverr( char* start, char** name, char** value, int* error, char** next );Description
Gets the information for the next variable in the HTML form error buffer. If any of the last four parameters in the function call are
NULL, then those parameters will not have a value returned. This is useful if you are only interested in certain variable information.Parameters
start
Pointer to the variable in the buffer for which we want to get information.
name
Return location for the name of the variable.
value
Return location for the value of the variable.
error
Return location for whether or not the variable is in error (0 if it is not, 1 if it is).
next
Return location for a pointer to the variable after this one.
Return Value
None, although information is returned in the last four parameters.
Library
http_parseform
int http_parseform(int form, HttpState* state);Description
Parses the returned form information
.It expects a POST submission. This function is useful for a developer who only wants the parsing functionality and wishes to generate forms herself. Note that the developer must still build the array ofFormVars and use theserver_spectable. This function will not, however, automatically display the form when used by itself. If all variables satisfy all integrity checks, then the variables' values are updated. If any variables fail, then none of the values are updated, and error information is written into the error buffer If this function is used directly, the developer must process errors.Parameters
form
server_specindex of the form (i.e., location in TCP/IP servers' object list).state
The HTTP server with which to parse the POSTed data.
Return value
0if there is more processing to do;1form processing has been completed.Library
http_setcookie
void http_setcookie(char* buf, char* value);Description
This utility generates a cookie on the client. This will store the text in
valueinto a cookie-generation header that will be written tobuf. This will not be written out to the client, and it is still the responsibility of the client to write out. Also, this utility will generate an HTTP header line that must be written along with any other headers that are written before the HTML file itself is written out. When a page is requested from the client, and the cookie is already set, the text of the cookie will be stored instate->cookie[]. This is achar*, andstate->cookie[0]will equal'\0'if no cookie was available.Parameters
buf
Buffer to store cookie-generation header.
value
Text to store in cookie-generation header.
Library
http_urldecode
char *http_urldecode(char *dest, const char *src, int len);Description
Converts a string with URL-escaped ''tokens'' (such as %20 (hex) for space) into actual values. Changes "+" into a space. String can be
NULLterminated; it is also bounded by a specified string length. This function is reentrant.Parameters
dest
Buffer where decoded string is stored.
src
Buffer holding original string (not changed).
len
Maximum size of string (
NULLterminated strings can be shorter).Return value
dest: If all conversion was good.NULL: If some conversion had troubles.Library
See also
shtml_addfunction
int shtml_addfunction(char* name, void (*fptr()));Description
Adds a CGI/SSI-exec function for making dynamic web pages to the TCP/IP servers' object list.
Parameters
name
Name of the function (e.g., "
/foo.cgi").fptr
Function pointer to the handler, that must take
HttpState*as an argument. This function should return anint(0while still pending,1when finished).Return value
0: Success;1: Failure (no room).Library
See also
shtml_addvariable
int shtml_addvariable(char* name, void* variable, word type, char* format);Description
This function adds a variable so it can be recognized by the
shtml_handler.Parameters
name
variable
type
Type of variable. The following types are supported:
INT8,INT16,INT32,PTR16, FLOAT32format
Standard printf format string. (e.g., "%d")
Return value
0: Success.1: Failure (no room).Library
See also
shtml_delfunction
int shtml_delfunction(char* name);Description
Deletes a function from the TCP/IP servers' object list.
Parameters
name
Name of the function as given to
shtml_addfunction.Return value
0: Success;1: Failure (not found).Library
See also
shtml_delvariable
int shtml_delvariable(char* name);Description
Deletes a variable from the TCP/IP servers' object list.
Parameters
name
Name of the variable, as given to
shtml_addvariable.Return value
0: Success;1: Failure (not found).Library
See also
| Z-World http://www.zworld.com Voice: 530.757.3737 Fax: 530.757.3792 or 530.753.5141 sales@zworld.com |