SheerPower® 4GL
A Guide to the SheerPower Language


Previous Contents Index

Emails are queued for sending when the file is closed. If WAIT was specified, then SheerPower waits until the email is delivered before continuing processing. The default is NOWAIT.

For high reliability on sending emails with SheerPower 4GL, the SMTP server should be either on the same server as SheerPower or at least on the same LAN. This is because the SheerPower 4GL email handler is not a full email system that endlessly tries to send out emails even if the application has terminated.

The best use for the SheerPower email facility is:

SheerPower --> SMTP server (local one) --> Internet for delivery

This way there will be very few delays and reliability will be highest.

19.3 Webserver CGI Interface

Preparation

SheerPower applications can easily be "web-enabled" through its simple CGI Interface. The CGI interface works with SheerPower's own webserver program, SPINS webserver. For more information on SPINS webserver, see Chapter 18, SheerPower Internet Services (SPINS) Webserver.

19.3.1 SheerPower 4GL CGI Interface Sample Program

The sample CGI program eval_handler.spsrc is located in:


  c:\sheerpower\sphandler 

The webpage instructions that go along with the sample program is located in the same folder, and is called cgi.html.

19.3.2 Testing the CGI Interface

To use the CGI interface in SheerPower, SPINS Webserver must be running. If the Microsoft IIS webserver is running, it needs to be stopped, or ports configured to run both webservers at the same time. Instructions are found here - Section 18.1.3, Specify a Different Port Number.

To continue with this test, double-click on the EVAL_HANDLER.SPSRC file. This runs the EVAL_HANDLER program. This program file is located in:

c:\sheerpower\sphandlers\eval_handler.spsrc

After the EVAL_HANDLER has been started, you can try the FORM below.

After entering an expression, press the ENTER key. To get back to this webpage, click on the browser's BACK button.

Enter an expression, like sin(355/113) then press the ENTER key:

If the form does not work..

If this form did not work correctly for you, see Appendix L, Troubleshooting the CGI Interface.

How this form works

Each time anyone enters an expression to evaluate (like 2+3), their browser sends the data to your SPINS webserver along with a handler name. In this example, the handler name is EVAL. The SPINS websever then passes the data to the EVAL_HANDLER.SPSRC SheerPower program. The EVAL_HANDLER handles the request, figures out the result, and sends the result back to the SPINS server. The SPINS server then sends the result back to the browser.

Important Note on the Handler Name

The handler name defined in the source code MUST be defined in UPPER CASE.

19.3.3 How the EVAL_HANDLER Program Works

In order to handle CGI requests, the following steps need to be taken:

First we open our CGI connection to the SPINS server.


    handler_name$ = 'cgi://EVAL' 
    open file cgi_ch: name handler_name$ 

In this example, EVAL is the HANDLER NAME.

Note that the handler name defined in the source code MUST be defined in UPPER CASE.

For higher performance, you can run as many copies of this handler as you wish. The SheerPower CGI interface will queue all requests to these handlers that have the form:


    http://www.ttinet.com/scripts/spiis.dll/EVAL 

Next we set up a logic loop to wait for requests, handle timeouts, and process each request.


    do
      line input #cgi_ch: method$ 
      if method$ = '' then repeat do
      .. 
      .. 
    loop

19.3.4 Waiting for CGI Requests

The LINE INPUT waits for a request from the SPINS server. When the LINE INPUT completes, the variable METHOD$ will contain one of three values.

In this program, when there is no request from the SPINS server (a timeout), we just go back and try again. In complex applications a program might instead unlock databases, write out statistics, and then go back and try again.

19.3.5 Processing CGI Requests

Now that we have a request from the SPINS server, we have to process the request.


  ask #cgi_ch, symbol 'EXPR': value expr$ 
  if  expr$ = '' then
    print #cgi_ch: '<h2>Thank you for using the Evaluator!</h2>' 
    repeat do
  end if
  
  when exception in
    answer = eval(expr$) 
  use
    answer = extext$ 
  end when
  if dtype(answer) <> 1 then answer = str$(answer) 
  print #cgi_ch: '<h2>'; expr$; ' --> '; answer; '</h2>' 
  
  ask #cgi_ch, symbol 'env:REMOTE_ADDR': value ipaddr$ 
  print #cgi_ch: '(Your IP address is '; ipaddr$; ')' 

