By Bernhard Rupp
CGI scripting - this page now available in Serbo-Croatian and a Hungarian translation courtesy of Zsolt Boros
There is a little CGI script that decodes a space group. Just enter a valid space goup symbol or a spacegroup number (1-230) and voila! here we go:
Cool, isn't it? So how does it work?
Introduction
The web pages you actually see are the client side of a client-server connection through the internet. If your browser (the client) wants to see a web page, for example, it sends a request to the host you specify in the URL (Uniform Resource Locator) using the specified protocol (HTTP in this case, Hyper Text Transfer Protocol). Example for a URL : https://www.ruppweb.org/default.htm (protocol://site.domain/document). The site name is nothing but a name assigned to the IP address of the machine (example 128.115.150.112) running the (web) server. (NOTE : in this context the server is a program running the web service on the machine, not the computer itself - the computer is the host).
When the server receives such a request, it responds and sends back a page, or whatever the request was for. The language in which the server and client communicate is HTML (Hyper Text Markup Language). Beyond static requests for web pages, one may want the server to execute a certain task (such as searching a data base or decode a space group). There must be a mechanism for the server to receive information about what to do and to hand it down to the application that handles the request. This interface is the CGI (Common Gateway Interface). The server essentially sets certain system environment variables, which the called program can read and process. The output is passed back to the server forwarding it through the internet to the requesting browser which displays the result. You may want to check out the Microsoft Internet Development CD or the other references for more information on the subject.
Example
In this web page I used following script to create the input box and define the action to be taken :
<form action="/cgi-bin/sexie_linux" method="GET"> <p>Enter a spacegroup or spacegroup number <input type="text" size="11" name="spcgrp"> and hit enter</p> </form>
This minimal code creates the above input box, assigns the input to the variable named 'spcgrp' and executes the program sexie32 which does the job. How do I get the space group variable into the program? By specifying GET as method, the server adds the variable name and its contents after a question mark to the program name and stores this string in an environment variable QUERY_STRING. All the program does is read this environment variable string, decode it, and after the calculation, write the result as an HTML file to the standard output (console) which the server redirects to the requester. Most scripting languages provide libraries and one does not have to deal with the details of reading the system environment.
FORTRAN
As scientists, we may have a useful program in FORTAN that does a nice job and it would be desirable to make it available on the web. The obvious benefit is that you do not have to deal with platform and implementation issues - no unvalidated version proliferation, no source code mess etc - the application runs on your host computer, and the browsers take care of the platform specific implementation. All of a sudden your old F66 code has a graphical windows interface!
Subroutine WEBSPC reads the environment variables and returns the spacegroup string to the main routine :
subroutine webspc (spcgrp,title,igr,ierr) WEBS0001
c ----------------------------------------------------------------------WEBS0002
c returns space group passed from web server through GET method WEBS0003
c ----------------------------------------------------------------------WEBS0004
USE MSFLIB WEBS0005
integer*4 lstr WEBS0006
integer igr(36) WEBS0007
character today*24,spcgrp*10,title*60,usradd*15,fname*60,qstr*80 WEBS0008
character usrnam*80,browsr*80 WEBS0009
WEBS0010
c --- Set spacegroup blank WEBS0011
spcgrp=' ' WEBS0012
ierr=0 WEBS0013
Here is how to read the environment variables which were set by the server according to the action instructions in the HTML code fragment above. You'll find a listing of other variables that are set in most books on web programming (some of them are read by webspc as well). The key is QUERY_STRING which contains the variable part of the URL constructed by the action listed above:
https://ruppweb.org/cgi-bin/sexie-linux?spcgrp=I+4%2Fm+m+m
QUERY_STRING contains: spcgrp=I+4%2Fm+m+m (NOTE: if you enter the URL above or click it, the CGI script will actually be executed). Notice also that the CGI interface substitutes blanks with + signs and special characters with their hexadecimal code preceeded by a % sign (e.g., the slash is %2F). The actual input string in the box was 'I 4/m m m' in this case.
WEBS0014
c --- get the client name and the query_string from environment WEBS0015
ladd = GETENVQQ('REMOTE_ADDR', usradd) WEBS0016
lnam = GETENVQQ('REMOTE_USR', usrnam) WEBS0017
lbrs = GETENVQQ('HTTP_USER_AGENT', browsr) WEBS0018
lstr = GETENVQQ('QUERY_STRING', qstr) WEBS0019
WEBS0020
c --- read space group - if an integer decode by number WEBS0021
read(qstr,'(7x,i3)',err=0001) ispa WEBS0022
c --- if we get here, it was read successfully as a number WEBS0023
Note that I use the error label when reading the symbol as a integer to distinguish whether a space group symbol or a space group number was entered.
call spsymc (spcgrp,ispa) WEBS0024
c --- ispa returns the symbol now proceed with checks WEBS0025
goto 2002 WEBS0026
WEBS0027
c --- parse the input string if not a number WEBS0028
0001 continue WEBS0029
ilen=lstr-7 WEBS0030
j=0 WEBS0031
c --- begin loop over query_string WEBS0032
Notice that the CGI interface substitutes blanks with + signs and special characters with hexadecimal code preceeded by a % sign (e.g., / is %2F), so we need to parse that string:
i=8 WEBS0033
1000 continue WEBS0034
c --- replace + with blank WEBS0035
if (qstr(i:i).eq.'+') then WEBS0036
j=j+1 WEBS0037
spcgrp(j:j)=' ' WEBS0038
i=i+1 WEBS0039
c --- replace special character hex code with character WEBS0040
else if (qstr(i:i).eq.'%') then WEBS0041
c --- %2F is slash WEBS0042
if (qstr(i+1:i+2).eq.'2F') then WEBS0043
j=j+1 WEBS0044
spcgrp(j:j)='/' WEBS0045
i=i+3 WEBS0046
end if WEBS0047
else WEBS0048
j=j+1 WEBS0049
spcgrp(j:j)=qstr(i:i) WEBS0050
i=i+1 WEBS0051
end if WEBS0052
c --- repeat until finished with string WEBS0053
if (i.lt.(ilen+8)) goto 1000 WEBS0054
WEBS0055
c --- now check if a valid space group symbol WEBS0056
2002 call upstrg(spcgrp,10) WEBS0057
read(spcgrp,'(10a1)') (igr(i), i=1,10) WEBS0058
ispa=0 WEBS0059
call spsymc (spcgrp,ispa) WEBS0060
WEBS0061
c --- get a date string, format is :Wed Nov 20 15:33:29 1996 WEBS0062
call fdate (today) WEBS0063
title='Webjob on '//today(1:10)//today(20:24)//' at'// WEBS0064
& today(11:19) //' from '//usradd WEBS0065
The program also keeps a log of the users.
c --- log the job WEBS0066
fname='C:\inetsrv\wwwroot\webjobs.html' WEBS0067
open (66,file=fname,access='append',position='append') WEBS0068
c --- overwrite old </body> tag WEBS0069
backspace (66) WEBS0070
write(66,'(a,a,a)')' <p>Date : '//today//'<br>' WEBS0071
write(66,'(a,a,a)')' Client : '//usradd(1:ladd)//'<br>' WEBS0072
write(66,'(a,a,a)')' Browser : '//browsr(1:lbrs)//'<br>' WEBS0073
write(66,'(a,a,a)')' Spacegr: '//spcgrp//'<br>' WEBS0074
if (ispa.lt.0) then WEBS0075
write(66,'(a)')' Status : failed!</p>' WEBS0076
else WEBS0077
write(66,'(a)')' Status : ok</p>' WEBS0078
end if WEBS0079
write(66,'(a)') ' <hr>' WEBS0080
write(66,'(a)') ' </BODY>' WEBS0081
close(66) WEBS0082
c --- if something went wrong, return message and termination signal WEBS0083
if (ispa.lt.0) then WEBS0084
call webtxt (1,spcgrp) WEBS0085
ierr=1 WEBS0086
close(5) WEBS0087
return WEBS0088
else WEBS0089
close(5) WEBS0090
return WEBS0091
end if WEBS0092
return WEBS0093
end WEBS0094
The variable spcgrp gets returned to the main routine which decodes the space group. The output is written to a file, and all that is needed is a tiny routine to write this output as a HTML file to the standard output (console).
subroutine htmake HTMA0001
HTMA0002
character*80 line HTMA0003
HTMA0004
open(6,file='sexie.out') HTMA0005
write(*,*)'Content-type: text/html' HTMA0006
write(*,*) HTMA0007
write(*,*)'<BODY bgcolor="#FFFDE6" TEXT="#0000FF">' HTMA0008
write(*,*)'<TITLE>Space group decoding</TITLE>' HTMA0009
write(*,*)'<pre>' HTMA0010
do i=1,100000 HTMA0011
read(6,'(1x,a)',end=9999) line HTMA0012
write(*,'(1x,a)') line HTMA0013
end do HTMA0014
9999 close(6) HTMA0015
open(6,file='xyz.txt') HTMA0016
write(*,'(//a//)') HTMA0017
& ' Alternate listing of symmetry operators follows' HTMA0018
do i=1,100000 HTMA0019
read(6,'(1x,a)',end=9990) line HTMA0020
write(*,'(1x,a)') line HTMA0021
end do HTMA0022
9990 close(6) HTMA0023
write(*,*) '</pre>' HTMA0024
write(*,*) '</BODY>' HTMA0025
return HTMA0026
end HTMA0027
So, that's all there is to basic CGI scripting. Just go ahead, write a little code fragment yourself and play around a little. I used Microsoft Frontpage [2] to create my site and the forms, and Microsoft FORTRAN professional edition for the F90 programming. Your FORTRAN compiler may use a different way to get the environment variables, but you should be able to find this in your documentation. Of course, this is NOT an encouragement to write CGI scripts in Fortran. The executables are bulky and full with overhead, and for many tasks, C, Perl, J++ etc are faster. But if you have a solid peace of code, hey, why not make it useable on the web!
References
[1] CGI developer's guide, E.E.Kim,
SamsNet Publishing (1996)
[2] https://www.microsoft.com/frontpage/documents/technical11/default.htm
[3] Mastering Internet Development, Micosoft CD-ROM
Back to Introduction
This World Wide Web site conceived and maintained by
Bernhard Rupp
Last revised
December 27, 2009 01:40