IBM Books

HTTP Server for AS/400 Web Programming Guide


Sample CGI programs (in Java, C, and RPG)

This chapter contains samples of coding in Java, C, and RPG languages.

You can locate programming samples through the following URL:

http://www.as400.ibm.com/tstudio/index.htm

Example of Java language CGI program

The samplejava program takes environmental and form variables and displays them back to the browser.



import java.io.DataInputStream;
import java.util.Hashtable;
import java.util.StringTokenizer;
 
class samplejava
{
 
         int x;
         int index;
         Hashtable cgi_vars = null;
 
         // String table with all the Environment Variables
 
         String[] EnvVar = { "GATEWAY_INTERFACE",
                        "SERVER_NAME",
                        "SERVER_SOFTWARE",
                        "SERVER_PROTOCOL",
                        "SERVER_PORT",
                        "PATH_INFO",
                        "PATH_TRANSLATED",
                        "SCRIPT_NAME",
                        "DOCUMENT_ROOT",
                        "REMOTE_HOST",
                        "REMOTE_ADDR",
"AUTH_TYPE",
                        "REMOTE_USER",
                        "REMOTE_IDENT",
                        "HTTP_FROM",
                        "HTTP_ACCEPT",
                        "HTTP_USER_AGENT",
                        "HTTP_REFERER",
                        "REQUEST_METHOD",
                        "CONTENT_TYPE",
                        "CONTENT_LENGTH",
                        "QUERY_STRING"};
 

samplejava()
{
 
        String userMethod;
        String cl;
        cl = new String();
        // Get the REQUEST_METHOD variable  (POST or GET)
        userMethod = System.getProperty("REQUEST_METHOD");
 
        if (userMethod != null)
        {
           if (userMethod.equalsIgnoreCase("POST"))
           {
             System.out.println("Server method not supporting");
             System.exit(0);
            }
           else
           {
               // if the method is GET
               if (userMethod.equalsIgnoreCase("GET"))
               {
                   // Get the Value of Query String
                   cl = System.getProperty("QUERY_STRING");
               }
               else
               {
                  errMsg("Invalid REQUEST_METHOD specified");
                  System.exit(0);
                }
             }
          }
          else
          {
            // Print No method
            errMsg ("No REQUEST_METHOD specified");
            System.exit(0);
           }
 
           if (cl == null )
           {
                  errMsg ("No user data");
                  System.exit(0);
            }
            else
            {
                   // fill the Hash table with the user values
                   cgi_vars = parseArguments(cl);
            }
      }
 

   private Hashtable parseArguments (String query_string)
   {
      Hashtable cgi_vars = new Hashtable();
 
      // get the first token scan for the '&' char
      StringTokenizer stringToken = new StringTokenizer(query_string,"&");
 
      while (stringToken.hasMoreTokens())
      {
       index++;
       // Split the first token into Variable and Value
       StringTokenizer subToken = new StringTokenizer(stringToken.nextToken(),"=");
 
       // Remove the '+' char from the Variable
       String variable = plussesToSpaces(subToken.nextToken());
 
       // Remove the '+' char from the Value
       String value = plussesToSpaces(subToken.nextToken());
 
       // Create the Keys to store the Variables and the Values in the Hash Table
       // the keys will be variable1, value1, variable2, value2, and so forth
       String temp1= new String("variable"+index);
       String temp2= new String("value"+index);
 
       // Store the variables and the values in the Hash table
       cgi_vars.put(temp1,translateEscapes(variable));
       cgi_vars.put(temp2,translateEscapes(value));
                
      }
      return cgi_vars;
   }
 private String plussesToSpaces(String query_string)
      {
 
        // Substitute the '+' char to a blank char
        return query_string.replace('+', ' ');
 
      }
 
