Subsections

8.6 CGI-Creation for Package httpd

8.6.1 General information about the web server

The web server used in fli4l is mini_httpd by ACME Labs. The sources can be found at http://www.acme.com/software/mini_httpd/. However, a few changes in the current version were made for fli4l. The modifications are located in the src package in the directory src/fbr/buildroot/package/mini_httpd.

8.6.2 Script Names

The script names should be self-explanatory in order to be easy to distinguish from other scripts and even similar names have to be avoided to differ from other OPTs.

To make scripts executable and convert DOS line breaks to UNIX ones a corresponding entry has to be created in opt/<PACKAGE>.txt, see Table .

8.6.3 Menu Entries

To create an entry in the menu you have to enter it in the file /etc/httpd/menu. This mechanism enables OPTs to change the menu during runtime. This should only be done using the script /etc/httpd/menu because this will check for valid file formatting. New menu items are inserted as follows:

    httpd-menu.sh add [-p <priority>] <link> <name> [section] [realm]

Thus, an entry with the name <name> is inserted to the [section]. If [section] is omitted, it will be inserted in the section ``OPT-Packages'' as default. <link> specifies the target of the new link. <priority> specifies the priority of a menu item in its section. If not set, the default priority used is 500. The priority should be a three digit number. The lower the priority, the higher the link is placed in the section. If an entry should be placed as far down as possible the priority to choose is e.g. 900. Entries with the same priority are sorted by the target of the link. In [realm] the range is specified for which a logged-in user must have view rights so the item is displayed for him. If [realm] is not specified, the menu item is always displayed. For this, see also the section ``User access rights''.

Example:

    httpd-menu.sh add "newfile.cgi" "Click here" "Tools" "tools"

This example creates a link named ``Click here'' with the target ``newfile.cgi'' in the section ``Tools'' which will be created if not present.

The script may also delete entries from a menu:

    httpd-menu.sh rem <link>

By executing this the entry containing the link <link> will be deleted.


Important: If several entries have the same link target file they will all be removed from the menu.

Since sections can have priorities they can also be created manually. If a section was created automatically when adding a menu entry it defaults to priority 500. The syntax for creating sections is as follows:

    httpd-menu.sh addsec <priority> <name>

<priority> should only be a three digit number.

In order to create meaningful priorities it is worthwhile to have a look at the file
/etc/httpd/menu of fli4l during runtime, priorities are placed in the second column.

A short description of the file format of the file menu follows for completeness. Those satisfied with the function of httpd-menu.sh may skip this section. The file /etc/httpd/menu is divided into four columns. The first column is a letter identifying the line as a heading or a menu entry. The second column is the sort priority. The third column contains the target of the link for entries and for headlines a hyphen, as this field has no meaning for headings. The rest of the line is the text that will appear in the menu.

Headings use the letter ``t'', a new menu section will be started then. Normal menu items use the letters ``e''. An example:

    t 300 - My beautiful OPT
    e 200 myopt1.cgi Do something beautiful
    e 500 myopt1.cgi?more=yes Do something even more beautiful

When editing this file you have to be aware that the script httpd-menu.sh always stores the file sorted. The individual sections are sorted and the entries in this section are sorted too. The sorting algorithm can be stolen from httpd-menu.sh, however, it would be better to expand the script itself with possible new functions, so that all menu-editing takes place at a central location.

8.6.4 Construction of a CGI script

8.6.4.1 The headers

All web server scripts are simple shell scripts (interpreter as e.g. Perl, PHP, etc. are much too big in filesize for fli4l). You should start with the mandatory script header (reference to the interpreter, name, what does the script, author, license).

8.6.4.2 Helper Script cgi-helper

After the header you should include the helper script cgi-helper with the following call:

    . /srv/www/include/cgi-helper

A space between the dot and the slash is important!

This script provides several helper functions that should greatly simplify the creation of CGIs for fli4l. With the integration some standard tasks are performed, such as the parsing of variables that were passed via forms or via the URL or loading of language and CSS files.

