Addendum to the X11-Basic User Manual
This document is not the user manual for X11-Basic. You can find the user manual and command reference im here: http://x11-basic.sourceforge.net/.
1. WEB Programming with X11-Basic
This chapter explains how you can use X11-Basic programs for WEB-interfacing. Especially via the use of so-called CGI-Scripts.
1.1. What is CGI?
CGI stands for Common Gateway Interface --- a term you don’t really need to know. In short, CGI defines how web servers and web browsers handle information from HTML forms on web pages. This means instead of the WEB server sending static web pages to the clients, it can invoke a program, typically called a cgi-script, to generate the page on the time the request was received. These cgi-scripts take some action, and then send a results page back to the user’s web browser. The results page might be different every time the program is run.
And these programs can be X11-Basic programs.
1.1.1. Configuration
-
All X11-Basic scripts must begin with the following statement on the first line:
#!/usr/bin/xbasic
Because Unix does not map file suffixes to programs, there has to be a way to tell Unix that this file is a X11-Basic program, and that it is to be executed by the X11-Basic interpreter
xbasic
. This is seen before in shell scripts, in which the first line tells Unix to execute it with one of the shell programs. The xbasic executable, which will take this file, parse it, and execute it, is located in the directory/usr/bin
. This may be different on some systems. If you are not sure where the xbasic executable is, typewhich xbasic
on the command line, and it will return you the path. -
All scripts should be marked as executable by the system.
Executable files are types that contain instructions for the machine or an interpreter, such as xbasic, to execute. To mark a file as executable, you need to alter the file permissions on the script file. X11-Basic files should have their permissions changed so that you, the owner, has permission to read, write and execute your file, while others only have permission to read and execute your file. This is done with the following command:
chmod 755 filename.bas
The number 755 is the file access mask. The first digit is your permission; it is 7 for full access. The user and anyone settings are 5 for read and execute.
-
The very first print statement in a X11-Basic cgi script that returns HTML should be:
PRINT "Content-type: text/html"+CHR$(13) PRINT ""+CHR$(13) FLUSH
When your X11-Basic script is going to return an HTML file, you must have this as the very first print statement in order to tell the web server that this is an HTML file. There must be two end of line characters (CR+LF) (the additional
chr$(13)
) in order for this to work. The flush statement ensures, that this statement is sent to the web-server. After that, you usually do aPRINT "<HTML><BODY>" .... and so on ...
-
End your program with
QUIT
.Do not use
END
. Otherwise the cgi-program will remain is the servers memory as a zombie. -
Always use the POST method with HTML forms.
There are 2 ways to get information from the client to the web server. The GET method takes all of the data from the forms and concatenates it onto the end of the URL. This information is then passed to the CGI program as an environment variable (
QUERY_STRING
). Because the GET method has the limitation of being 1024 characters long, it is best to use the POST method. This takes the data and sends it along with the request to the web server, without the user seeing the ugly strings in the URL. This information is passed to the CGI program through standard in, which the program can easily read from. To use the POST method, make sure that your HTML form tag hasMETHOD=POST
(no quotes). -
HTML forms must reference the cgi script to be executed.
In your FORM tag, there is an ACTION attribute. This is like the HREF attribute for a link. It should be the URL of the CGI program you want the form data sent to. Usually this is
ACTION="/cgi-bin/filename.bas"
. -
X11-Basic-cgi files usually go in the
cgi-bin
directory of your web server.The web server has a "root" directory. This is the highest directory your HTML files can access. (You don’t want clients to be able to snoop around your entire system, so the rest of the system is sealed off) in this directory, there is usually one called cgi-bin, where all the CGI programs go. Some web service providers give each user a cgi-local directory in their home directory where they can put their cgi scripts. If this is the case, use this one instead.
1.2. How it works
When a user activates a link to a gateway script, input is sent to the server. The server formats this data into environment variables and checks to see whether additional data was submitted via the standard input stream.
1.2.1. Environment Variables
Input to CGI scripts is usually in the form of environment variables. The environment variables passed to gateway scripts are associated with the browser requesting information from the server, the server processing the request, and the data passed in the request. Environment variables are case-sensitive and are normally used as described in this section. The standard (and platform independent) environment variables are shown in the following table:
Variable |
Purpose |
|
Specifies the authentication method and is used to validate a user’s access. |
|
Used to provide a way of tracking the length of the data string as a numeric value. |
|
Indicates the MIME type of data. |
|
Indicates which version of the CGI standard the server is using. |
|
Indicates the MIME content types the browser will accept, as passed to the gateway script via the server. |
|
Indicates the type of browser used to send the request, as passed to the gateway script via the server. |
|
Identifies the extra information included in the URL after the identification of the CGI script. |
|
Set by the server based on the |
|
Set to the query string (if the URL contains a query string). |
|
Identifies the Internet Protocol address of the remote computer making the request. |
|
Identifies the name of the machine making the request. |
|
Identifies the machine making the request. |
|
Identifies the user name as authenticated by the user. |
|
Indicates the method by which the request was made. |
|
Identifies the virtual path to the script being executed. |
|
Identifies the server by its host name, alias, or IP address. |
|
Identifies the port number the server received the request on. |
|
Indicates the protocol of the request sent to the server. |
AUTH_TYPE
|
The Using this mechanism, the server can challenge a client’s request and the
client can respond. To do this, the server sets a value for the
|
||||||||||||||||||||||||||||||||||||||||||||||||
CONTENT_LENGTH
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
CONTENT_TYPE
|
The
MIME subtypes are defined in three categories: primary, additionally defined, and extended. The primary subtype is the primary type of data adopted for use as a MIME content type. Additionally defined data types are additional subtypes that have been officially adopted as MIME content types. Extended data types are experimental subtypes that have not been officially adopted as MIME content types. You can easily identify extended subtypes because they begin with the letter x followed by a hyphen. The following Table lists common MIME types and their descriptions.
Note, that there are more than the above listed types. Some MIME content types can be used with additional parameters. These content
types include text/plain, text/html, and all multi-part message data. The
charset parameter, which is optional, is used with the text/plain type to
identify the character set used for the data. If a charset is not specified, the
default value CONTENT_TYPE = text/plain; charset=iso-8859-1 The boundary parameter, which is required, is used with multi-part data to identify the boundary string that separates message parts. The boundary value is set to a string of 1 to 70 characters. Although the string cannot end in a space, it can contain any valid letter or number and can include spaces and a limited set of special characters. Boundary parameters are unique strings that are defined as follows: CONTENT_TYPE = multipart/mixed; boundary=boundary_string |
||||||||||||||||||||||||||||||||||||||||||||||||
GATEWAY_INTERFACE
|
The GATEWAY_INTERFACE = name/version The version of the CGI specification is 1.1. A server conforming
to this version would set the GATEWAY_INTERFACE = CGI/1.1 |
||||||||||||||||||||||||||||||||||||||||||||||||
HTTP_ACCEPT
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
HTTP_USER_AGENT
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
PATH_INFO
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
PATH_TRANSLATED
|
Servers translate the |
||||||||||||||||||||||||||||||||||||||||||||||||
QUERY_STRING
|
The URL:
/cgi-bin/doit.cgi?string When the query string is URL-encoded, the browser encodes key parts of the string. The plus sign is a placeholder between words and acts as a substitute for spaces: URL:
/cgi-bin/doit.cgi?word1+word2+word3 Equal signs separate keys assigned by the publisher from values entered by the user. In the following example, response is the key assigned by the publisher, and never is the value entered by the user: URL:
/cgi-bin/doit.cgi?response=never Ampersand symbols ( URL:
/cgi-bin/doit.cgi?response=sometimes&reason=I+am+not+really+sure Finally, the percent sign is used to identify escape characters. Following the percent sign is an escape code for a special character expressed as a hexadecimal value. Here is how the previous query string could be rewritten using the escape code for an apostrophe: URL:
/cgi-bin/doit.cgi?response=sometimes&reason=I%27m+not+really+sure |
||||||||||||||||||||||||||||||||||||||||||||||||
REMOTE_ADDR
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
REMOTE_HOST
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
REMOTE_IDENT
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
REMOTE_USER
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
REQUEST_METHOD
|
The The |
||||||||||||||||||||||||||||||||||||||||||||||||
SCRIPT_NAME
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
SERVER_NAME
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
SERVER_PORT
|
The |
||||||||||||||||||||||||||||||||||||||||||||||||
SERVER__PROTOCOL
|
The |
1.2.2. CGI Standard Input
Most input sent to a Web server is used to set environment variables, yet not all input fits neatly into an environment variable. When a user submits data to be processed by a gateway script, this data is received as an URL-encoded search string or through the standard input stream. The server knows how to process this data because of the method (either POST or GET in HTTP 1.0) used to submit the data.
Sending data as standard input is the most direct way to send data. The server tells the gateway script how many eight-bit sets of data to read from standard input. The script opens the standard input stream and reads the specified amount of data. Although long URL-encoded search strings may get truncated, data sent on the standard input stream will not. Consequently, the standard input stream is the preferred way to pass data.
1.2.3. Which CGI Input Method to use?
You can identify a submission method when you create your fill-out forms.
Two submission methods for forms exist. The HTTP GET
method uses URL-encoded search strings. When a server receives an
URL-encoded search string, the server assigns the value of the search
string to the QUERY_STRING
variable.
The HTTP POST method uses the standard input streams. When a server
receives data by the standard input stream, the server assigns the value
associated with the length of the input stream to the CONTENT_LENGTH
variable.
1.2.4. Output from CGI Scripts
After the script finishes processing the input, the script should return output to the server. The server will then return the output to the client. Generally, this output is in the form of an HTTP response that includes a header followed by a blank line and a body. Although the CGI header output is strictly formatted, the body of the output is formatted in the manner you specify in the header. For example, the body can contain an HTML document for the client to display.
1.2.5. CGI Headers
CGI headers contain directives to the server. Currently, these three server directives are valid:
-
Content-Type
-
Location
-
Status
A single header can contain one or all of the server directives. Your CGI script outputs these directives to the server. Although the header is followed by a blank line that separates the header from the body, the output does not have to contain a body.
The Content-Type field in a CGI header identifies the MIME type of the data you are sending back to the client. Usually the data output from a script is a fully formatted document, such as an HTML document. You could specify this output in the header as follows:
Content-Type: text/html
But of course, if your program outputs other data like images etc. you should specify the corresponding content type.
- Location
-
The output of your script doesn’t have to be a document created within the script. You can reference any document on the Web using the Location field. The Location field references a file by its URL. Servers process location references either directly or indirectly depending on the location of the file. If the server can find the file locally, it passes the file to the client. Otherwise, the server redirects the URL to the client and the client has to retrieve the file. You can specify a location in a script as follows:
Location: http://www.new-jokes.com/
- Status
-
The Status field passes a status line to the server for forwarding to the client. Status codes are expressed as a three-digit code followed by a string that generally explains what has occurred. The first digit of a status code shows the general status as follows:
1XX Not yet allocated 2XX Success 3XX Redirection 4XX Client error 5XX Server error
Although many status codes are used by servers, the status codes you pass to a client via your CGI script are usually client error codes. Suppose the script could not find a file and you have specified that in such cases, instead of returning nothing, the script should output an error code. Here is a list of the client error codes you may want to use:
401 Unauthorized Authentication has failed. User is not allowed to access the file and should try again. 403 Forbidden. The request is not acceptable. User is not permitted to access file. 404 Not found. The specified resource could not be found. 405 Method not allowed. The submission method used is not allowed.
1.3. An Example cgi-Script
Here is a simple sample cgi-script, which simply returns all the information which it gets from the web server as a html page.
#!/usr/bin/xbasic PRINT "Content-type: text/html"+CHR$(13) PRINT ""+CHR$(13) FLUSH PRINT "<html><head><TITLE>Test CGI</TITLE><head><body>" PRINT "<h1>Commandline:</h1>" i=0 WHILE LEN(PARAM$(i)) PRINT STR$(i)+": "+PARAM$(i)+"<br>" INC i WEND PRINT "<h1>Environment:</h1><pre>" FLUSH ! flush the output before another program is executed ! SYSTEM "env" PRINT "</pre><h1>Stdin:</h1><pre>" length=VAL(ENV$("CONTENT_LENGTH")) IF length FOR i=0 TO length-1 t$=t$+CHR$(inp(-2)) NEXT i PRINT t$ ENDIF PRINT "</pre>" PRINT "<FORM METHOD=POST ACTION=/cgi-bin/envtest.cgi>" PRINT "Name: <INPUT NAME=name><BR>" PRINT "Email: <INPUT NAME=email><BR>" PRINT "<INPUT TYPE=submit VALUE="+CHR$(34)+"Test POST Method"+CHR$(34)+">" PRINT "</FORM>" PRINT "<hr><h6>(c) Markus Hoffmann cgi with X11-basic</h6></body></html>" FLUSH QUIT
2. Acknowledgements
Portions of this chapter come from or are based on documentation that was used in the 1990s. (I hope it was public domain or something like that.) Unfortunately I lost the link to its source. If you know your potential source, let me know. Then I can quote it here and thank the author.