CGI Introduction

So what is CGI?

You may have heard of CGI, or the Common Gateway Interface, which is simply a standard way for a web server to run a program that dynamically generates a web page. In reality all that is happening is that there is a program (running in whatever language the developer decided to use) that is generating HTML on the fly and the output of that program is returned to the browser.

How does this program get it's inputs?

There are a few common methods of sending a request to a web server. In this class we focus on GET and POST. With GET, all of the form data is encoded within the URL and sent as part of the HTTP headers, and with POST the same data is provided in the body of the HTTP request, as you may remember from the previous class. For each HTTP request received, the web server sets multiple environment variables and the stdin with different pieces of information it receives in the request. For the data sent using thr GET method, an environment variable called "QUERY_STRING" is set on the server with the data received.

When you use a web server that supports CGI, like the Apache2 server we use with our classes, this data is provided to the scripts via environment variables that the program can read while it is executing. This means that any programming language can be used.

Lets take a look at a C++ program that would perform these actions. Note that this was pulled and modified from https://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm :

#include <iostream>
#include <stdlib.h>

using namespace std;

const string ENV[ 24 ] = {
   "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
   "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",
   "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",
   "HTTP_HOST", "HTTP_USER_AGENT", "PATH",
   "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
   "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
   "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",
   "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",
   "SERVER_SIGNATURE","SERVER_SOFTWARE" };

int main()
{

  // Set the return header
  cout << "Content-type:text/html\n\n";

  // Output the text (our HTML)
  cout << "<!DOCTYPE html>\n"
  cout << "<html lang = \"en\">\n";
  cout << "<head>\n";
  cout << "<title>CGI Environment Variables</title>\n";
  cout << "</head>\n";
  cout << "<body>\n";
  cout << "<table>";

  for ( int i = 0; i < 24; i++ ) {
     cout << "<tr><td>" << ENV[ i ] << "</td><td>";

     // attempt to retrieve value of environment variable
     char *value = getenv( ENV[ i ].c_str() );
     if ( value != 0 ) {
        cout << value;
     } else {
        cout << "Environment variable does not exist.";
     }
     cout << "</td></tr>\n";
  }

  cout << "</table>\n";
  cout << "</body>\n";
  cout << "</html>\n";

  return 0;
}

What do you see when you run it from the command line, and when you view the file on the website? Do "View page source" in the browser to see the source received by the browser as well.

Why is this nice?

Well this means that instead of having static HTML files that never change, we can write programs that will produce HTML on the fly. This is how we will make dynamic websites that are interactive for our users, or that can provide up to date information. The data sent by the user can be retrieved from the QUERY_STRING environment variable or stdin, parsed, and used to dynamically generate personalized webpages.

Practice Problem - Complete this (counts as a quiz) due Friday NLT 2359

  1. In your public_html/IT350/CGIIntro folder write a cpp program named ex1.cpp that will, given the URL http://midn.cs.usna.edu/~mXXXXXX/IT350/CGIIntro/ex1.cgi?maxNumber=5, generate HTML that looks like this: cgi table

A few notes:

  1. For this exercise, you can assume that the maxNumber value is a single digit
  2. Name your C++ file ex1.cpp
  3. Name the compiled output ex1.cgi and place it in your "~/public_html/IT350/CGIIntro/" folder
  4. In a browser, go to http://midn.cs.usna.edu/~mXXXXXX/IT350/CGIIntro/ex1.cgi?maxNumber=5 to test your script. Try it with different values from 1 to 9 for maxNumber.
  5. Retrieve the results from the command line via:

    curl http://midn.cs.usna.edu/~mXXXXXX/IT350/CGIIntro/ex1.cgi?maxNumber=5
    To save the results, redirect stdout from curl to a file:

    curl http://midn.cs.usna.edu/~mXXXXXX/IT350/CGIIntro/ex1.cgi?maxNumber=5 > results.html
  6. Submit your ex1.cpp, ex1.cgi, and results.html files to the online submissions system (submit.moboard.com) on or before the due date. This is CGIIntro project. Use the command line submit script and capture the entire contents of the directory; the easiest way to do this would be to cut and paste the following while logged onto the web server (midn.cs.usna.edu):

    
    		cd ~/public_html/IT350
    		~/bin/submit -c=IT350 -p=CGIIntro CGIIntro
    This assumes that the submit script is located in ~/bin/ and is executable.