This form returns one form variable---the expression to be evaluated (EXPR). We use the SheerPower ASK instruction to ask for its value.


  ask #cgi_ch, symbol 'EXPR': value expr$ 

If they didn't enter any expression, we just tell them "Thank you...". This is done using the PRINT instruction.

print #cgi_ch: '<h2>Thank you for using the Evaluator!</h2>'

Using EXPR$, we calculate the ANSWER and PRINT the result back to the SPINS server.

print #cgi_ch: '<h2>'; expr$; ' --> '; answer; '</h2>'

Finally, we ask the SPINS server for the "REMOTE_ADDR". This is the IP address of the requestor. Since "REMOTE_ADDR" is an environmental variable, we must put "env:" in front of the symbol name. Once we get the IP address, we PRINT it to the SPINS server---which, in turn, sends the data back to the browser.


  ask #cgi_ch, symbol 'env:REMOTE_ADDR': value ipaddr$ 
  print #cgi_ch: '(Your IP address is '; ipaddr$; ')' 

19.3.6 Building CGI Custom HTTP Headers

By default, SheerPower automatically builds the CGI required HTTP headers. But, sometimes there is a need to write out your own custom HTTP headers. For example, you might need to write out binary data, or perhaps send a cookie. Here is a sample routine that writes out a HTTP header:


    routine start_http_output 
      ask #cgi_ch, symbol 'env:PATH_INFO': value path_info$ 
      print #cgi_ch: "HTTP/1.1 200 OK" 
      print #cgi_ch: 'Cache-Control: max-age=2, must-revalidate' 
      print #cgi_ch: "Content-type: text/html" 
      print #cgi_ch: 'Referer: ' + path_info$ 
      print #cgi_ch: "Pragma: no-cache" 
      print #cgi_ch: 
      print #cgi_ch: 
    end routine 

Note

When printing out binary data, include a trailing semi-colon at the end of the PRINT instruction:

print #cgi_ch: mybinary$; // notice the trailing semi-colon

19.3.7 CGI Interface Performance Considerations

The SheerPower CGI interface was designed for very high performance. If the server it is running on has multiple CPUs, full advantage of the CPUs can be taken by running multiple copies of the same HANDLER. A good "rule of thumb" is to run at least two HANDLERS for each CPU on the server. Idle handlers consume very little cpu-time---less than 1/10th of 1% of available CPU-time for each idle handler.

19.3.8 Summary of CGI Environment Variables

FORMAT:


        ASK #cgi_ch, SYMBOL 'ENV:environment_variable : VALUE x$ 

EXAMPLE:

Example 19-3 Environment Variables

// This sample program can be found in 
// SheerPower/sample/sphandlers/eval_handler.spsrc 
// It is also the sample program used to illustrate 
// and test the CGI Interface in SheerPower, also 
// in this chapter (Webserver CGI Interface) 
 
declare object answer 
handler_name$ = 'cgi://EVAL' 
 
print 'Eval Handler started '; date$(days(date$), 4);' at '; time$ 
 
open file cgi_ch: name handler_name$ 
do
  line input #cgi_ch: method$ 
  if method$ = '' then repeat do
  ask #cgi_ch, symbol 'EXPR': value expr$ 
  if  expr$ = '' then
    print #cgi_ch: '<h2>Thank you for using the Evaluator!</h2>' 
    repeat do
  end if
 
  when exception in
    answer = eval(expr$)
  use
    answer = extext$ 
  end when
  if dtype(answer) <> 1 then answer = str$(answer) 
  print #cgi_ch: '<h2>'; expr$; ' --> '; answer; '</h2>' 
 
  ask #cgi_ch, symbol 'env:REMOTE_ADDR': value ipaddr$ 
  print #cgi_ch: '(Your IP address is '; ipaddr$; ')' 
 
loop
close #cgi_ch 
stop
 
end


Previous Next Contents Index