OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [athttpd/] [current/] [doc/] [athttpd.sgml] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.