1 /*******************************************************************************
 2  *  Copyright (c) 2009, Arthur Benilov
 3  *
 4  * This library is free software; you can redistribute it and/or
 5  * modify it under the terms of the GNU Lesser General Public
 6  * License as published by the Free Software Foundation; either
 7  * version 2 of the License, or (at your option) any later version.
 8  *
 9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  ******************************************************************************/
18 
19 /*
20     This is a simple example of HTTP server usage.
21     It shows how to start the server, register some CGI functions
22     and handle HTTP requests within these functions.
23 */
24 
25 /* Here is forward declaration of two CGI functions */
26 static void cgi_test1_html ( char *params, int length );
27 static void cgi_test2_html ( char *params, int length );
28 
29 /**
30  * Entry point. Here we start the server and register some CGI functions.
31  */
32 void httpd_example ( ) {
33 
34     /* Starting the server, listening on port 80 */
35     if ( HTTPD_OK != httpd_start(80) ) {
36         logMsg("Cannot start the server!\n");
37         return;
38     }
39 
40     /* Registering CGI functions. Note, that you cannot
41      * register them before starting the server.
42      */
43     httpd_register_resource("/test1.html", &cgi_test1_html);
44     httpd_register_resource("/test2.html", &cgi_test2_html);
45 
46     /* From now we are done. Server is running, CGI functions
47      * will be called when a client requests
48      * http://target/test1.html or http://target/test2.html
49      */
50 }
51 
52 /* ------------------------------------------------------ */
53 /**
54  * Here is a first CGI function.
55  * We assume that stdio redirection is enabled, so we can
56  * use printf() for output to a client. The argument we receive
57  * here is a parameters string as it sent by a client.
58  */
59 static void cgi_test1_html ( char *params, int length ) {
60     char name[64];
61 
62     /* The first thing to do before performing any output
63      * is to send an HTTP header, stating HTTP result
64      * and content type we are about to send.
65      * Here we are going to send an HTML data.
66      */
67     httpd_header(HTTP_OK, CONTENT_TEXT_HTML);
68 
69     printf("<HTML><HEAD><TITLE>%s</TITLE></HEAD>\n", __FUNCTION__);
70     printf("<BODY>\n");
71     printf("<P>Request handled by %s<BR>\n", __FUNCTION__);
72     printf("<P>Received data[%d]: %s<BR>\n", length, params);
73 
74     /* Here we try to fetch parameter 'name'.
75      * So that when a client requests something like
76      * http://target/test1.html?name=foo
77      * will obtain a sting 'foo' as a value of
78      * name parameter.
79      */
80     if ( httpd_get_param(params, "name", name) == HTTPD_OK ) {
81         printf("<H2>name=\"%s\"</H2>\n", name);
82     } else
83         printf("<H2>name parameter was not sent</H2>\n");
84 
85     printf("</BODY></HTML>\n");
86 }
87 
88 /* ------------------------------------------------------ */
89 /**
90  * Here is another CGI function.
91  * The difference here is that we'll try to maintain a
92  * keep-alive connection. It is not possible with a previous function
93  * because the length of content is unknown. Now we put
94  * all the data we want to send into a temporary buffer,
95  * deternime its length and send a keep-alive header.
96  *
97  * When a client (i.g. web browser) receives a keep-alive
98  * response it may want to send a second, third, etc. request
99  * via the same connection without closing a socket. This
100  * increase somehow HTTP performance.
101  */
102 void cgi_test2_html ( char *params, int length ) {
103     char *buffer;
104     int i;
105 
106     /* Allocating memory for temporary buffer.
107      * We use dynamic allocation in order to not to use stack
108      * memory which is limited.
109      * Note, that if you use global or static variables here you have
110      * protect them by mutex because several session tasks
111      * may want to execute the same CGI function at the same time.
112      */
113     buffer = (char *)malloc(2048);
114     bzero(buffer, 2048);
115 
116     /* Here we'll output an XML file with some information.
117      * Note that you cannot use printf() or other functions
118      * that output to stdio since this may break an HTTP stream.
119      * (Well, if you have stdio redirection option disabled
120      * you may use printf, since it will print to your target
121      * console in this case).
122      */
123     strcat(buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
124     strcat(buffer, "<data>\n");
125     for ( i = 0; i < 10; i++ ) {
126         char tmp[64] = '\0';
127 
128         /* Some dumb random values */
129         sprintf(tmp, "<item id=\"%d\" value=\"%f\" />\n", i, rand());
130         strcat(buffer, tmp);
131     }
132     strcat(buffer, "</data>\n");
133 
134     /* Send an HTTP header and previously prepared content */
135     httpd_keep_alive(HTTPD_OK, CONTENT_TEXT_XML, strlen(buffer), buffer);
136 
137     free(buffer); /* Don't forget to free allocated memory */
138 }
139 
140 /* ------------------------------------------------------ */
141 /* End of file */
142