Introducing CGI


Important

All ".html" and ".cgi" files that you want to be available to web browsers must be in your public_html directory. That is the only place the web server is allowed to look for your files. You will probably find it most convenient to cd to public_html and do all the work there.

Unfortunately, everything you put in that directory is accessible to everyone using this computer unless you do something about it. You must protect your ".cpp" files or people will be able to steal your work. Even if you don't care about your work being stolen, I do, so you must use protection.

Here is how: use "ls -l" (dash-little-L, not dash-one) to see the protections of all your files in the public_html directory. You should see that all your human-readable files (.cpp and .html) have "-rw-r--r--" protection and your executables (.cgi) have "-rwxr-xr-x" protectedion. That is perfect for things that are supposed to be visible, but not for things that are supposed to be private. After each .cpp file is created, type this command "chmod 600 *.cpp", it will change the protection of your .cpp files to "-rw-------", which means that you can continue to use them freely, but nobody else can even see them.

Note: If you do CGI programming on any other computer, you can expect everything to be exactly the same as it is here, except that you will probably have two separate web subdirectories, one called public_html which is for .html and other normal web files, and one called cgi-bin which is for .cgi files. Having to keep things in two different directories is too much of a pain so I changed it. Also on other computers your URL will be different. Instead of the substring /students/yourname you will probably see /~yourname, and the URL to access CGI files could be just about anything; you'll have to check with the locals.

1: Basic HTML

$ cd public_html
$ pico experiment1.html
<html>
  <head> <title> first experiment </title> </head>
  <body>

    <h1>Experiment One</h1>

    Just to see

    how everything

        works!!
    <br>
    one two three four
    five six.

   </body>
</html>


2: Basic CGI

First, download and compile the two small support files:
$ cp ~data/cgi.cpp .
$ cp ~data/cgi.h .
$ CC -c cgi.cpp
$ pico experiment2.cpp
#include <iostream>
#include <string>
#include "cgi.h"

void main(void)
{ cout << "Content-type: text/html\r\n\r\n";
  cout << "<html>\r\n" ;
  cout << "  <head> <title> Testing CGI (experiment 2)</title> </head>\r\n";
  cout << "  <body>\r\n";
  cout << "    <h1>Testing CGI (experiment 2)</h1>\r\n";
  cout << "    Still just seeing if everything works<br>\r\n";
  cout << "    one two three\r\n";
  cout << "    four five six.\r\n";
  cout << "  </body>\r\n";
  cout << "</html>\r\n"; }

$ chmod 600 *.cpp
$ CC experiment2.cpp cgi.o -o experiment2.cgi


3: HTML for accessing CGI

$ pico experiment3.html
<html>
  <head> <title> Accessing CGI from HTML (exp 3)</title> </head>
  <body>
    <h1>Accessing CGI from HTML (exp 3)</h1>

    This is the access page for the super-calculator. <br>
    Please Complete and Submit the survey below.

    <form  action=experiment4.cgi method=post>
      <table>
        <tr>
          <td> What is your Name?
          <td> <input name="name" type=text>
        <tr>
          <td> What is Your Favourite Colour?
          <td> <input name="favcol" type=text>
        <tr>
          <td> Think of a number:
          <td> <input name="number1" type=text>
        <tr>
          <td> And another number:
          <td> <input name="number2" type=text>
        <tr>
          <td> Then click "submit"
          <td> <input type=submit value="SUBMIT">
      </table>
    </form>
  </body>
</html>






4: CGI to be accessed by HTML

$ pico experiment4.cpp
#include <iostream>
#include <string>
#include "cgi.h"

void main(void)
{ cout << "Content-type: text/html\r\n\r\n";
  cout << "<html>\r\n" ;
  cout << "  <head> <title> Using CGI (experiment 4)</title> </head>\r\n";
  cout << "  <body>\r\n";
  cout << "    <h1>Using CGI (experiment 4)</h1>\r\n";
  int num = NumberOfQuestions();
  cout << "    You provided " << num << " inputs, and they were: <br> \r\n";
  for (int i=0; i<num; i+=1)
  { string q = GetQuestion(i);
    string a = GetAnswer(q);
    cout << i << ": Question Identifier: " << q <<
                 ", Answer: " << a << " <br> \r\n"; }
  cout << "    And that's the end..\r\n";
  cout << "  </body>\r\n";
  cout << "</html>\r\n"; }

