CGI: the Common Gateway Interface

A widget is a button, checkbox, entry form, etc. A web page that contains widgets is called a form. When you press the big button at the bottom of the form (in this case, the “See the calendar” button), the data that you have typed or clicked into the form can be transmitted into a program called a gateway. In this example, the gateway program is named pythoncal.cgi.

The gateway program must be on the machine that is running the web server that has served the form to the user. In this example, the machine is the Fedora Linux box oit2.scps.nyu.edu. The gateway program must also follow a set of rules called the CGI, or Common Gateway Interface. The first rule in this set says that the output of the gateway program must begin with the word Content-type.

The following form runs the gateway /home/m/meretzkm/public_html/cgi-bin/pythoncal.cgi on the host oit2.scps.nyu.edu.

pythoncal.cgi


Calender form

Which year do you want to see?

Which month do you want to see?
January
February
March
April
May
June
July
August
September
October
November
December
All twelve months

Check here to see the current date and time too.




When the user selects June 2019 and checks the checkbox for the current date and time, the output is the following.

<HTML>
<HEAD>
<TITLE>Calendar</TITLE>
</HEAD>

<BODY>
<H1>Calendar</H1>

<H2>34 environment variables</H2>

<OL>
<LI><CODE>CONTENT_LENGTH = 25</CODE></LI>
<LI><CODE>CONTENT_TYPE = application/x-www-form-urlencoded</CODE></LI>
<LI><CODE>CONTEXT_DOCUMENT_ROOT = /home/m/meretzkm/web</CODE></LI>
<LI><CODE>CONTEXT_PREFIX = /~meretzkm</CODE></LI>
<LI><CODE>DOCUMENT_ROOT = /var/www/html</CODE></LI>
<LI><CODE>GATEWAY_INTERFACE = CGI/1.1</CODE></LI>
<LI><CODE>HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3</CODE></LI>
<LI><CODE>HTTP_ACCEPT_ENCODING = gzip, deflate</CODE></LI>
<LI><CODE>HTTP_ACCEPT_LANGUAGE = en-US,en;q=0.9</CODE></LI>
<LI><CODE>HTTP_CACHE_CONTROL = max-age=0</CODE></LI>
<LI><CODE>HTTP_CONNECTION = keep-alive</CODE></LI>
<LI><CODE>HTTP_COOKIE = _ga=GA1.2.146985307.1534342603; _ap_utma=57748789.429615176.1535761070.1535761070.1535761070.1; __utma=57748789.146985307.1534342603.1553427371.1553427559.11; __utmz=57748789.1553427559.11.5.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)</CODE></LI>
<LI><CODE>HTTP_HOST = oit2.scps.nyu.edu</CODE></LI>
<LI><CODE>HTTP_ORIGIN = http://oit2.scps.nyu.edu</CODE></LI>
<LI><CODE>HTTP_REFERER = http://oit2.scps.nyu.edu/~meretzkm/python/misc/cgi.html</CODE></LI>
<LI><CODE>HTTP_UPGRADE_INSECURE_REQUESTS = 1</CODE></LI>
<LI><CODE>HTTP_USER_AGENT = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36</CODE></LI>
<LI><CODE>PATH = /usr/local/bin:/usr/bin:/bin</CODE></LI>
<LI><CODE>QUERY_STRING = </CODE></LI>
<LI><CODE>REMOTE_ADDR = 66.108.88.87</CODE></LI>
<LI><CODE>REMOTE_PORT = 52626</CODE></LI>
<LI><CODE>REQUEST_METHOD = POST</CODE></LI>
<LI><CODE>REQUEST_SCHEME = http</CODE></LI>
<LI><CODE>REQUEST_URI = /~meretzkm/cgi-bin/pythoncal.cgi</CODE></LI>
<LI><CODE>SCRIPT_FILENAME = /home/m/meretzkm/web/cgi-bin/pythoncal.cgi</CODE></LI>
<LI><CODE>SCRIPT_NAME = /~meretzkm/cgi-bin/pythoncal.cgi</CODE></LI>
<LI><CODE>SERVER_ADDR = 128.122.238.18</CODE></LI>
<LI><CODE>SERVER_ADMIN = root@localhost</CODE></LI>
<LI><CODE>SERVER_NAME = oit2.scps.nyu.edu</CODE></LI>
<LI><CODE>SERVER_PORT = 80</CODE></LI>
<LI><CODE>SERVER_PROTOCOL = HTTP/1.1</CODE></LI>
<LI><CODE>SERVER_SIGNATURE = </CODE></LI>
<LI><CODE>SERVER_SOFTWARE = Apache/2.4.10 (Fedora) mod_jk/1.2.40 PHP/5.5.26 mod_wsgi/3.5 Python/3.3.2</CODE></LI>
<LI><CODE>UNIQUE_ID = XQ1HPSilUo-77lGSpLVgjgAAAAI</CODE></LI>
</OL>

<H2>25 bytes of standard input</H2>

