athttpd.sgml
来自「开放源码实时操作系统源码.」· SGML 代码 · 共 638 行 · 第 1/2 页
SGML
638 行
<!-- DOCTYPE part PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
<!-- =============================================================== -->
<!-- -->
<!-- athttpd.sgml -->
<!-- -->
<!-- Another Tiny HTTPD Server for eCos -->
<!-- -->
<!-- =============================================================== -->
<!-- ####COPYRIGHTBEGIN#### -->
<!-- -->
<!-- =============================================================== -->
<!-- Copyright (C) 2003, 2004, 2007 eCosCentric Ltd. -->
<!-- This material may be distributed only subject to the terms -->
<!-- and conditions set forth in the Open Publication License, v1.0 -->
<!-- or later (the latest version is presently available at -->
<!-- http://www.opencontent.org/openpub/) -->
<!-- =============================================================== -->
<!-- -->
<!-- ####COPYRIGHTEND#### -->
<!-- =============================================================== -->
<!-- #####DESCRIPTIONBEGIN#### -->
<!-- -->
<!-- ####DESCRIPTIONEND#### -->
<!-- =============================================================== -->
<!-- }}} -->
<part id="athttpd">
<title>Another Tiny HTTP Server for <productname>eCos</productname></title>
<partintro>
<para>
This package provides an extensible, small footprint, full featured HTTP
server for <productname>eCos</productname>. Many of these features can be
disabled via the configuration tool, thus reducing the footprint of the server.
The server has been written for the FreeBSD network stack.
</para>
</partintro>
<chapter id="net-athttpd">
<title>The ATHTTP Server</title>
<sect1 id="athttpd-features">
<title>Features</title>
<para>This ATHTTP implementation provides the following features:</para>
<itemizedlist>
<listitem><para>GET, POST and HEAD Methods</para></listitem>
<listitem><para>File system Access</para></listitem>
<listitem><para>Callbacks to C functions</para></listitem>
<listitem><para>MIME type support</para></listitem>
<listitem><para>CGI mechanism through the OBJLOADER package or through a
simple tcl interpreter</para></listitem>
<listitem><para>Basic Authentication</para></listitem>
<listitem><para>Directory Listing</para></listitem>
<listitem><para>Extendable Internal Resources</para></listitem>
</itemizedlist>
<para>
Ecos tables are used extensively throught the server to provide a high degree
of customization.</para>
</sect1>
<sect1 id="athttpd-using">
<title>Starting the server</title>
<para>
In order to start the web server, the user needs to call the function:</para>
<programlisting width=72>
cyg_httpd_start();
</programlisting>
<para>in the application code. The server initialization code spawns a new
thread which calls <command>init_all_network_interfaces()</command> to
initialize the TCP/IP stack and then starts the deamon. The function is safe
to call multiple times.
</para>
</sect1>
<sect1 id="athttpd-mime-types">
<title>MIME types</title>
<para>
The server has an internal table with all the recognized mime types. Each time
a file or an internal resource is sent out by the server, its extension is
searched in this table and if a match is found, the associated MIME type is
then sent out in the header.
The server already provides entries for the following standard file extensions:
'html', 'htm', 'gif', 'jpg', 'css', 'js', 'png'
and the user is responsible for adding any further entry. The syntax for
adding an entry is the following:</para>
<para><programlisting width=72>
CYG_HTTPD_MIME_TABLE_ENTRY(entry_label, extension_string, mime_tipe_sting);
entry table : an identifier unique to this entry
extension string : a string containing the extension for this entry
type_string : the mime string. The strings for many more mime types
is included in a file in the "doc" directory.
</programlisting></para>
<para>
The following is an example of how to add the Adobe Portable Document Format
<command>pdf</command> MIME type to the table:</para>
<para><programlisting width=72>
CYG_HTTPD_MIME_TABLE_ENTRY(hal_pdf_entry, "pdf", "application/pdf");
</programlisting></para>
<sect2 id="athttpd-mime-types-chunked">
<title>MIME Types for Chunked Frames</title>
<para>
For chunked frames, which are generally used inside c language callbacks, there
is no file name to match an extension to, and thus the extension to be used
must be passed in the <command>cyg_httpd_start_chunked()</command> call. The
server will then scan the MIME table to find a MIME type to match the extension.
For example, to start a chunked transfer of an <command>html</command> file,
the following call is used:</para>
<para><programlisting width=72>
cyg_httpd_start_chunked("html");
</programlisting></para>
<para>
In any event, it is the responsibility of the user to make sure that a match to
all used extensions is found in the table search. Failing this,
the default MIME type specified in the CYGDAT_NET_ATHTTPD_DEFAULT_MIME_TYPE
string is returned.</para>
</sect2>
</sect1>
<sect1 id="athttpd-callback">
<title>C language callback functions</title>
<para>
The server allows the association of particular URLs to C language callback
functions. eCos tables are used to define the association between a URL and its
corresponding callback. The syntax of the macro to add callback entries to
the table is:
</para>
<para><programlisting width=72>
CYG_HTTPD_HANDLER_TABLE_ENTRY(entry_label, url_string, callback);
entry table : an identifier unique to this entry.
url_string : a string with the extension url that will be appended to the
default directory.
callback : a function with a prototype:
cyg_int32 callback_function(CYG_HTTPD_STATE*);
Return value is ignored - just return 0.
</programlisting></para>
<para>
<command>CYG_HTTPD_STATE*</command> is a pointer to a structure that
contains, among others, a buffer (outbuffer) that can be used to send data
out. The definitions of the structure is in http.h.</para>
<para>
The following is an example of how to add a callback to a function myForm()
whenever the URL /myform.cgi is requested:
</para>
<programlisting width=72>
CYG_HTTPD_HANDLER_TABLE_ENTRY(hal_cb_entry, "/myform.cgi", myForm);
</programlisting>
<para>
and somewhere in the source tree there is a function:</para>
<programlisting>
cyg_int32 myForm(CYG_HTTPD_STATE* p)
{
cyg_httpd_start_chunked("html");
strcpy(p->outbuffer, "eCos Web Server");
cyg_httpd_write_chunked(p->outbuffer, strlen(p->outbuffer))
cyg_httpd_end_chunked();
}
</programlisting>
<para>This function also shows the correct method of using the chunked frames
API inside a c language callback and also shows the use of outbuffer to
collect data to send out.</para>
<para>Chunked frames are useful when the size of the frame is not known upfront.
In this case it possible to send a response in chunks of various sizes, and
terminate it with a null chunk (See RFC 2616 for details). To use chunked
frames, the <command>cyg_httpd_start_chunked()</command> function is used.
The prototype is the following:</para>
<programlisting>
ssize_t cyg_httpd_start_chunked(char *);
</programlisting>
<para>The only parameter is the <command>extension</command> to use in the
search for the MIME type. For most files this will be "html" or "htm" and
it will be searched in the MIME table for an approriate MIME type that will
be sent along in the header. The function returns the number of bytes sent
out.</para>
<para>The chunked frame must be terminated by a call to
<command>cyg_httpd_end_chunked()</command>:</para>
<programlisting>
void cyg_httpd_end_chunked()(void);
</programlisting>
<para>In between these two calls, the user can call the function
<command>cyg_httpd_write_chunked()</command> to send out data any number of
times. It is important that <command>cyg_httpd_write_chunked()</command> be
the only function used to send data out for chunked frames. This
guarantees that proper formatting of the response is respected.
The prototype for the function is:</para>
<programlisting>
ssize_t cyg_httpd_write_chunked(char* p, int len);
</programlisting>
<para>The 'char*' points to the data to send out, the 'int' is the length of the
data to send.</para>
<para>In the case in which the size of the data is known upfront, the
callback can instead create the header with a call to
<command>cyg_httpd_create_std_header()</command> with the following
prototype:</para>
<programlisting>
void cyg_httpd_create_std_header(char *ext, int len);
extension : the extension used in the search of the MIME type
len : length of the data to send out
</programlisting>
<para>and use
<command>cyg_httpd_write()</command> to send data out to the client. The
prototype of <command>cyg_httpd_write()</command> is the same as
<command>cyg_httpd_write_chunked()</command></para></sect1>
<sect1 id="athttpd-cgi">
<title>CGI</title>
<para>
The web server allows writing of pseudo-CGI programs. This is helpful in order
to modify the functionality of the server without having to recompile it and
reflash it.</para>
<para>One way to implement CGI is, of course, the C language callback mechanism
described above: This assumes, of course, that all the callbacks are written
by compile time and cannot be modified later on. Another way to perform the
same functionality is the use of a library in the form of an object file.
These object files reside in the file system and are loaded, executed and
unloaded on demand.</para>
<para>Yet a third way is the use of a scripting language. Since full fledged
implementation of the most popular scripting languages such as Python or Perl
are too large for most embedded systems, a slim down implementation of tcl
was chosen for this server. Most of the tcl functionality is still there,
and makes writing cgi a lot easier.</para>
<para>In order to limit the footprint of the operating system support for both
the objloader and the tcl script for dealing with cgi files can be
independently selected out. Tcl support in particular increases the memory
requirements considerably.
</para>
<sect2 id="athttpd-cgi-objloader">
<title>CGI via objloader</title>
<para>
In order to use the cgi mechanism the CYGPKG_OBJLOADER must be included
when building the operating system. This will enable the proper option in the
configuration tool and if selected, the necessary code will be compiled
in the eCos kernel. The user will then have to compile the necessary libraries
and place them in the file system under a directory defined by
CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR.
When a request is made, the web server checks if the root directory of the
requested URL is inside the CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR directory.
If so, the server assumes that the user requested a cgi file and looks into the
directory to see if a library by the same name is present, and if so load it
and tries to execute a function inside the library with the following prototype:
</para>
<programlisting width=72>void exec_cgi(CYG_HTTPD_STATE *)
</programlisting>
<para>
The pointer <command>CYG_HTTPD_STATE*</command> gives access to the socket
data: The user will use this pointer to access the 'outbuffer' and use it to
copy data to send data out.
</para>
<para>
When using the OBJLOADER package within the HTTP server a number of functions
are automatically added to the externals table of the OBJLOADER package. These
functions are likely to be used inside the library and the relocator need to
have a pointer to them. In order to add more functions, see the OBJLOADER
documentation. The complete list of the functions automatically added is:
</para>
<itemizedlist>
<listitem><para>cyg_httpd_start_chunked()</para></listitem>
<listitem><para>cyg_httpd_write_chunked()</para></listitem>
<listitem><para>cyg_httpd_end_chunked()</para></listitem>
<listitem><para>cyg_httpd_write()</para></listitem>
<listitem><para>cyg_httpd_find_form_variable()</para></listitem>
<listitem><para>cyg_httpd_find_ires()</para></listitem>
<listitem><para>cyg_httpd_send_ires()</para></listitem>
<listitem><para>diag_printf()</para></listitem>
<listitem><para>cyg_httpd_format_header()</para></listitem>
<listitem><para>cyg_httpd_find_mime_string()</para></listitem>
</itemizedlist>
<para>Every time the web client issues a GET or POST request for a file with an
extension of '.o'in the /cgi-bin directory (or whatever path the user chooses
to hold the libraries) then the library by that name is loaded, run and
when the execution is over, it is dumped from memory.
The library must be compiled separately, using the same toolchain used to
compile the server and then added to the file system.</para>
<para>In order to reduce the footprint of the server, CGI through OBJLOADER
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?