Here is a small function overview:


Table 8.4: Functions of the cgi-helper script
Name Function
check_rights Check for user access rights
http_header Creation of a standard HTTP header or a special header, e.g. for file download
show_html_header Creation of a complete page header (inc. HTTP header, headline and menu)
show_html_footer Creation of a footer for the HTML page
show_tab_header Creation of a content window with tabs
show_tab_footer Creation of a footer for the content window
show_error Creation of a box for error messages (background color: red)
show_warn Creation of a box for warning messages (background color: yellow)
show_info Creation of a box for information/ success messages (background color: green)

8.6.4.3 Contents of a CGI script

To ensure consistency in design and especially the compatibility with future versions of fli4l it is highly recommended to use the functions of the cgi-helper script even if theoretically everything in a CGI could be generated from scratch.

A simple CGI script might look like this:

    #!/bin/sh
    # --------------------
    # Header (c) Author Date
    # --------------------
    # get main helper functions
    . /srv/www/include/cgi-helper

    show_html_header "My first CGI"
    echo '   <h2>Welcome</h2>'
    echo '   <h3>This is a CGI script example</h3>'
    show_html_footer

8.6.4.4 The Function show_html_header

The show_html_header function expects a string as a parameter. This string represents the title of the generated page. It automatically generates the menu and includes associated CSS and language files as long as they can be found in the directories /srv/www/css resp. /srv/www/lang and have the same name (but of course a different extension) as the script. An example:

    /srv/www/admin/OpenVPN.cgi
    /srv/www/css/OpenVPN.css
    /srv/www/lang/OpenVPN.de

Both the use of language files and CSS files is optional. The files css/main.css and lang/main.<lang> (where <lang> refers to the chosen language) are always included.

Additional parameters can be passed to the function show_html_header. A call with all possible parameters might look like this:

    show_html_header "Title" "refresh=$time;url=$url;cssfile=$cssfile;showmenu=no"

Any additional parameters must, as shown in the example, be enclosed with quotation marks and separated by a semicolon. The syntax will not be checked! So it is necessary to pay close attention to the exact parameter syntax.

Here is a brief overview of the function of the parameters:

Other Content Guidelines:

8.6.4.5 The Function show_html_footer

The function show_html_footer closes the block from the CGI script which was openend by the function show_html_header.

8.6.4.6 The Function show_tab_header

For good looking content of your generated webpage generated by the CGI you may use the cgi-helper function show_tab_header. It creates clickable ``Tabs'' in order to present your page divided into multiple logically separated areas.

Parameters are always passed in pairs to the show_tab_header function. The first value reflects the title of a tab, the second reflects the link. If the string ``no'' is passed as a link only the title will be created and the tab is not clickable (and blue).

In the following example a ``window'' with the title ``A great window'' is generated. In the window is ``foo bar'':

    show_tab_header "A great window" "no"
    echo "foo"
    echo "bar"
    show_tab_footer

In this example, two clickable selection tabs are generated that pass the variable action to the script, each with a different value.

    show_tab_header "1st selection tab" "$myname?action=dothis" \
                    "2nd selection tab" "$myname?action=dothat"
    echo "foo"
    echo "bar"
    show_tab_footer

Now the script can change the content of the variable FORM_action (see variable evaluation below) and provide different content depending on the selection. For the clicked tab to appear selected and not clickable anymore, a ``no'' would have to be passed to the function instead of the link. But there is an easier way, if you hold to the convention in the following example:

    _opt_dothis="1st selection tab"
    _opt_dothat="2nd selection tab"
    show_tab_header "$_opt_dothis" "$myname?action=opt_dothis" \
                    "$_opt_dothat" "$myname?action=opt_dothat"
    case $FORM_action in
        opt_dothis) echo "foo" ;;
        opt_dothat) echo "bar" ;;
    esac
    show_tab_footer

Hence, if a variable whose name equals the content of the variable action with a leading underscore (_) is passed as the title then the tab will be displayed selected.

8.6.4.7 The Function show_tab_footer