<PRE>year=2019&month=6&date=on</PRE>

<H2>3 values entered into the form</H2>

<OL>
<LI><CODE>date = on</CODE></LI>
<LI><CODE>month = 6</CODE></LI>
<LI><CODE>year = 2019</CODE></LI>
</OL>

<H2>Calendar</H2>

<PRE>
      June 2019     
Su Mo Tu We Th Fr Sa
                   1 
 2  3  4  5  6  7  8 
 9 10 11 12 13 14 15 
16 17 18 19 20 21 22 
23 24 25 26 27 28 29 
30                   

Fri Jun 21 17:08:13 EDT 2019
</PRE>
</BODY>
</HTML>

The browser renders the above output as follows.

Calendar

Calendar

34 environment variables

  1. CONTENT_LENGTH = 25
  2. CONTENT_TYPE = application/x-www-form-urlencoded
  3. CONTEXT_DOCUMENT_ROOT = /home/m/meretzkm/web
  4. CONTEXT_PREFIX = /~meretzkm
  5. DOCUMENT_ROOT = /var/www/html
  6. GATEWAY_INTERFACE = CGI/1.1
  7. HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
  8. HTTP_ACCEPT_ENCODING = gzip, deflate
  9. HTTP_ACCEPT_LANGUAGE = en-US,en;q=0.9
  10. HTTP_CACHE_CONTROL = max-age=0
  11. HTTP_CONNECTION = keep-alive
  12. HTTP_COOKIE = _ga=GA1.2.146985307.1534342603; _ap_utma=57748789.429615176.1535761070.1535761070.1535761070.1; __utma=57748789.146985307.1534342603.1553427371.1553427559.11; __utmz=57748789.1553427559.11.5.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
  13. HTTP_HOST = oit2.scps.nyu.edu
  14. HTTP_ORIGIN = http://oit2.scps.nyu.edu
  15. HTTP_REFERER = http://oit2.scps.nyu.edu/~meretzkm/python/misc/cgi.html
  16. HTTP_UPGRADE_INSECURE_REQUESTS = 1
  17. HTTP_USER_AGENT = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
  18. PATH = /usr/local/bin:/usr/bin:/bin
  19. QUERY_STRING =
  20. REMOTE_ADDR = 66.108.88.87
  21. REMOTE_PORT = 52626
  22. REQUEST_METHOD = POST
  23. REQUEST_SCHEME = http
  24. REQUEST_URI = /~meretzkm/cgi-bin/pythoncal.cgi
  25. SCRIPT_FILENAME = /home/m/meretzkm/web/cgi-bin/pythoncal.cgi
  26. SCRIPT_NAME = /~meretzkm/cgi-bin/pythoncal.cgi
  27. SERVER_ADDR = 128.122.238.18
  28. SERVER_ADMIN = root@localhost
  29. SERVER_NAME = oit2.scps.nyu.edu
  30. SERVER_PORT = 80
  31. SERVER_PROTOCOL = HTTP/1.1
  32. SERVER_SIGNATURE =
  33. SERVER_SOFTWARE = Apache/2.4.10 (Fedora) mod_jk/1.2.40 PHP/5.5.26 mod_wsgi/3.5 Python/3.3.2
  34. UNIQUE_ID = XQ1HPSilUo-77lGSpLVgjgAAAAI

25 bytes of standard input

year=2019&month=6&date=on

3 values entered into the form

  1. date = on
  2. month = 6
  3. year = 2019

Calendar

      June 2019     
Su Mo Tu We Th Fr Sa
                   1 
 2  3  4  5  6  7  8 
 9 10 11 12 13 14 15 
16 17 18 19 20 21 22 
23 24 25 26 27 28 29 
30                   

Fri Jun 21 17:08:13 EDT 2019

Test the form with Selenium

The JavaScript function scrollIntoView prevents the submitButton.click() from raising the selenium.common.exceptions.ElementClickInterceptedException.

"""
Test the calendar form.  Change myname to yourname.
"""

import sys
import time
import re
import selenium.webdriver

driver = selenium.webdriver.Chrome("/Users/myname/Downloads/chromedriver")
url = "http://oit2.scps.nyu.edu/~meretzkm/python/misc/cgi.html"
driver.get(url)

query = driver.find_element_by_name("year")
query.send_keys("2019")

radioButton = driver.find_elements_by_css_selector("input[type='radio'][value='6']")[0]
radioButton.click()

checkBox = driver.find_element_by_name("date")
checkBox.click()

submitButton = driver.find_elements_by_css_selector("input[type='submit']")[0]
driver.execute_script("arguments[0].scrollIntoView();", submitButton)
submitButton.click()

html = driver.page_source
if re.search("June 2019", html):
    print("found")
else:
    print("not found")

time.sleep(5)
driver.quit()   #Close the browser window.
sys.exit(0)
found

Things to try

  1. Have the gateway script display the output of /usr/bin/locale too. Remember to flush the standard output first.