|
2250
|
1 <!-- =============================================================== --> |
|
|
2 <!-- --> |
|
|
3 <!-- athttpd.sgml --> |
|
|
4 <!-- --> |
|
|
5 <!-- Another Tiny HTTPD Server for eCos --> |
|
|
6 <!-- --> |
|
|
7 <!-- =============================================================== --> |
|
|
8 <!-- ####COPYRIGHTBEGIN#### --> |
|
|
9 <!-- --> |
|
|
10 <!-- =============================================================== --> |
|
|
11 <!-- Copyright (C) 2003, 2004 eCosCentric Ltd. --> |
|
|
12 <!-- This material may be distributed only subject to the terms --> |
|
|
13 <!-- and conditions set forth in the Open Publication License, v1.0 --> |
|
|
14 <!-- or later (the latest version is presently available at --> |
|
|
15 <!-- http://www.opencontent.org/openpub/) --> |
|
|
16 <!-- =============================================================== --> |
|
|
17 <!-- --> |
|
|
18 <!-- ####COPYRIGHTEND#### --> |
|
|
19 <!-- =============================================================== --> |
|
|
20 <!-- #####DESCRIPTIONBEGIN#### --> |
|
|
21 <!-- --> |
|
|
22 <!-- ####DESCRIPTIONEND#### --> |
|
|
23 <!-- =============================================================== --> |
|
|
24 |
|
|
25 <!-- }}} --> |
|
|
26 |
|
|
27 |
|
|
28 <part id="athttpd"> |
|
|
29 <title>Another Tiny HTTP Server for <productname>eCos</productname></title> |
|
|
30 |
|
|
31 <partintro> |
|
|
32 <para> |
|
|
33 This package provides an extensible, small footprint, full featured HTTP |
|
|
34 server for <productname>eCos</productname>. Many of these features can be |
|
|
35 disabled via the configuration tool, thus reducing the footprint of the server. |
|
|
36 The server has been written for the FreeBSD network stack. |
|
|
37 </para> |
|
|
38 </partintro> |
|
|
39 |
|
|
40 <chapter id="net-athttpd"> |
|
|
41 <title>The ATHTTP Server</title> |
|
|
42 <sect1 id="athttpd-features"> |
|
|
43 <title>Features</title> |
|
|
44 <para>This ATHTTP implementation provides the following features:</para> |
|
|
45 <itemizedlist> |
|
|
46 <listitem><para>GET, POST and HEAD Methods</para></listitem> |
|
|
47 <listitem><para>File system Access</para></listitem> |
|
|
48 <listitem><para>Callbacks to C functions</para></listitem> |
|
|
49 <listitem><para>MIME type support</para></listitem> |
|
|
50 <listitem><para>CGI mechanism through the OBJLOADER package or through a |
|
|
51 simple tcl interpreter</para></listitem> |
|
|
52 <listitem><para>Basic Authentication</para></listitem> |
|
|
53 <listitem><para>Directory Listing</para></listitem> |
|
|
54 <listitem><para>Extendable Internal Resources</para></listitem> |
|
|
55 </itemizedlist> |
|
|
56 |
|
|
57 <para> |
|
|
58 Ecos tables are used extensively throught the server to provide a high degree |
|
|
59 of customization.</para> |
|
|
60 </sect1> |
|
|
61 |
|
|
62 <sect1 id="athttpd-using"> |
|
|
63 <title>Starting the server</title> |
|
|
64 <para> |
|
|
65 In order to start the web server, the user needs to call the function:</para> |
|
|
66 |
|
|
67 <programlisting width=72> |
|
|
68 cyg_httpd_start(); |
|
2265
|
69 </programlisting> |
|
2250
|
70 |
|
|
71 <para>in the application code. The server initialization code spawns a new |
|
|
72 thread which calls <command>init_all_network_interfaces()</command> to |
|
|
73 initialize the TCP/IP stack and then starts the deamon. The function is safe |
|
|
74 to call multiple times. |
|
|
75 </para> |
|
|
76 </sect1> |
|
|
77 |
|
2265
|
78 <sect1 id="athttpd-mime-types"> |
|
|
79 <title>MIME types</title> |
|
|
80 <para> |
|
|
81 The server has an internal table with all the recognized mime types. Each time |
|
|
82 a file or an internal resource is sent out by the server, its extension is |
|
|
83 searched in this table and if a match is found, the associated MIME type is |
|
|
84 then sent out in the header. |
|
|
85 |
|
|
86 The server already provides entries for the following standard file extensions: |
|
|
87 |
|
|
88 'html', 'htm', 'gif', 'jpg', 'css', 'js' |
|
|
89 |
|
|
90 and the user is responsible for adding any further entry. The syntax for |
|
|
91 adding an entry is the following:</para> |
|
|
92 |
|
|
93 <para><programlisting width=72> |
|
|
94 CYG_HTTPD_MIME_TABLE_ENTRY(entry_label, extension_string, mime_tipe_sting); |
|
|
95 |
|
|
96 entry table : an identifier unique to this entry |
|
|
97 extension string : a string containing the extension for this entry |
|
|
98 type_string : the mime string. The strings for many more mime types |
|
|
99 is included in a file in the "doc" directory. |
|
|
100 </programlisting></para> |
|
|
101 |
|
|
102 <para> |
|
|
103 The following is an example of how to add the Adobe Portable Document Format |
|
|
104 <command>pdf</command> MIME type to the table:</para> |
|
|
105 |
|
|
106 <para><programlisting width=72> |
|
|
107 CYG_HTTPD_MIME_TABLE_ENTRY(hal_pdf_entry, "pdf", "application/pdf"); |
|
|
108 </programlisting></para> |
|
|
109 |
|
|
110 <sect2 id="athttpd-mime-types-chunked"> |
|
|
111 <title>MIME Types for Chunked Frames</title> |
|
|
112 <para> |
|
|
113 For chunked frames, which are generally used inside c language callbacks, there |
|
|
114 is no file name to match an extension to, and thus the extension to be used |
|
|
115 must be passed in the <command>cyg_httpd_start_chunked()</command> call. The |
|
|
116 server will then scan the MIME table to find a MIME type to match the extension. |
|
|
117 |
|
|
118 For example, to start a chunked transfer of an <command>html</command> file, |
|
|
119 the following call is used:</para> |
|
|
120 |
|
|
121 <para><programlisting width=72> |
|
|
122 cyg_httpd_start_chunked("html"); |
|
|
123 </programlisting></para> |
|
|
124 |
|
|
125 <para> |
|
|
126 In any event, it is the responsibility of the user to make sure that a match to |
|
|
127 all used extensions is found in the table search. Failing this, |
|
|
128 the default MIME type specified in the CYGDAT_NET_ATHTTPD_DEFAULT_MIME_TYPE |
|
|
129 string is returned.</para> |
|
|
130 </sect2> |
|
|
131 </sect1> |
|
|
132 |
|
2250
|
133 <sect1 id="athttpd-callback"> |
|
|
134 <title>C language callback functions</title> |
|
|
135 <para> |
|
|
136 The server allows the association of particular URLs to C language callback |
|
2265
|
137 functions. eCos tables are used to define the association between a URL and its |
|
|
138 corresponding callback. The syntax of the macro to add callback entries to |
|
|
139 the table is: |
|
2250
|
140 </para> |
|
|
141 |
|
|
142 <para><programlisting width=72> |
|
2265
|
143 CYG_HTTPD_HANDLER_TABLE_ENTRY(entry_label, url_string, callback); |
|
|
144 |
|
|
145 entry table : an identifier unique to this entry. |
|
|
146 url_string : a string with the extension url that will be appended to the |
|
|
147 default directory. |
|
|
148 callback : a function with a prototype: |
|
|
149 cyg_int32 callback_function(CYG_HTTPS_STATE*); |
|
|
150 </programlisting></para> |
|
2250
|
151 |
|
|
152 <para> |
|
|
153 <command>CYG_HTTPS_STATE*</command> is a pointer to a structure that |
|
|
154 contains, among others, a buffer (outbuffer) that can be used to send data |
|
2265
|
155 out. The definitions of the structure is in http.h.</para> |
|
|
156 |
|
2250
|
157 <para> |
|
2265
|
158 If the callback function returns the value of 0, the server will try to find |
|
|
159 the file with the same URL in the file system and send it. Any other value |
|
2250
|
160 returned causes the sever to stop further processing of this request. It is |
|
|
161 assumed that in this case the user has send the response back to the client |
|
2265
|
162 inside the body of the callback function. |
|
|
163 |
|
|
164 The following is an example of how to add a callback to a function myForm() |
|
|
165 whenever the URL /myform.cgi is requested: |
|
2250
|
166 </para> |
|
|
167 |
|
|
168 <programlisting width=72> |
|
2265
|
169 CYG_HTTPD_HANDLER_TABLE_ENTRY(hal_cb_entry, "/myform.cgi", myForm); |
|
2250
|
170 </programlisting> |
|
2265
|
171 |
|
2250
|
172 <para> |
|
|
173 and somewhere in the source tree there is a function:</para> |
|
|
174 |
|
|
175 <programlisting> |
|
|
176 cyg_int32 myForm(CYG_HTTPS_STATE* p) |
|
|
177 { |
|
|
178 cyg_httpd_start_chunked("html"); |
|
|
179 strcpy(p->outbuffer, "eCos Web Server"); |
|
|
180 cyg_httpd_write_chunked(p->outbuffer, strlen(p->outbuffer)) |
|
|
181 cyg_httpd_end_chunked(); |
|
|
182 return -1; // Do not further search the file system. |
|
2265
|
183 } |
|
2250
|
184 </programlisting> |
|
|
185 |
|
|
186 <para>This function also shows the correct method of using the chunked frames |
|
|
187 API inside a c language callback and also shows the use of outbuffer to |
|
|
188 collect data to send out.</para> |
|
|
189 |
|
|
190 <para>Chunked frames are useful when the size of the frame is not known upfront. |
|
|
191 In this case it possible to send a response in chunks of various sizes, and |
|
2265
|
192 terminate it with a null chunk (See RFC 2616 for details). To use chunked |
|
2250
|
193 frames, the <command>cyg_httpd_start_chunked()</command> function is used. |
|
|
194 The prototype is the following:</para> |
|
|
195 |
|
|
196 <programlisting> |
|
|
197 ssize_t cyg_httpd_start_chunked(char *); |
|
|
198 </programlisting> |
|
|
199 |
|
|
200 <para>The only parameter is the <command>extension</command> to use in the |
|
|
201 search for the MIME type. For most files this will be "html" or "htm" and |
|
|
202 it will be searched in the MIME table for an approriate MIME type that will |
|
|
203 be sent along in the header. The function returns the number of bytes sent |
|
|
204 out.</para> |
|
|
205 |
|
|
206 <para>The chunked frame must be terminated by a call to |
|
|
207 <command>cyg_httpd_end_chunked()</command>:</para> |
|
|
208 |
|
|
209 <programlisting> |
|
|
210 void cyg_httpd_end_chunked()(void); |
|
|
211 </programlisting> |
|
|
212 |
|
|
213 <para>In between these two calls, the user can call the function |
|
2265
|
214 <command>cyg_httpd_write_chunked()</command> to send out data any number of |
|
2250
|
215 times. It is important that <command>cyg_httpd_write_chunked()</command> be |
|
|
216 the only function used to send data out for chunked frames. This |
|
|
217 guarantees that proper formatting of the response is respected. |
|
|
218 The prototype for the function is:</para> |
|
|
219 |
|
|
220 <programlisting> |
|
|
221 ssize_t cyg_httpd_write_chunked(char* p, int len); |
|
|
222 </programlisting> |
|
|
223 |
|
|
224 <para>The 'char*' points to the data to send out, the 'int' is the length of the |
|
|
225 data to send.</para> |
|
|
226 |
|
|
227 <para>In the case in which the size of the data is known upfront, the |
|
|
228 callback can instead create the header with a call to |
|
|
229 <command>cyg_httpd_create_std_header()</command> with the following |
|
|
230 prototype:</para> |
|
|
231 |
|
|
232 <programlisting> |
|
|
233 void cyg_httpd_create_std_header(char *ext, int len); |
|
|
234 |
|
|
235 extension : the extension used in the search of the MIME type |
|
|
236 len : length of the data to send out |
|
|
237 </programlisting> |
|
|
238 |
|
2265
|
239 <para>and use |
|
|
240 <command>cyg_httpd_write()</command> to send data out to the client. The |
|
|
241 prototype of <command>cyg_httpd_write()</command> is the same as |
|
|
242 <command>cyg_httpd_write_chunked()</command></para></sect1> |
|
2250
|
243 |
|
|
244 <sect1 id="athttpd-cgi"> |
|
|
245 <title>CGI</title> |
|
|
246 <para> |
|
2265
|
247 The web server allows writing of pseudo-CGI programs. This is helpful in order |
|
|
248 to modify the functionality of the server without having to recompile it and |
|
2250
|
249 reflash it.</para> |
|
|
250 |
|
|
251 <para>One way to implement CGI is, of course, the C language callback mechanism |
|
|
252 described above: This assumes, of course, that all the callbacks are written |
|
2265
|
253 by compile time and cannot be modified later on. Another way to perform the |
|
2250
|
254 same functionality is the use of a library in the form of an object file. |
|
2265
|
255 These object files reside in the file system and are loaded, executed and |
|
2250
|
256 unloaded on demand.</para> |
|
|
257 |
|
|
258 <para>Yet a third way is the use of a scripting language. Since full fledged |
|
|
259 implementation of the most popular scripting languages such as Python or Perl |
|
|
260 are too large for most embedded systems, a slim down implementation of tcl |
|
|
261 was chosen for this server. Most of the tcl functionality is still there, |
|
|
262 and makes writing cgi a lot easier.</para> |
|
|
263 |
|
|
264 <para>In order to limit the footprint of the operating system support for both |
|
2265
|
265 the objloader and the tcl script for dealing with cgi files can be |
|
|
266 independently selected out. Tcl support in particular increases the memory |
|
|
267 requirements considerably. |
|
2250
|
268 </para> |
|
|
269 |
|
|
270 <sect2 id="athttpd-cgi-objloader"> |
|
|
271 <title>CGI via objloader</title> |
|
|
272 <para> |
|
2265
|
273 In order to use the cgi mechanism the CYGPKG_OBJLOADER must be included |
|
2250
|
274 when building the operating system. This will enable the proper option in the |
|
2265
|
275 configuration tool and if selected, the necessary code will be compiled |
|
|
276 in the eCos kernel. The user will then have to compile the necessary libraries |
|
|
277 and place them in the file system under a directory defined by |
|
2250
|
278 CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR. |
|
2265
|
279 When a request is made, the web server checks if the root directory of the |
|
|
280 requested URL is inside the CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR directory. |
|
|
281 If so, the server assumes that the user requested a cgi file and looks into the |
|
2250
|
282 directory to see if a library by the same name is present, and if so load it |
|
2265
|
283 and tries to execute a function inside the library with the following prototype: |
|
2250
|
284 </para> |
|
|
285 |
|
2265
|
286 <programlisting width=72>void exec_cgi(CYG_HTTPS_STATE *) |
|
2250
|
287 </programlisting> |
|
|
288 |
|
|
289 <para> |
|
|
290 The pointer <command>CYG_HTTPS_STATE*</command> gives access to the socket |
|
|
291 data: The user will use this pointer to access the 'outbuffer' and use it to |
|
|
292 copy data to send data out. |
|
|
293 </para> |
|
2265
|
294 |
|
2250
|
295 <para> |
|
|
296 When using the OBJLOADER package within the HTTP server a number of functions |
|
|
297 are automatically added to the externals table of the OBJLOADER package. These |
|
|
298 functions are likely to be used inside the library and the relocator need to |
|
|
299 have a pointer to them. In order to add more functions, see the OBJLOADER |
|
2265
|
300 documentation. The complete list of the functions automatically added is: |
|
2250
|
301 </para> |
|
|
302 |
|
|
303 <itemizedlist> |
|
|
304 <listitem><para>cyg_httpd_start_chunked()</para></listitem> |
|
|
305 <listitem><para>cyg_httpd_write_chunked()</para></listitem> |
|
|
306 <listitem><para>cyg_httpd_end_chunked()</para></listitem> |
|
|
307 <listitem><para>cyg_httpd_write()</para></listitem> |
|
|
308 <listitem><para>cyg_httpd_find_form_variable()</para></listitem> |
|
|
309 <listitem><para>cyg_httpd_find_ires()</para></listitem> |
|
|
310 <listitem><para>cyg_httpd_send_ires()</para></listitem> |
|
|
311 <listitem><para>diag_printf()</para></listitem> |
|
|
312 <listitem><para>cyg_httpd_format_header()</para></listitem> |
|
|
313 <listitem><para>cyg_httpd_find_mime_string()</para></listitem> |
|
|
314 </itemizedlist> |
|
|
315 |
|
2265
|
316 <para>Every time the web client issues a GET or POST request for a file with an |
|
|
317 extension of '.o'in the /cgi-bin directory (or whatever path the user chooses |
|
2250
|
318 to hold the libraries) then the library by that name is loaded, run and |
|
2265
|
319 when the execution is over, it is dumped from memory. |
|
|
320 |
|
2250
|
321 The library must be compiled separately, using the same toolchain used to |
|
|
322 compile the server and then added to the file system.</para> |
|
2265
|
323 |
|
2250
|
324 <para>In order to reduce the footprint of the server, CGI through OBJLOADER |
|
|
325 can be compiled out by unchecking CYGOPT_NET_ATHTTPD_USE_CGIBIN_OBJLOADER |
|
|
326 in the configuration tool.</para> |
|
|
327 </sect2> |
|
|
328 |
|
|
329 <sect2 id="athttpd-cgi-tcl"> |
|
|
330 <title>CGI via the simple tcl interpreter</title> |
|
|
331 <para>A small tcl interpreter has been added to the web server, and it can |
|
|
332 be used to write simple cgi scripts. The interpreter is admittedly very |
|
|
333 minimal, and it is only useful for very simple applications, but it is an |
|
|
334 excellent starting point for further development.</para> |
|
|
335 |
|
|
336 <para>In order for the scripting language to be useful, it has to access |
|
|
337 the form variables passed on during the GET or POST request. Because of |
|
|
338 this, all form variables registered with the CYG_HTTPD_FVAR_TABLE_ENTRY() |
|
|
339 macro are accessible via tcl. For example, if we have registered a |
|
|
340 form variable called foo, and during the GET request we are defining foo |
|
|
341 as being "1":</para> |
|
|
342 |
|
2265
|
343 <programlisting width=72>GET /myForm.cgi?foo=1</programlisting> |
|
2250
|
344 |
|
|
345 <para>then tcl will be able to access the variable foo as $foo.</para> |
|
|
346 |
|
|
347 <para>In order to send back a response to the client a few functions have been |
|
|
348 added to the interpreter. These functions are:</para> |
|
|
349 |
|
|
350 <sect3 id="athttpd-start-chunked"> |
|
|
351 <title>start_chunked</title> |
|
|
352 <programlisting width=72>start_chunked "extension";</programlisting> |
|
|
353 <para>"extension" is a string used to search the |
|
|
354 table of the mime types. For example, to send back to the client an HTML file, |
|
|
355 we can use: start_chunked "html"; |
|
2265
|
356 </para> |
|
2250
|
357 </sect3> |
|
|
358 |
|
|
359 <sect3 id="athttpd-write-chunked"> |
|
|
360 <title>write_chunked</title> |
|
|
361 <programlisting width=72>write_chunked content;</programlisting> |
|
|
362 <para>content is a string to send back to the client. |
|
2265
|
363 </para> |
|
2250
|
364 </sect3> |
|
|
365 |
|
|
366 <sect3 id="athttpd-end-chunked"> |
|
|
367 <title>end_chunked</title> |
|
|
368 <programlisting width=72>end_chunked;</programlisting> |
|
2265
|
369 <para>No parameters. Send back an end of frame to the client.</para> |
|
2250
|
370 </sect3> |
|
|
371 </sect2> |
|
|
372 </sect1> |
|
|
373 |
|
|
374 <sect1 id="athttpd-authentication"> |
|
|
375 <title>Authentication</title> |
|
|
376 <para> |
|
|
377 The server supports both Basic (base64) and Digest (MD5) authentication, |
|
|
378 although they have not been tested with all clients. In this implementation, |
|
|
379 the contents of certain directories of the file system can be protected, such |
|
|
380 that the user will be required to issue a username/password to access the |
|
|
381 content of the directory.</para> |
|
|
382 |
|
|
383 <para>To protect a directory with a basic authentication, there is a |
|
|
384 specific macro:</para> |
|
|
385 |
|
|
386 <programlisting> |
|
|
387 CYG_HTTPD_AUTH_TABLE_ENTRY(entry, path, domain, un, pw, mode) |
|
|
388 |
|
|
389 entry : an identifier unique to this entry. |
|
|
390 path : the path to the directory whose content must be |
|
|
391 authenticated before it is sent out |
|
|
392 domain : a domain identifier for this directory. |
|
|
393 un : username for authentication |
|
|
394 pw : password for authentication |
|
2265
|
395 mode : CYG_HTTPD_AUTH_BASIC for base64 encoding or |
|
2250
|
396 CYG_HTTPD_AUTH_DIGEST for MD5 encoding |
|
|
397 </programlisting> |
|
|
398 |
|
|
399 <para>for example, to require basic authentication of the content of directory |
|
2265
|
400 "/ecos/" with a username of "foo" and password "bar", the following is used: |
|
2250
|
401 </para> |
|
|
402 |
|
|
403 <programlisting> |
|
2265
|
404 CYG_HTTPD_AUTH_TABLE_ENTRY(hal_domain1_entry, \ |
|
|
405 "/ecos/", "ecos_domain", \ |
|
|
406 "foo", "bar", \ |
|
2250
|
407 CYG_HTTPD_AUTH_BASIC); |
|
|
408 </programlisting> |
|
|
409 |
|
2265
|
410 <para>Any request for a file in the directory /ecos/ will now trigger a |
|
2250
|
411 credential check. These credentials, once provided, are automatically sent by |
|
2265
|
412 the client for every request within the particular domain.</para> |
|
2250
|
413 |
|
2265
|
414 <para>It must be noticed that the path name set in the macro is relative to the |
|
2250
|
415 HTML document directory, CYGDAT_NET_HTTPD_SERVEROPT_HTMLDIR and it is the |
|
|
416 first part of the path provided by the client request (including the leading |
|
|
417 slash).</para> |
|
|
418 |
|
|
419 <para>In order to reduce the footprint of the server, authentication |
|
|
420 is not enabled by default, and so the option CYGOPT_NET_ATHTTPD_USE_AUTH must |
|
|
421 be used to enable support for basic and digest authentication.</para> |
|
|
422 |
|
|
423 <para>The MD5 digest authentication support is implemented using the RSA |
|
|
424 Data Security, Inc. MD5 Message-Digest Algorithm. Derivative works with |
|
|
425 MD5 digest authentication included must be identified as "derived from the |
|
|
426 RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material |
|
|
427 mentioning or referencing the derived work. See the file md5.c within this |
|
|
428 package for license details.</para> |
|
|
429 </sect1> |
|
|
430 |
|
|
431 <sect1 id="athttpd-dirlist"> |
|
|
432 <title>Directory Listing</title> |
|
|
433 |
|
|
434 <para>If the user issues a "GET" request with a URL terminating in a slash, the |
|
|
435 server will try to locate one of the following index files in the directory, |
|
|
436 choosing one in the following order:</para> |
|
|
437 |
|
|
438 <itemizedlist> |
|
|
439 <listitem><para>index.html</para></listitem> |
|
|
440 <listitem><para>index.htm</para></listitem> |
|
|
441 <listitem><para>default.html</para></listitem> |
|
|
442 <listitem><para>home.html</para></listitem> |
|
|
443 </itemizedlist> |
|
|
444 |
|
|
445 <para>If any of these files is found, its contents are sent back |
|
2265
|
446 to the client. If no such file is found the server uses the user-provided |
|
|
447 index file name (if any is specified with the CYGDAT_NET_ATHTTPD_ALTERNATE_HOME |
|
|
448 setting. Failing all this a directory listing is sent.</para> |
|
2250
|
449 |
|
|
450 <para>Trailing slash redirection for directory names is supported.</para> |
|
|
451 |
|
|
452 <para>In order to reduce the footprint of the server, directory listing can |
|
|
453 be disabled by unchecking CYGOPT_NET_ATHTTPD_USE_DIRLIST. The savings are |
|
|
454 substantial since directory listing also makes use of a few internal |
|
|
455 resources (gif files) which are also compiled out.</para> |
|
|
456 </sect1> |
|
|
457 |
|
|
458 <sect1 id="athttpd-formvars"> |
|
|
459 <title>Form Variables</title> |
|
|
460 |
|
|
461 <para>The server will automatically try to parse form variables when a form is |
|
|
462 submitted.The variable names to look for during the parsing are held in |
|
|
463 an eCos table. In order to take advantage of this feature, the user first |
|
|
464 adds the variable names to the table, also providing a buffer where the parsed |
|
|
465 value will eventually be stored. The values will then be available in |
|
|
466 the buffers during the processing of the request, presumably in the body |
|
2265
|
467 of a c language callback or CGI script.</para> |
|
2250
|
468 |
|
|
469 <para>For example, if the user wants two form variables, "foo" and "bar", to |
|
|
470 be parsed automatically, those variable names must be added to the table |
|
|
471 with the following macro:</para> |
|
|
472 |
|
|
473 <programlisting> |
|
|
474 CYG_HTTPD_FVAR_TABLE_ENTRY(entry, name, buffp, bufflen) |
|
|
475 |
|
|
476 entry : an identifier unique to this entry. |
|
|
477 name : name of the form variable |
|
|
478 buffp : a pointer to a buffer of characters where to store the value |
|
|
479 of the form variable. |
|
|
480 bufflen : The length of the buffer. Must include a trailing string |
|
|
481 terminator. |
|
|
482 </programlisting> |
|
|
483 |
|
|
484 <para>or, in the specific instance mentioned above:</para> |
|
|
485 |
|
|
486 <programlisting> |
|
2265
|
487 #define HTML_VAR_LEN 20 |
|
|
488 char var_foo[HTML_VAR_LEN]; |
|
|
489 char var_bar[HTML_VAR_LEN]; |
|
|
490 CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_foo, "foo", var_foo, HTML_VAR_LEN); |
|
|
491 CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_bar, "bar", var_bar, HTML_VAR_LEN); |
|
2250
|
492 </programlisting> |
|
|
493 |
|
|
494 <para>and after the GET or POST submissions, the list will contain the value |
|
|
495 for "foo" and "bar" (if they were found in the form data.) It is the |
|
|
496 responsability of the user to make sure that the buffer is large enough |
|
|
497 to hold all the data parsed (including the string terminator). The parser will |
|
|
498 write only up to the length of the buffer minus one (the last being the |
|
|
499 terminator).</para> |
|
|
500 |
|
|
501 <para>The values parsed are likely going to be used in c language callback, or |
|
|
502 in CGI files. The user can access the pointers of individual variable |
|
|
503 for further processing, keeping in mind that the parsing always result |
|
|
504 in a string of characters to be produced, and any conversion from strings to |
|
|
505 integer (i.e. atoi()) must be performed in the callback.</para> |
|
|
506 |
|
|
507 <para>In CGI functions implemented using the objloader the pointers to the |
|
|
508 variables cannot be accessed directly, since the library will likely not |
|
|
509 know their location in memory. The proper way to access them is by using the |
|
2265
|
510 cyg_httpd_find_form_variable() function from withing the library:</para> |
|
2250
|
511 |
|
|
512 <programlisting> |
|
|
513 char* cyg_httpd_find_form_variable(char* name) |
|
|
514 |
|
|
515 name : name of the form variable to look up |
|
|
516 |
|
|
517 returns a pointer to the buffer, or 0 if the variable was not found. |
|
|
518 </programlisting> |
|
|
519 |
|
2265
|
520 <para>When using the OBJLOADER package within the web server, an entry |
|
|
521 for the cyg_httpd_find_form_variable() function is automatically added to the |
|
|
522 externals table the OBJLOADER for relocation. See the OBLOADER paragraph of |
|
|
523 the ATHTTP user's guide for the full list of the exported functions.</para> |
|
|
524 |
|
|
525 <para>In order to avoid stale data, all the buffers in the table are cleared |
|
|
526 before running the parser and thus any variable in the list that was not |
|
|
527 assigned a new value dureing the request will be an empty string.</para> |
|
2250
|
528 </sect1> |
|
|
529 |
|
|
530 <sect1 id="athttpd-ires"> |
|
|
531 <title>Internal Resources</title> |
|
|
532 |
|
|
533 <para>When the server does not use a file system the user must be responsible |
|
|
534 to provide a C language callback function for each URL that will be |
|
|
535 requested by the client. This means locating the data and sending it out |
|
|
536 using either <command>cyg_httpd_write()</command> or |
|
|
537 <command>cyg_httpd_write_chunked()</command>.</para> |
|
|
538 |
|
|
539 <para>In order to simplify this process the server allows registering |
|
2265
|
540 any number of URLs as internal resources, by providing the URL name, the |
|
2250
|
541 pointer to the resource data and its size. When a URL is requested the |
|
|
542 server will look it up among all internal resources, and if found, it |
|
|
543 will send out the resource.</para> |
|
|
544 |
|
|
545 <para>Internal resource can also be used along with a file system. In this |
|
|
546 case the file system is searched first, and if a file is found, it it |
|
|
547 sent. If a file is not found, the internal resources are searched and |
|
|
548 if a match if found it is sent.</para> |
|
|
549 |
|
|
550 <para>The drawback of this approach is, of course, that all these |
|
|
551 resources are going to add to the size of the operating system image, and thus |
|
|
552 it should be used only when memory is not a major constraint of the |
|
|
553 design.</para> |
|
|
554 |
|
|
555 <para>As always, to provide this type of customization, ecos tables are used. |
|
|
556 The format for adding a new resource to the internal table is the following: |
|
|
557 </para> |
|
|
558 |
|
|
559 <programlisting> |
|
|
560 CYG_HTTPD_IRES_TABLE_ENTRY(entry, name, buffp, len) |
|
|
561 |
|
|
562 entry : an identifier unique to this entry. |
|
|
563 name : name of the URL including leading '/' |
|
|
564 buffp : a pointer to a buffer of characters where to store the value |
|
|
565 of the form variable. |
|
|
566 len : size of the array |
|
|
567 </programlisting> |
|
|
568 |
|
|
569 <para>As an example, if the user wants to provide his own web page by |
|
|
570 hardcoding it in the application code, here is how he would do it:</para> |
|
|
571 |
|
|
572 <programlisting> |
|
|
573 #define MY_OWN_HOME_PAGE "eCos RTOS" |
|
|
574 CYG_HTTPD_IRES_TABLE_ENTRY(cyg_httpd_ires_home, \ |
|
|
575 "/index.html", \ |
|
|
576 MY_OWN_HOME_PAGE, \ |
|
|
577 9); |
|
|
578 </programlisting> |
|
|
579 |
|
|
580 <para>The extension of the file name determines the MIME type to be used for |
|
|
581 internal resources.</para> |
|
|
582 |
|
|
583 <para>When using directory listing you are implicitly making use of internal |
|
|
584 resources. The small icons that appear to the left of file names and |
|
|
585 directories are internal resources. Unchecking CYGOPT_NET_HTTP_USE_DIRLIST |
|
|
586 will prevent the addition of these files.</para> |
|
|
587 |
|
|
588 <para>In order to use internal resources, a generic file must first be |
|
|
589 turned into a c language array, which is then compiled in the application |
|
|
590 code. To create this array you can use the tcl script that comes with the |
|
|
591 ecos distribution at packages/fs/rom/current/support/file2.tcl.</para> |
|
|
592 </sect1> |
|
|
593 </chapter> |
|
|
594 </part> |