The function show_tab_footer closes the block in the CGI script that was opened by the function show_tab_header.

8.6.4.8 Multi-Language Capabilities

The helper script cgi-helper furthermore contains functions to create multi-langual CGI scripts. You only have to use variables with a leading underscore (_) for all text output. This variables have to be defined in the respective language files.

Example:

Let lang/opt.de contain:

    _opt_dothis="Eine Ausgabe"

Let lang/opt.en contain:

    _opt_dothis="An Output"

Let admin/opt.cgi contain:

    ...
    echo $_opt_dothis
    ...

8.6.4.9 Form Evaluation

To process forms you have to know a few more things. Regardless of using the form's GET or POST methods, after including the cgi-helper script (which in turn calls the utility proccgi) the parameters can be accessed by variables named FORM_<Parameter>. If i.e. the form field had the name ``input'' the CGI script can access its content in the shell variable $FORM_input.

Further informations on the program proccgi can be found under http://www.fpx.de/fp/Software/ProcCGI.html.


8.6.4.10 User access rights: The Function check_rights

At the beginning of a CGI scripts the check_rights function has to be called in order to check whether a user has sufficient rights to use the script. Do this like here:

    check_rights <Section> <Action>

The CGI script will only be executed if the user, who is logged in at the moment

8.6.4.11 The Function show_error

This funtion displays an error message in a red box. It expects two parameters: a title and a message. Example:

    show_error "Error: No key" "No key was specified!"

8.6.4.12 The Function show_warn

This funtion displays a warning message in a yellow box. It expects two parameters: a title and a message. Example:

    show_info "Warning" "No connection at the moment!"

8.6.4.13 The Function show_info

This funtion displays an information or success message in a green box. It expects two parameters: a title and a message. Example:

    show_info "Info" "Action successfully executed!"

8.6.4.14 The Helper Script cgi-helper-ip4

Right after cgi-helper the helper script cgi-helper-ip4 may be included by writing the following line:

. /srv/www/include/cgi-helper-ip4

A space between the dot and the slash is important!

The script provides helper funtions for checking IPv4 addresses.

8.6.4.15 The Function ip4_isvalidaddr

This function checks if a valid IPv4 address was passed. Example:

    if ip4_isvalidaddr ${FORM_inputip}
    then
        ...
    fi

8.6.4.16 The Function ipv4_normalize

This function removes leading zeros from the passed IPv4 address. Example:

    ip4_normalize ${FORM_inputip}
    IP=$res
    if [ -n "$IP" ]
    then
        ...
    fi

8.6.4.17 The Function ipv4_isindhcprange

This function checks whether the passed IPv4 address is ranged between the passed start and end addresses. Example:

    if ip4_isindhcprange $FORM_inputip $ip_start $ip_end
    then
        ...
    fi

8.6.5 Miscellaneous

This and that (yes, also important!):

8.6.6 Debugging

To ease debugging of a CGI script you may activate the debugging mode by sourcing the cgi-helper script. Set the variable set_debug to ``yes'' in order to do so. This will create a file debug.log which may be loaded down with the URL http://<fli4l-Host>/admin/debug.log. It contains all calls of the CGI script. The variable set_debug is not a global one, it has to be set anew for each CGI in question. Example:

    set_debug="yes"
    . /srv/www/include/cgi-helper

Furthermore, cURL8.9 is ideal for troubleshooting, especially if the HTTP headers are not assembled correctly or the browser displays only blank pages. Also, the caching behavior of modern Web browser is obstructive when troubleshooting.

Example: Get a dump of the HTTP-Header with ("`dump"', -D) and the normal output of the CGI admin/my.cgi. The ``user'' (-u) name here shall be ``admin''.

    curl -D - http://fli4l/admin/my.cgi -u admin



Footnotes

... (SelfHTML8.8
see http://de.selfhtml.org/
... cURL8.9
see http://de.wikipedia.org/wiki/CURL
© 2001-2019 The fli4l-Team - 15 September 2019