FP to the rescue : CGI module

I'm rather chaotic in my projects. I start a topic. I get very enthusiastic. I make some thingies. And then I find another love. And it all happens again. Over and over. Same with the CGI topics. Luckily for me, I have a friend in Amsterdam which I affectionately refer to as FP. FP likes to tickle my mind so that I finnish some of the almost complete topics. Like this one: CGI with Mocka.

FP needed to know about the cgi MODULE to which I refer in some sources. He couldn't find them on the site. And right he was, since they're not there. So now is the time to tidy up a little bit.

CGI.DEF

Below is the definition module for the CGI modules. It exports CGI types and server data types. Plus three procedures that are required to have the browser believe the webpage is actually delivered by a webserver and not just by a mere CGI program. Read and hickup:

DEFINITION MODULE cgi;

FROM  Strings     IMPORT  String;

TYPE   ServerDataType = (Text, Html, Gif, Jpeg, PS, Mpeg);
       CGItype        = (ContentLength, GatewayInterface, HttpHost,
       		         HttpReferer,	QueryString,	  RemoteAddress,
		  	 RemoteHost,	RemotePort,	  RequestMethod,
		  	 ScriptName,	ServerAddress,	  ServerName,
		  	 ServerPort,	ServerProtocol,	  ServerSignature,
		  	 DocumentRoot,	RedirectStatus,	  RedirectUrl,
			 RedirectNotes,	none);


PROCEDURE InformServer (dataType : ServerDataType);

PROCEDURE CheckType (str : String) : CGItype;

PROCEDURE GetEnvVar (kind : CGItype; VAR  res : String) : BOOLEAN;

END cgi.
   

CGI.MOD

After this very difficult definition module :o) it's time for the implementation module. It's slightly more complex and slightly bigger. But not too difficult if you read some of the Wirth books.

IMPLEMENTATION MODULE cgi;

FROM  Arguments	  	IMPORT  GetEnv, ArgTable;
FROM  InOut		IMPORT  WriteLn, WriteString;
FROM  Strings	  	IMPORT  Assign, CAPS, pos, String;


VAR    content 	 	       : String;
       EnvTable		       : ArgTable;


PROCEDURE InformServer (dataType : ServerDataType);

BEGIN
   WriteString ('Content-type:');
   CASE  dataType  OF
     Text  :  WriteString ('text/plain')		|
     Html  :  WriteString ('text/html')			|
     Gif   :  WriteString ('image/gif')			|
     Jpeg  :  WriteString ('image/jpeg')		|
     PS	   :  WriteString ('application/postscript')	|
     Mpeg  :  WriteString ('video/mpeg')
   END;
   WriteLn;
   WriteLn 		  (* TWO linefeeds are required!  *)
END InformServer;


PROCEDURE CheckType (str : String) : CGItype;

BEGIN
   CAPS  (str);					(*  Convert entire string to capitals.	 *)
   IF  pos ('CONTENT_LENGTH', str) = 0  THEN  
      RETURN  ContentLength
   ELSIF  pos ('GATEWAY_INTERFACE', str) = 0  THEN  
      RETURN  GatewayInterface
   ELSIF  pos ('DOCUMENT_ROOT', str) = 0  THEN  
      RETURN  DocumentRoot
   ELSIF  pos ('HTTP_HOST', str) = 0  THEN  
      RETURN  HttpHost 
   ELSIF  pos ('HTTP_REFERER', str) = 0  THEN  
      RETURN  HttpReferer
   ELSIF  pos ('QUERY_STRING', str) = 0  THEN
      RETURN  QueryString
   ELSIF  pos ('REMOTE_ADDR', str) = 0  THEN  
      RETURN  RemoteAddress
   ELSIF  pos ('REMOTE_HOST', str) = 0  THEN  
      RETURN  RemoteHost
   ELSIF  pos ('REMOTE_PORT', str) = 0  THEN  
      RETURN  RemotePort
   ELSIF  pos ('REQUEST_METHOD', str) = 0  THEN  
      RETURN  RequestMethod
   ELSIF  pos ('SCRIPT_NAME', str) = 0  THEN  
      RETURN  ScriptName
   ELSIF  pos ('SERVER_ADDR', str) = 0  THEN  
      RETURN  ServerAddress
   ELSIF  pos ('SERVER_NAME', str) = 0  THEN  
      RETURN  ServerName
   ELSIF  pos ('SERVER_PORT', str) = 0  THEN  
      RETURN  ServerPort
   ELSIF  pos ('SERVER_PROTOCOL', str) = 0  THEN  
      RETURN  ServerProtocol
   ELSIF  pos ('SERVER_SIGNATURE', str) = 0  THEN  
      RETURN  ServerSignature
   ELSIF  pos ('REDIRECT_STATUS', str) = 0  THEN  
      RETURN  RedirectStatus
   ELSIF  pos ('REDIRECT_URL', str) = 0  THEN  
      RETURN  RedirectUrl
   ELSIF  pos ('REDIRECT_ERROR_NOTES', str) = 0  THEN  
      RETURN  RedirectNotes
   ELSE
      RETURN none
   END
END CheckType;


PROCEDURE GetEnvVar (kind : CGItype; VAR  res : String) : BOOLEAN;

VAR   found 		 : BOOLEAN;
      i, j     		 : CARDINAL;
      TexBuf		 : String;
      type		 : CGItype;

BEGIN
   found := FALSE;
   i := 0;
   LOOP
      IF  EnvTable^ [i] = NIL  THEN  EXIT  END;
      Assign (TexBuf, EnvTable^ [i]^);
      IF  CheckType (TexBuf) = kind  THEN
         found := TRUE;
         EXIT  
      END;
      INC (i);
   END;
   IF  NOT found  THEN  RETURN FALSE  END;
   i := 0;
   LOOP
      IF  TexBuf [i] = '='  THEN  EXIT  END;
      INC (i);
   END;
   INC (i);
   j := 0;
   LOOP
      res [j] := TexBuf [i];
      INC (i);
      INC (j);
      IF  ( j > HIGH (res) ) OR ( i > HIGH (TexBuf) )  THEN  EXIT  END;
      IF  TexBuf [i] = 0C  THEN  
         res [j] := 0C;
	 EXIT
      END
   END;
   RETURN TRUE
END GetEnvVar;


BEGIN
   GetEnv (EnvTable)
END cgi.
   
It may be a bit clumsy or over structured, but it works and gets the job done. For the time being this is what I need. Perhaps later. I rely on FP here. He can make me move mountains.

Page created on 10 December 2007 and