Documentation/Example for CGI kioslave

Juergen Pfennig info at j-pfennig.de
Sat Jun 24 23:10:33 BST 2006


Hi there,

Michael Pyne recently "repaired" an ugly bug in CGI kioslave and encouraged me
to contribute some documentation directly to KDE (thread in kfm-devel).

> Documentation for the CGI kioslave would indeed be nice however.  It doesn't 
> even have to be marked up or anything, the documentation team is fine with 
> plain text submissions.
> 
> Does anyone on the list have objections to me committing the fix then?  If not 
> I'll probably commit tomorrow.
> 
> Regards,
>  - Michael Pyne

The text listed below (can be used freely by KDE under whatever license) could 
be added behind the current CGI kioslave documentation. It's goal is to enable
experienced Linux Users to use the power of CGI/Bash/Konqueror for their own
scripts. The old documentation was not very helpfull without the source code.

An example of a more komplex CGI kioslave app can be found under:

     http://www.j-pfennig.de/LinuxImHaus/SyslogEinrichtenUndAnsehen.html

Yours Jürgen

==============================================================================
.... KDE 3.5.3 documentation text ....

Please note:
------------

The cgi kioslave needs to know where to find the script (or program) to
be executed. It searches in special folders that can be configured using
the kcontrol application (search for cgi). Alternatively you might press
Alt+F2 and type in "kcmshell kcmcgi". Add the folder where you keep
your script (or program) to the list.

Another important point is that your script must be executable. Type
something like "chmod 755 myscript" to be sure.

Examples:
---------

Two examples using bash scripting follow next to give you a starting
point and to demonstrate the power of the CGI kioslave. Combining
Bash (or another scripting language) with HTML (eventually using CSS
and Javascript) will allow you to write powerfull GUI applications
without any C++ programming!

Example 1
=========

This is the minimal CGI hello world program. The important line of
code is here the "Content-Type: text/html" thing that instructs konqueror
to render the output of the script as HTML.

    -----------------------------------------------------------------------
    #!/bin/bash

    # The HTTP header followed by an empty line:
    echo -e "Content-Type: text/html\n"

    # The content:
    echo "<html><h1>Hello World!</h1></html>"
    -----------------------------------------------------------------------

To make it work create a folder, save the above example as "demo1" and type
in a console window:

    chmod 775 demo1
    kwriteconfig --file kcmcgirc --group General --key Paths $PWD
    konqueror cgi:demo1

Beware: The way kwriteconfig is used above would clear all other registered
CGI paths. Consider 1st reading the Paths with kreadconfig and then merging
it with the new one.

Example 2
=========

The second example is a bit more complex and demonstrates four features:

1) Finding out if a script is called via CGI or from the command line
2) Checking if the script got input from an HTML Form
3) Converting the url encoded form input to text in bash variables
4) Escaping & and < in output to become HTML compatible

The example itself displays two pages, one prompts for input and the other
shows a result. The result page echoes the text from the input page and can
optionally display the environtment variables of the executing shell.

    -----------------------------------------------------------------------
    #!/bin/bash

    # function called when run from command line ...
    commandline_call() {
    echo "Please open Konqueror and enter 'cgi:${0##*/}' as url"
    exit 1
    }

    # function to format html content - input form
    input_page() {
    cat <<EOF
    <h2>An Input Form</h2>
    <form action="cgi:${0##*/}" method="GET">
    <table><tr>
    <td align=right>Display environment settings:</td>
    <td><input name="chkBox1" type="checkbox" value="x"></td>
    </tr>
    <tr>
    <td align=right>Type some text please:</td>
    <td><input name="txtText1"></td>
    </tr>
    <tr>
    <td colspan="2" align=center>
        <INPUT type="reset"> <INPUT type="submit"></td>
    </tr></table>
    </form>
    EOF
    }

    # Function to format html content - result page
    output_page() {

    # (3) convert url encoded query string to bash variables...
    set x ${QUERY_STRING//&/ }
    while [ $# -gt 1 ] ; do
        local nam="${2%%=*}" ; val="${2#*=}" ; shift
        local val="${val//\%5C/ }" ; val="${val//+/ }"
        read $nam <<<"$(printf "${val//\%/\x}")"
    done

    # (4) prepare html output: '&' -> '&' and '<' -> '&lt'
    local ltxt="${txtText1//&/&}" ; ltxt="${ltxt//</<}"

    # now create the output...
    echo "<h2>This is the Output Page</h2>"
    echo "<h3>Here comes the echo text: $ltxt</h3>"
    [ -n "$chkBox1" ] &&
        echo "<h3>The environment is:</h3><pre>$(set)</pre>"
    }

    # (1) Are we called from the command line?

    [ -z "$REQUEST_METHOD" ] && commandline_call

    # (2) Called via cgi - What action to take?

    echo -e "Content-Type: text/html\n"
    echo "<html><title>This is CGI Demo2</title>"

    [ -z "$QUERY_STRING" ] && input_page || output_page

    echo "<div style='margin-top: 2cm'>This is my footer</div></html>"
    -----------------------------------------------------------------------


Finding out if a script is called via CGI or from the command line
------------------------------------------------------------------

Use the REQUEST_METHOD variable - when called via CGI the content should
be "POST" or "GET". Otherwise the script was called as a command.


Checking if the script got input from an HTML Form
-----------------------------------------------

Here the "QUERY_STRING" variable is used. When a form uses the "GET"
method the input becomes encoded in a special way and is appended to the
url. Spaces in the input are replaced by + and multiple parameters
are separated by &. Most special characters get encoded by their
hexadecimal value.


Converting the url encoded form input to text in bash variables
---------------------------------------------------------------

It takes a bit of bash woodo to convert url parameters back to normal
text. The code in the example uses "printf" to convert back from
hexadecimal and "read" to set a local bash variable with the name of
the input field to the field's value. So if your input field was
named "txtHello" the result is a variable of that name containing
what the user typed into the form.

Escaping & and < in output to become HTML compatible
----------------------------------------------------

When you send back HTML encoded output to konqueror you have to
maintain syntactical correctness. At least you should replace the &
and < characters by HTML entities, which is what the example does.

Did you notice that this conversion is missing from the "set" command
output? So you got a buggy example! Can you fix it as an exercise?

Bugs and Limitations
--------------------

- Unfortunately KDE prior to 3.5.4 contained a bug that occasionally
  inserted extra spaces in the HTML sent back to konqueror. Depending
  on the output this sometimes corrupted the HTML rendering.

- Some 7 billion people on the planet will have to wait for KDE 4 to
  let CGI kioslave accept utf-8 or other specific chreacter encodings.
  Up to KDE 3.5.x a fixet build-in encoder for "latin1" is used. In
  later versions of KDE the charset keyword in the HTTP header will be
  used to select an encoder. Example:

    echo -e "Content-Type: text/html; charset: utf-8\n"

END




More information about the kfm-devel mailing list