$ chmod 600 *.cpp
$ CC experiment4.cpp cgi.o -o experiment4.cgi



What experiment4.cgi actually printed
Content-type: text/html

<html>
  <head> <title> Using CGI (experiment 4)</title> </head>
  <body>
    <h1>Using CGI (experiment 4)</h1>
    You provided 4 inputs, and they were: <br>
 0: Question Identifier: name, Answer: Xlkasflkjffj <br>
 1: Question Identifier: favcol, Answer: orange <br>
 2: Question Identifier: number1, Answer: 123 <br>
 3: Question Identifier: number2, Answer: 456 <br>
    And that's the end..
  </body>
</html>


5: Other information you can get

$ pico experiment5.cpp
#include <iostream>
#include <string>
#include "cgi.h"

string days[] = { "Sunday", "Monday", "Tuesday", "Wednesday",
                  "Thursday", "Friday", "Saturday" };

string dates[] = {   "", "st", "nd", "rd", "th", "th", "th", "th", "th", "th",
                   "th", "th", "th", "th", "th", "th", "th", "th", "th", "th",
                   "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th",
                   "th", "st" };

string months[] = { "", "January", "February", "March", "April", "May", "June",
                    "July", "Frank", "Jeffrey", "October", "November", "December" };

void main(void)
{ int yr, mo, dy, wd, hr, mi, se;
  DateAndTimeNow(yr, mo, dy, wd, hr, mi, se);
  cout << "Content-type: text/html\r\n\r\n";
  cout << "<html>\r\n" ;
  cout << "  <head> <title> Using CGI (Experiment 5) </title> </head>\r\n";
  cout << "  <body>\r\n";
  cout << "    <h1>Using CGI (Experiment 5)</h1>\r\n";
  cout << "    (connection from " << RemoteHost() <<
                           " on " << days[wd] <<
                              " " << dy << dates[dy] <<
                              " " << months[mo] <<
                              " " << yr <<
                           " at " << hr <<
                              ":" << (mi<10 ? "0" : "") << mi <<
                              ":" << (se<10 ? "0" : "") << se <<
                  ")<br><br>\r\n";
  int num = NumberOfQuestions();
  cout << "    You provided " << num <<
                            " inputs, and they were as follows <br> \r\n";
  cout << "    <center> \r\n";
  cout << "      <table border=2> \r\n";
  cout << "        <tr> <th> Number <th> Identifier <th> Answer \r\n";
  for (int i=0; i<num; i+=1)
  { string q = GetQuestion(i);
    string a = GetAnswer(q);
    cout << "        <tr> \r\n";
    cout << "          <td> " << i << "\r\n";
    cout << "          <td> " << q << "\r\n";
    cout << "          <td> " << a << "\r\n"; }
  cout << "      </table>\r\n";
  cout << "    </center>\r\n";
  cout << "    The End. <br> \r\n";
  cout << "  </body>\r\n";
  cout << "</html>\r\n"; }

$ chmod 600 *.cpp
$ CC experiment5.cpp cgi.o -o experiment5.cgi
$ pico experiment3.html
                    (quickly edit to make it refer to experiment5.cgi now)

Doing Something Useful

$ cat experiment6.cpp
#include <iostream>
#include <string>
#include "cgi.h"

void main(void)
{ int yr, mo, dy, wd, hr, mi, se;
  DateAndTimeNow(yr, mo, dy, wd, hr, mi, se);
  cout << "Content-type: text/html\r\n\r\n";
  cout << "<html>\r\n" ;
  cout << "<head> <title> Super Calculator (Exp 6)</title> </head>\r\n";
  cout << "<body>\r\n";
  cout << "<h1>Super Calculator (Exp 6)</h1>\r\n";
  string name = GetAnswer("name");
  string first = GetAnswer("number1");
  string second = GetAnswer("number2");
  int n1 = ConvertToInteger(first);
  int n2 = ConvertToInteger(second);
  cout << "Hello " << name << " <br> \r\n";
  cout << "<br> \r\n";
  cout << n1 << " + " << n2 << " = " << n1+n2 << " <br> \r\n";
  cout << "</body>\r\n";
  cout << "</html>\r\n"; }

$ chmod 600 *.cpp
$ CC experiment6.cpp cgi.o -o experiment5.cgi