   private String translateEscapes(String query_string)
   {
     int percent_sign = query_string.indexOf('%');
     int ascii_val;
     String next_escape=null;
     String first_part=null;
     String second_part=null;
 
     while (percent_sign != -1)
     {
      next_escape = query_string.substring(percent_sign + 1, percent_sign + 3);
      ascii_val = (16 * hexValue(next_escape.charAt(0)) + hexValue(next_escape.charAt(1)));
      first_part = query_string.substring(0, percent_sign);
      second_part = query_string.substring(percent_sign + 3, query_string.length());
      query_string = first_part + (char)ascii_val + second_part;
      percent_sign = query_string.indexOf('%', percent_sign + 1);
     }
     return query_string;
    
 
 

    private int hexValue(char c)
       {
       int rc;
 
       switch(c)
            {
             case '1':
                  rc = 1;
                  break;
             case '2':
                  rc = 2;
                  break;
             case '3':
                  rc = 3;
                  break;
             case '4':
                  rc = 4;
                  break;
             case '5':
                  rc = 5;
                  break;
             case '6':
                  rc = 6;
                  break;
             case '7':
                  rc = 7;
                  break;
             case '8':
                  rc = 8;
                  break;
             case '9':
                  rc = 9;
                  break;
             case 'a':
             case 'A':
                  rc = 10;
                  break;
             case 'b':
             case 'B':
                  rc = 11;
                  break;
             case 'c':
             case 'C':
                  rc = 12;
                  break;
             case 'd':
             case 'D':
                  rc = 13;
                  break;
             case 'e':
             case 'E':
                  rc = 14;
                  break;
             case 'f':
             case 'F':
                  rc = 15;
                  break;
             default:
                  rc = 0;
                  break;
             }
   return rc;
   }
 
 
 

 private void errMsg(String message)
    {
 
    System.out.println("Content-type: text/html\n");
    System.out.println("<html>");
    System.out.println("<head>");
    System.out.println("<title>Error</title>");
    System.out.println("</head>");
    System.out.println("<body>");
    System.out.println("<h1>Error</h1>");
    System.out.println("<hr>");
    System.out.println("<p>");
    System.out.println("An internal error occurred.");
    System.out.println("The specific error message is shown below:");
    System.out.println("<p><pre>" + message + "</pre><p>");
    System.out.println("<p>");
    System.out.println("<hr>");
    System.out.println("</body>");
    System.out.println("</html>");
     }
 
private void display()
{
       System.out.println("Content-type: text/html\n");
       System.out.println("<html>");
       System.out.println("<head>");
       System.out.println("<title>Environment and User Variables</title>");
       System.out.println("</head>");
       System.out.println("<body>");
       System.out.println("<h1>Environment and User variables</h1>");
       System.out.println("<h2>Environment Variables</h2>");
       System.out.println("<table>");
 
       for (int i=0; i<22; i++)
           {
                if (System.getProperty(EnvVar[i]) != null)
                {
                  System.out.println("<tr>");
                {
                  System.out.println("<tr>");
                  System.out.println("<td align=right>" + EnvVar[i] + " : ");
                  System.out.println("<td>" + System.getProperty(EnvVar[i]));
                }
                else
                {
                    System.out.println("<tr>");
                    System.out.println("<td align=right>" + EnvVar[i] + " : ");
                    System.out.println("<td>NONE");
                }
           }
       System.out.println("</table>");
       System.out.println("</body>");
       System.out.println("</html>");
       System.out.flush();
       }
 
       public static void main (String args[])
       {
           samplejava cgi = new samplejava();
           cgi.display();
       }
}


Example of C language CGI program

To call the SAMPLEC C program, add the following lines to an HTML form:

   <form method="POST" action="/CGI-BIN/SAMPLEC.PGM">
   <input name="YourInput" size=42,2>
   <br>
   Enter input for the C sample and click <input type="SUBMIT" value="ENTER">
   <p>The output will be a screen with the text,
   "YourInput=" followed by the text you typed above.
   The contents of environment variable SERVER_SOFTWARE is also displayed.
   </form>

The SAMPLEC program shows how to write a CGI program in C language.

/**********************************************************************/
/*                                                                    */
/* Source File Name: QCSRC.SAMPLEC                                    */
/*                                                                    */
/* Module Name: SAMPLEC                                               */
/*                                                                    */
/* This sample code is provided by IBM for illustrative purposes only.*/
/* It has not been fully tested. It is provided as-is without any     */
/* warranties of any kind, including but not limited to the implied   */
/* warranties of merchantability and fitness for a particular purpose.*/
/*                                                                    */
/* Source File Description: A sample of a C program executed as a     */
/* CGI program on the AS/400 HTTP server.  The program demonstrates   */
/* reading standard input, reading environment variables and          */
/* writing standard output.  The input data comes from information    */
/* typed in HTML  fields.  This program will read this input    */
/* information and write exactly what is read to standard output.     */
/*                                                                    */
/* This program is a simple AS/400 ILE/C program that demonstrates    */
/* the ILE/C function calls for reading standard input, reading       */
/* environment variables and writing standard output.  The fread()    */
/* and printf() are used to read standard input and write standard    */
/* output.  getenv() is used to read HTTP server environment          */
/* variables. The fread() and printf() are found in stdio.h header    */
/* file and getenv() is found in stdlib.h.  These includes are needed */
/* in any AS/400 ILE/C program reading standard input, writing        */
/* standard output and reading environment variables.                 */
/*                                                                    */
/* This program will write HTML type data to standard output.  The    */
/* first line of data written to standard output must be included and */
/* consists of the Content Type of the data that follows.             */
/*                                                                    */
/* Here are the steps to setting up and running this CGI program on   */
/* the AS/400 HTTP server:                                            */
/*                                                                    */
/* 1-> Create HTML document as a member in a source physical file.    */
/* 2-> Set Source type of HTML document to HTML.                      */
/* 3-> Create the *PGM object called SAMPLEC(CRTCMOD and CRTPGM).     */
/* 4-> Check QTMHHTTP or *PUBLIC has access to document and QTMHHTP1  */
/*       or *PUBLIC has access to program(DSPOBJAUT and GRTOBJAUT).   */
/*     (If configuration runs CGI request using Userid, The User      */
/*     profile specified on Userid directive must have access to      */
/*     program.)                                                      */
/* 5-> Set up HTTP server configuration directives(WRKHTTPCFG)        */
/* 6-> Start the HTTP server instance(STRTCPSVR).                     */
/* 7-> Request the document from the browser.                         */
/*                                                                    */
/* Sample the html form segment to run this sample CGI script:        */
/*                                                                    */
/*           .                                                        */
/*           .                                                        */
/*           .                                                        */
/* <form action="/cgi-bin/samplec" method="POST">                     */
/* <input type="Text" maxsize=80 size=20 name="Sample">               */
/* <input type="Submit" name="SampleData" value="Submit CGI script">  */
/* <br>Sample CGI program written in AS/400 ILE/C.<br>                */
/* Type data and Click Submit to run a Sample program using ILE/C.    */
/* </form>                                                            */
/*           .                                                        */
/*           .                                                        */
/*           .                                                        */
/* Change the form method to "GET" when input data for sample CGI     */
/* program comes from the QUERY_STRING environment variable.          */
/*                                                                    */
/* HTTP Server configuration:                                         */
/* # Pass the html document in a library                              */
/* Pass /sampledoc /qsys.lib/websamp.lib/htmlfile.file/samplec.mbr    */
/* # Allow CGI program to run.                                        */
/* Map  /cgi-bin/* /cgi-bin/*.pgm                                     */
/* Exec /cgi-bin/* /qsys.lib/websamp.lib/*                            */
/*                                                                    */
/* This program is invoked by a URL from a browser in the form:       */
/* http://hostname/sampledoc                                          */
/*                                                                    */
/* Functions tested: Calls to Standard input and output using         */
/*                   standard i/o c calls.  This program uses         */
/*                   fread(), putchar(), and printf(). It is          */
/*                   designed to run on the AS/400 HTTP Server.       */
/*                                                                    */
/**********************************************************************/
 
 
#include <stdio.h>                    /* C-stdio library.             */
#include <string.h>                   /* string functions.            */
#include <stdlib.h>                   /* stdlib functions.            */
#include <errno.h>                    /* errno values.                */
 
 
#define LINELEN  80                   /* Max length of line.          */
 
 
 
/**********************************************************************/
/*                                                                    */
/* Function Name: writeData()                                         */
/*                                                                    */
/* Descriptive Name: Function is used to print the data to the        */
/* browser.  The data is printed 80 characters/line to provide        */
/* a neat and readable output.                                        */
/*                                                                    */
/* HTTP Server Environment variables:                                 */
/* ----------------------------------                                 */
/*                                                                    */
/* Standard Input:                                                    */
/* ---------------                                                    */
/*                                                                    */
/* Standard Output:                                                   */
/* ----------------                                                   */
/* All data directed to Standard output is sent using printf() or     */
/* putchar().  Standard output is written with html text.             */
/*                                                                    */
/*                                                                    */
/* Input: ptrToData : A pointer to the data to write to stdout.       */
/*        dataLen   : Length of data buffer.                          */
/*                                                                    */
/* Output: Data buffer written to stdout.                             */
/*                                                                    */
/* Exit Normal:                                                       */
/*                                                                    */
/* Exit Error: None                                                   */
/*                                                                    */
/**********************************************************************/
void writeData(char* ptrToData, int dataLen)
{
 
  div_t  insertBreak;
  int    i;
 
  /*------------------------------------------------------------------*/
  /* Write dataLen bytes of data from ptrToData.                      */
  /*------------------------------------------------------------------*/
  for (i=1; i<= dataLen; i++) {
 
      putchar(*ptrToData);
      ptrToData++;
 
      /*--------------------------------------------------------------*/
      /* Print a break after every 80 characters.                     */
      /*--------------------------------------------------------------*/
      insertBreak = div(i, LINELEN);
      if ( insertBreak.rem == 0 )	
          printf("<br>");
 
  }
 
  return;
 
}
 
 
 
 
 
/**********************************************************************/
/*                                                                    */
/* Function Name: main()                                              */
/*                                                                    */
/* Descriptive Name: A sample of the method used for AS/400 ILE/C to  */
/* read standard input, write standard output and check environment   */
/* variables; SERVER_SOFTWARE, REQUEST_METHOD, CONTENT_LENGTH, etc.   */
/*                                                                    */
/* HTTP Server Environment variables:                                 */
/* ----------------------------------                                 */
/* The C function call, getenv, is used to read AS/400 server         */
/* environment variables.  The value of the argument is a (char *)    */
/* pointer with the name of the environment variable. The value of    */
/* the environment variable is always returned as a string pointer.   */
/* The value may need to be converted to be used; that is             */
/* CONTENT_LENGTH needs to be converted to int using atoi().          */
/*                                                                    */
/* Standard Input:                                                    */
/* ---------------                                                    */
/* CONTENT_LENGTH is used to determine the amount of data to be       */
/* read from standard input with fread().  The standard input is      */
/* considered to be a stream of bytes up to CONTENT_LENGTH bytes. The */
/* standard input can be read with any file input stream function up  */
/* to and including CONTENT_LENGTH bytes.  Reading more than          */
/* CONTENT_LENGTH bytes is not defined.                               */
/*                                                                    */
/* Standard Output:                                                   */
/* ----------------                                                   */
/* All data directed to Standard output is using writeData().         */
/*                                                                    */
/* Standard output is written with html text which includes HTTP      */
/* header lines identifying the content type of the data written and  */
/* HTTP response headers.  This MUST be followed by a blank line(\n\n)*/
/* before writing any html text.  This indicates the end of the       */
/* header and the start of text that is served from the server.       */
/* This text is usually html but can be plain/text.                   */
/*                                                                    */
/* Input: Data read from standard input or QUERY_STRING that is       */
/*        entered in an HTML form.                                    */
/*                                                                    */
/* Output: The data read from standard input is written as is to      */
/*         standard output.  This information would then be served by */
/*         the HTTP server.                                           */
/*                                                                    */
/* Exit Normal:                                                       */
/*                                                                    */
/* Exit Error: None                                                   */
/*                                                                    */
/**********************************************************************/
void main()
{
 
  char   *stdInData;                   /* Input buffer.               */
  char   *queryString;                 /* Query String env variable   */
  char   *requestMethod;               /* Request method env variable */
  char   *serverSoftware;              /* Server Software env variable*/
  char   *contentLenString;            /* Character content length.   */
  int    contentLength;                /* int content length          */
  int    bytesRead;                    /* number of bytes read.       */
  int    queryStringLen;               /* Length of QUERY_STRING      */
 
  /*------------------------------------------------------------------*/
  /* The "Content-type" is the minimum request header that must be    */
  /* written to standard output.  It describes the type of data that  */
  /* follows.                                                         */
  /*------------------------------------------------------------------*/
  printf("Content-type: text/html\n");
 
  /*------------------------------------------------------------------*/
  /* VERY IMPORTANT! An extra newline must be written                 */
  /* after the request header.  In this case the request header is    */
  /* only the Content-type.  This tells the HTTP server that the      */
  /* request header is ended and the data follows.                    */
  /*------------------------------------------------------------------*/
  printf("\n");
 
  /*------------------------------------------------------------------*/
  /* This html text consists of a head and body section.  The head    */
  /* section has a title for the document.  The body section will     */
  /* contain standard input, QUERY_STRING, CONTENT_LENGTH,            */
  /* SERVER_SOFTWARE and REQUEST_METHOD.                              */
  /*------------------------------------------------------------------*/
  printf("<html>\n");
  printf("<head>\n");
  printf("<title>\n");
  printf("Sample AS/400 HTTP Server CGI program\n");
  printf("</title>\n");
  printf("</head>\n");
  printf("<body>\n");
  printf("<h1>Sample AS/400 ILE/C program.</h1>\n");
  printf("<br>This is sample output writing in AS/400 ILE/C\n");
  printf("<br>as a sample of CGI programming.  This program reads\n");
  printf("<br>the input data from Query_String environment\n");
  printf("<br>variable when the Request_Method is GET and reads\n");
  printf("<br>standard input when the Request_Method is POST.\n");
 
  /*------------------------------------------------------------------*/
  /* Get and write the REQUEST_METHOD to stdout.                      */
  /*------------------------------------------------------------------*/
  requestMethod = getenv("REQUEST_METHOD");
  if ( requestMethod )
      printf("<h4>REQUEST_METHOD:</h4>%s\n", requestMethod);
  else
      printf("Error extracting environment variable REQUEST_METHOD.\n");
 
  /*------------------------------------------------------------------*/
  /* html form data can be provided to the CGI program either on      */
  /* stdin or in environment variable QUERY_STRING.  This can be      */
  /* determined by examining REQUEST_METHOD.                          */
  /*------------------------------------------------------------------*/
  if ( strcmp(requestMethod,"POST") == 0 ) {
 
      /*--------------------------------------------------------------*/
      /* The REQUEST_METHOD is "POST".  The environment variable      */
      /* CONTENT_LENGTH will tell us how many bytes of data to read   */
      /* from stdin.  Note: CONTENT_LENGTH must be convert to an int. */
      /*--------------------------------------------------------------*/
      contentLenString = getenv("CONTENT_LENGTH");
      contentLength = atoi(contentLenString);
 
      /*--------------------------------------------------------------*/
      /* Write CONTENT_LENGTH to stdout.                              */
      /*--------------------------------------------------------------*/
      printf("<h4>CONTENT_LENGTH:</h4>%i<br><br>\n",contentLength);
 
      if ( contentLength ) {
 
          /*----------------------------------------------------------*/
          /* Allocate and set memory to read stdin data into.         */
          /*----------------------------------------------------------*/
          stdInData = malloc(contentLength);
          if ( stdInData )
              memset(stdInData, 0x00, contentLength);
          else
              printf("ERROR: Unable to allocate memory\n");
          /*----------------------------------------------------------*/
          /* A CGI program MUST read standard input as a stream       */
          /* file only up to and including CONTENT_LENGTH bytes.      */
          /* Never should a program read more than CONTENT_LENGTH     */
          /* bytes.  A CGI program that reads standard input must     */
          /* never depend on an end of file flag.  This will cause    */
          /* unpredictable results when the CGI program reads         */
          /* standard input.                                          */
          /*----------------------------------------------------------*/
          printf("<h4>Server standard input:</h4>\n");
          bytesRead = fread((char*)stdInData, 1, contentLength, stdin);
 
          /*----------------------------------------------------------*/
          /* If we successfully read all bytes from stdin, format and */
          /* write the data to stdout using the writeData function.   */
          /*----------------------------------------------------------*/
          if ( bytesRead == contentLength )
              writeData(stdInData, bytesRead);
          else
              printf("<br>Error reading standard input\n");
 
          /*----------------------------------------------------------*/
          /* Free the storage allocated to hold the stdin data.       */
          /*----------------------------------------------------------*/
          free(stdInData);
 
      } else
          printf("<br><br><b>There is no standard input data.</b>");
 
  } else if (strcmp(requestMethod, "GET") == 0 ) {
      /*--------------------------------------------------------------*/
      /* The REQUEST_METHOD is "GET".  The environment variable       */
      /* QUERY_STRING will contain the form data.                     */
      /*--------------------------------------------------------------*/
      queryString = getenv("QUERY_STRING");
      if ( queryString ) {
 
          /*----------------------------------------------------------*/
          /* Write the QUERY_STRING data to stdout.                   */
          /*----------------------------------------------------------*/
          printf("<h4>Server input read from QUERY_STRING:</h4>");
          queryStringLen = strlen(queryString);
          if ( queryStringLen )
              writeData(queryString, queryStringLen);
          else
              printf("<b>There is no data in QUERY_STRING.</b>");
 
      } else
          printf("<br>Error getting QUERY_STRING variable.");
 
  } else
      printf("<br><h2>ERROR: Invalid REQUEST_METHOD.</h2>");
 
  /*------------------------------------------------------------------*/
  /* Write break and paragraph html tag to stdout.                    */
  /*------------------------------------------------------------------*/
printf("<br><p>\n");
 
 /*------------------------------------------------------------------*/
  /* Write the SERVER_SOFTWARE environment variable to stdout.        */
  /*------------------------------------------------------------------*/
  serverSoftware = getenv("SERVER_SOFTWARE");
  if ( serverSoftware )
      printf("<h4>SERVER_SOFTWARE:</h4>%s\n", serverSoftware);
  else
      printf("<h4>Server Software is NULL</h4>");
 
  /*-----------------------------------------------------------------*/
  /* Write the closing tags on HTML document.                        */
  /*-----------------------------------------------------------------*/
  printf("</p>\n");
  printf("</body>\n");
  printf("</html>\n");
 
  return;
}

Example of RPG language CGI program

To call the SAMPLE RPG program, add the following lines to an HTML form:

   <form method="POST" action="/CGI-BIN/SAMPLE.PGM">
   <input name="YourInput" size=42,2>
   <br>
   Enter input for the RPG sample and click <input type="SUBMIT" value="ENTER">
   <p>The output will be a screen with the text,
   "YourInput=" followed by the text you typed above.
   The contents of environment variable SERVER_SOFTWARE is also displayed.
   </form>

The SAMPLE program shows how to write a CGI program in RPG language.

      **************************************************************************
      ****                   Sample ILE RPG program.                         ***
      ****                                                                   ***
      ****This sample code is provided by IBM for illustrative purposes only.***
      ****It has not been fully tested. It is provided as-is without any     ***
      ****warranties of any kind, including but not limited to the implied   ***
      ****warranties of merchantability and fitness for a particular purpose.***
      ****                                                                   ***
      **** This program is a simple RPG program that demonstrates the HTTP   ***
      **** server APIs for reading standard input, reading an environment    ***
      **** variable and writing standard output.  This is done using the     ***
      **** IBM AS/400 HTTP Server APIs.                                      ***
      ****                                                                   ***
      **** The HTML at the end of this listing in CTDATA HTML is the text    ***
      **** that is modified by this program, written to standard output and  ***
      **** served to a client.                                               ***
      ****                                                                   ***
      **** 1-> Create HTML document as source physical file in library.      ***
      **** 2-> Set Source type of HTML document to HTML.                     ***
      **** 3-> Create the *PGM object called SAMPLE(CRTRPGMOD and CRTPGM).   ***
      ****      -Include the service program QTCP/QTMHCGI when doing the     ***
      ****        CRTPGM in the BNDSRVPGM or BNDDIR parameter.               ***
      **** 4-> Check QTMHHTTP or *PUBLIC has access to document and QTMHHTP1 ***
      ****       or *PUBLIC has access to program(DSPOBJAUT and GRTOBJAUT).  ***
      **** 5-> Set up HTTP server configuration directives(WRKHTTPCFG)       ***
      **** 6-> Start the HTTP server(STRTCPSVR).                             ***
      **** 7-> Run request from a browser.                                   ***
      ****                                                                   ***
      ****------------------------ IMPORTANT --------------------------------***
      **** The input for this program comes from CGI standard input or       ***
      **** the environment variable, QUERY_STRING.  For an HTTP request      ***
      **** method of POST, the input is read from standard input and         ***
      **** for an HTTP request method of GET, the input is read from         ***
      **** QUERY_STRING. For method POST, this program will only read 1024   ***
      **** characters.  For method GET, the program will not read any        ***
      **** input data when it exceeds 1024 characters.  The QtmhGetEnv       ***
      **** API will set the length of the environment variable response      ***
      **** to the actual length and no data is read into the receive         ***
      **** buffer.                                                           ***
      ****------------------------ IMPORTANT --------------------------------***
      ****                                                                   ***
      **** Sample html form segment to run this sample CGI script:           ***
      ****                                                                   ***
      ****           .                                                       ***
      ****           .                                                       ***
      ****           .                                                       ***
      **** <form action="/cgi-bin/sample" method="POST">                     ***
      **** <input type="Text" maxsize=80 size=20 name="Sample">              ***
      **** <input type="Submit name="SampleData" value="Submit CGI script">  ***
      **** <br>Sample CGI program written in RPG.<br>                        ***
      **** Type data and Click Submit to run a Sample program using RPG.     ***
      **** </form>                                                           ***
      ****           .                                                       ***
      ****           .                                                       ***
      ****           .                                                       ***
      ****                                                                   ***
      **** HTTP Server configuration:                                        ***
      **** # Pass the html document in a library                             ***
      **** Pass /sampledoc /qsys.lib/websamp.lib/htmlfile.file/sample.mbr    ***
      **** # Allow CGI program to run.                                       ***
      **** Map  /cgi-bin/* /cgi-bin/*.pgm                                    ***
      **** Exec /cgi-bin/* /qsys.lib/websamp.lib/*                           ***
      ****                                                                   ***
      **** This program is invoked by a URL from a browser in the form:      ***
      **** http://hostname/sampledoc                                         ***
      ****                                                                   ***
      **************************************************************************
      ****                                                                   ***
      **** Function of this SAMPLE program:                                  ***
      **** Sample ILE RPG AS/400 program to demonstrate AS/400 HTTP server   ***
      **** CGI program. It reads data from standard input based on the       ***
      **** Content_Length environment variable.  The QtmhGetEnv System API   ***
      **** is used to get the Content_Length and set the InDataLn variable   ***
      **** used by the QtmhRdStdIn API. The data to be returned to the       ***
      **** client to written to standard output using the QtmhWrStOut API.   ***
      **** The data will be returned as text/html.                           ***
      ****                                                                   ***
      **************************************************************************
      * Variables for the CGI interface API for QtmhRdStIn.
     DBufIn            S           1024a   INZ
     DBufInLn          S              9b 0 INZ(1024)
     DStdInLn          S              9b 0
      **************************************************************************
      * Variables for the CGI interface API for QtmhGetEnv.
     DEnvRec           S           1024A   INZ
     DEnvRecLen        S              9B 0 INZ(1024)
     DEnvLen           S              9B 0 INZ
     DEnvName          S             25A   INZ('CONTENT_LENGTH')
     DEnvNameLen       S              9B 0 INZ(14)
      **************************************************************************
      *Variables for the CGI interface API for QtmhWrStout.
     DBufOut           S           2048a   INZ
     DBufOutln         S              9b 0
      *************************************************************************
      ***                   Data structure for error reporting.             ***
      *** Copied from QSYSINC/QRPGLESRC(QUSEC).                             ***
      *** The QUSBPRV must be initialized to 16.                            ***
      *** This is the common error structure that is passed to the CGI APIs;***
      *** QtmhWrStOut, QtmhRdStin, QtmhGetEnv and QtmhCvtDb.  The Error     ***
      *** structure is documented in the "AS/400 System API Reference".     ***
      *************************************************************************
     DQUSEC            DS
     D*                                             Qus EC
     D QUSBPRV                 1      4B 0 INZ(16)
     D*                                             Bytes Provided
     D QUSBAVL                 5      8B 0
     D*                                             Bytes Available
     D QUSEI                   9     15
     D*                                             Exception Id
     D QUSERVED               16     16
      **************************************************************************
      *** Constants for names of CGI APIs.                                   ***
     DAPIStdIn         C                   'QtmhRdStin'
     DAPIStdOut        C                   'QtmhWrStout'
     DAPIGetEnv        C                   'QtmhGetEnv'
      **************************************************************************
      * Prototype for c2n procedure that converts content length to numeric. ***
     Dc2n              PR            30p 9
     Dc                              32    options(*varsize)
      **************************************************************************
      * Compile-time array for HTML output.                                  ***
     Darrsize          C                   23
     Dhtml             S             80    DIM(arrsize) PERRCD(1) CTDATA
     DContentLn        S              9B 0 INZ(0)
     DEnvCL            S             20A   INZ('CONTENT_LENGTH')
     DEnvSS            S             20A   INZ('SERVER_SOFTWARE')
     DEnvMethod        S             20A   INZ('REQUEST_METHOD')
     DEnvQS            S             20A   INZ('QUERY_STRING')
     DEnvMDResp        S             30A   INZ
     DEnvSSResp        S             50A   INZ
     DEResp            S              4A   INZ
     D**************************************************************************
     D* Define line feed that is required when writing data to std output.   ***
     Dlinefeed         C                   x'15'
     Dbreak            C                   '<br>'
     Dmaxdataln        S              4B 0 INZ(1024)
     D**************************************************************************
     D* Some local variables used for adding newline in std output buffer.   ***
     Dcnt              S              4B 0 INZ(1)
     DWORK2            S             80A   INZ
     DResult           S              9B 0 INZ
      **************************************************************************
      * Start of CGI Program execution section...
      **************************************************************************
      * Initialize error code structure for error ids.
      * This allows for 7 bytes in QUSEI for error message id.
     C                   Z-ADD     16            QUSBPRV
      **************************************************************************
      **** Read the Environment variable, REQUEST_METHOD.
      **************************************************************************
     C                   MOVEL     EnvMethod     EnvName
     C                   Z-ADD     14            EnvNameLen
     C                   callb     APIGetEnv
     C                   parm                    EnvRec
     C                   parm                    EnvRecLen
     C                   parm                    EnvLen
     C                   parm                    EnvName
     C                   parm                    EnvNameLen
     C                   parm                    QUSEC
     C                   MOVEL     EnvRec        EnvMDResp
      **************************************************************************
      **** Is the REQUEST_METHOD, POST?
     C     4             subst     EnvRec:1      EResp
     C     EResp         ifeq      'POST'
      **************************************************************************
      * Get Environment Variable 'Content_Length' using 'QtmhGetEnv' API
     C                   MOVEL     EnvCL         EnvName
     C                   Z-ADD     14            EnvNameLen
     C                   CALLB     APIGetEnv
     C                   parm                    EnvRec
     C                   parm                    EnvRecLen
     C                   parm                    EnvLen
     C                   parm                    EnvName
     C                   parm                    EnvNameLen
     C                   parm                    QUSEC
      * Convert Content_Length to numeric.
     C                   eval      ContentLn=c2n(EnvRec)
      * When the Content Length is greater than the buffer, Read maxdataln.
     C     ContentLn     ifgt      maxdataln
     C                   Z-ADD     maxdataln     ContentLn
     C                   endif
      * Specify InDataLn to Content_Length value.  Never should a CGI program
      * ever attempt to read more than content length.  Specification of more
      * than content length in InDataLn is not defined.
     C                   Z-ADD     ContentLn     BufInLn
      **************************************************************************
      * Read standard input
     C                   callb     APIStdIn
     C                   parm                    BufIn
     C                   parm                    BufInLn
     C                   parm                    StdInLn
     C                   parm                    QUSEC
     C                   MOVEL     StdInLn       Result
     C                   else
      **************************************************************************
      **** Read the Environment variable, QUERY_STRING.
      **************************************************************************
     C                   MOVEL     EnvQS         EnvName
     C                   Z-ADD     12            EnvNameLen
     C                   callb     APIGetEnv
     C                   parm                    EnvRec
     C                   parm                    EnvRecLen
     C                   parm                    EnvLen
     C                   parm                    EnvName
     C                   parm                    EnvNameLen
     C                   parm                    QUSEC
      **************************************************************************
      **** Check length of environment value is less than
      **** the receive buffer.  When this occurs, the
      **** QtmhGetEnv sets the EnvLen to the actual value
      **** length without changing the receive buffer.
     C     EnvLen        ifgt      maxdataln
     C                   eval      Bufin='Data buffer +
     C                              not big enough for +
     C                              available input data.'
     C                   Z-ADD     80            Result
     C                   else
     C                   MOVEL     EnvRec        BufIn
     C                   MOVEL     EnvLen        Result
     C                   endif
     C                   endif
      **************************************************************************
      **** Read the Environment variable, SERVER_SOFTWARE.
      **************************************************************************
     C                   MOVEL     EnvSS         EnvName
     C                   Z-ADD     15            EnvNameLen
     C                   callb     APIGetEnv
     C                   parm                    EnvRec
     C                   parm                    EnvRecLen
     C                   parm                    EnvLen
     C                   parm                    EnvName
     C                   parm                    EnvNameLen
     C                   parm                    QUSEC
     C                   MOVEL     EnvRec        EnvSSResp
      **************************************************************************
      **** Put the data written to standard output in buffer; bufout.        ***
      **************************************************************************
      * For each line of HTML, move it to BufOut and set the
      * output buffer's length(BufOutLn).
     C                   do        arrsize       i                 5 0
      * Write out HTTP response and HTML lines.
     C     i             iflt      17
     C     BufOut        cat       html(i):0     BufOut
     C     BufOut        cat       linefeed:0    BufOut
     C                   endif
      * Add the data read from standard input or QUERY_STRING.
     C     i             ifeq      17
     D* Add html break to BufOut string written to standard output
     D* when input is greater than 79.
     C     Result        dowgt     79
     C     80            SUBST     BufIn:cnt     WORK2
     C                   cat       work2:0       BufOut
     C                   cat       break:0       BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*                  cat       linefeed:0    BufOut
     C                   add       80            cnt
     C                   sub       80            Result
     C                   ENDDO
     C                   IF        Result > 0
     C                   clear                   WORK2
     C     Result        SUBST     BufIn:cnt     WORK2
     C                   cat       work2:0       BufOut
     C                   cat       break:0       BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*                  cat       linefeed:0    BufOut
     C                   ENDIF
     C                   endif
      * Add the Environment variable header line for REQUEST_METHOD.
     C     i             ifeq      18
     C     BufOut        cat       html(i):0     BufOut
     C     BufOut        cat       break:0       BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*    BufOut        cat       linefeed:0    BufOut
     C                   endif
      * Display the Environment variable REQUEST_METHOD.
     C     i             ifeq      19
     C     BufOut        cat       EnvMDResp:0   BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*    BufOut        cat       linefeed:0    BufOut
     C                   endif
      * Add the Environment variable header line for SERVER_SOFTWARE.
     C     i             ifeq      20
     C     BufOut        cat       html(i):0     BufOut
     C     BufOut        cat       break:0       BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*    BufOut        cat       linefeed:0    BufOut
     C                   endif
      * Display the Environment variable SERVER_SOFTWARE.
     C     i             ifeq      21
     C     BufOut        cat       EnvSSResp:0   BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*    BufOut        cat       linefeed:0    BufOut
     C                   endif
      * Write out closing HTML lines.
     C     i             ifgt      21
     C     BufOut        cat       html(i):0     BufOut
      * For V4R2, the newline after 254 characters is not needed.
     C*    BufOut        cat       linefeed:0    BufOut
     C                   endif
     C                   enddo
      **************************************************************************
      **** Get length of data to be sent to standard output.
      **************************************************************************
     C                   z-add     1             i
     C     arrsize       mult      80            i
     C     a             doune     ' '
     C     1             subst     bufout:i      a                 1
     C                   sub       1             i
     C                   enddo
     C     i             add       1             BufOutLn
      **************************************************************************
      **** Send BufOut to standard output.
      **************************************************************************
     C                   callb     APIStdOut
     C                   parm                    BufOut
     C                   parm                    BufOutLn
     C                   parm                    QUSEC
      **************************************************************************
      * Return to caller
      **************************************************************************
     C                   return
      ********************************************************
      * Function: Convert a character to numeric value.      *
      ********************************************************
      * nomain c2n subprocedure
     Pc2n              B                   export
     Dc2n              PI            30p 9
     Dc                              32    options(*varsize)
      * variables
     Dn                s             30p 9
     Dwknum            s             30p 0
     Dsign             s              1  0 inz(1)
     Ddecpos           s              3  0 inz(0)
     Dindecimal        s              1    inz('0')
     Di                s              3  0
     Dj                s              3  0
     D                 ds
     Dalpha1                          1
     Dnumber1                         1  0 overlay(alpha1) inz(0)
     C                   eval      c = %triml(c)
     C     ' '           checkr    c             j
     C     1             do        j             i
     C                   eval      alpha1=%subst(c:i:1)
     C                   select
     C                   when      alpha1='-'
     C                   eval      sign= -1
     C                   when      alpha1='.'
     C                   eval      indecimal='1'
     C                   when      alpha1 >='0' and alpha1 <= '9'
     C                   eval      wknum  = wknum  * 10 + number1
     C                   if        indecimal = '1'
     C                   eval      decpos = decpos + 1
     C                   endif
     C                   endsl
     C                   enddo
     C                   eval      n = wknum  * sign / 10 ** decpos
     C                   return    n
     Pc2n              E
      **************************************************************************
      * Compile-time array follows:
      **************************************************************************
      * A line MUST follow Content-type with only a single newline(x'15').  If
      * this newline does not exist, Then NO data will be served to the client.
      * This newline represents the end of the HTTP header and the data follows.
**CTDATA HTML
Content-type: text/html
 
 
<html>
<head>
<title>Sample AS/400 RPG program executed by HTTP Server as a CGI</title>
</head>
<body>
<h1>Sample AS/400 RPG program.</h1>
<br>
<br>
<p>This is sample output using AS/400 HTTP Server CGI APIs from an RPG
program.  This program reads the input data from Query_String
environment variable when the Request_Method is GET and reads
standard input when the Request_Method is POST.
<p>Server input:<br>
 
<p>Environment variable - REQUEST_METHOD:
 
<p>Environment variable - SERVER_SOFTWARE:
 
</body>
</html>


[ Top of Page | Previous Page | Next Page | Table of Contents ]