# Common Gateway Interface

## Projects in Information Technology II

http://www.sw.it.aoyama.ac.jp/2019/Projects2/lecture4.html

## Martin J. Dürst

© 2019 Martin J. Dürst 青山学院大学

# ミニテスト

• デスクトップPC (強く推薦) 又はノートPCで https://moo.sw.it.aoyama.ac.jp/ にログイン済み
• ナビゲーションは左に畳み、ブラウザは全画面に拡大
• もう片方のマシーンで電源を切る (ノートPCの場合、鞄に)
• 授業開始まで教科書、資料、筆箱、財布などを鞄に入れ、鞄は床に
• テスト終了後その場で待つ

# Today's Schedule

• Minitest
• Last week's exercises and homework
• Iterators and blocks for loops, with demo
• Dynamic Web sites with CGI, with demo
• Today's exercises

# How to Be Successful in this Course

• Contents is progressive ⇒ Don't forget previous lecture's content
• Contents is not necessarily complete, on purpose
(no simple typing or filling in the blanks)
• Learn to ask questions (better use Moodle)
• Learn to search the Web when needed
• Learn to distinguish what you know and what you don't know
• Work to make sure to plug gaps in your knowledge

# Last Lecture's Exercises

## Exercise 3a: Calendar Conversion

• Write a function `to_japanese_calendar` in a file `japanese_calendar.rb`.
• The function takes a year (`Integer`) in the Western calendar as an argument.
• The function returns a `String` indicating the year in the Japanese calendar.
• Solution: `def` with `if` statement with a branch for each era and for the exceptions.

## Exercise 3b: Temperature Conversion

• Write a class `Temperature` in a file `temperature.rb`.
• An object of a class `Temperature` represents a temperature.
• Set the temperature to 20℃ on initialization (this is a nice temperature).
• Create methods for access (`celsius`, `fahrenheit`, `kelvin`) and setting (`celsius=`, `fahrenheit=`, `kelvin=`).
• Solution: Very similar to example class `Length`

## Homework

• Review the most important Ruby classes: `Integer`, `Float`, `String`, `Array` (incl. `Enumerable`), `Hash`
• Study a few methods for each class

# Course Overview

• 1st week: HTML markup ⇒ structure
• 2nd week: CSS stylesheet ⇒ styling
• Starting in 3rd week: Programming on the server side with Ruby
• Today: First time we use a Web server and create a Web page with a program

# Loop Example

```(1..5).each do |n|
puts n
end```

# Range

• `a..b` is a `Range` from `a` to `b` (inclusive).
• Because of precedence, `Range`s are usually written in parentheses.
• `Range`s can be used for simple loops.

# Loops in Ruby

• For loops in Ruby, use iterators
• There are many convenient iterators, but the most important one is `each`
• Many iterators are defined in `Enumerable`, so they work for `Arrays`, `Ranges`, `Hashes`,…
• Iterators take blocks that do the actual work in each iteration

# Ruby Blocks

• Part of arguments to a function/method call
• Appear after all other arguments
• Start/end with `do` `end` or `{` `}`
• General style:
• `do` `end` used for multiline blocks
• `{` `}` used for inline blocks
• Block parameters (loop variables,…) appear between `|` `|`, after `do` or `{`
• Blocks make Ruby very powerful, you can use this power, too

# More Loop Examples

```(1..5).each  { |n| puts n }

(1..5).each  { |i| puts i }

(1..5).each  { |n| puts n+3, n*3 }

(1..10).each { |n| puts n }

(1...5).each { |n| puts n }

(1..5).each do |n| puts n end

[2,3,5,7,11].each { |n| puts n }

[1,2,4,8].each { |n| puts n**n }```

Many of these examples use `Range`s, but use on `Array`s is even more common.

# Dynamic Web Sites

• With HTML, we can create static documents
• But on a Web page, we also want to show dynamic results
• One way to show dynamic results is to create a Web page on the Web server with a program
• This can be done with CGI

# CGI Basics

• CGI: Common Gateway Interface (see RFC 3875 for details)
• Program to generate Web page is called externally from Web server
• Old and well established, but slow
• Easy to understand
• Traditionally used with Perl (and C), we will use Ruby
• Traditional extension is `.cgi`, we will use `.rb`
• Not very flexible, and slow

# How CGI Works

```---------------               --------------------------------------
| client      |               |             server machine         |
| machine     |               |                                    |
|             | (1)           |              (2) set ENV           |
| ----------- | HTTP request  | ------------ call script --------- |
| |         |------------------>|          |------------>|       | |
| | client  | |               | |Web server|             | CGI   | |
| |(browser)| |               | |(webrick) |             | script| |
| |         |<------------------|          |<------------|       | |
| ----------- | HTTP response | ------------ (3) stdout  --------- |
--------------- (4)           --------------------------------------```

# CGI Input and Output

• Input: Environment variables (環境変数) carefully set by the Web server
(accessible in Ruby via `ENV`)
• Output: To standard output
`Content-Type: text/html;charset=UTF-8`
• Empty line
(HTTP headers and empty lines have to end with `\r\n`, not just `\n`)
• Web page itself (from `<!DOCTYPE` to `</html>`)

# Web Servers

• A Web server
• Waits for a TCP connection on a specific port
• Analyses the input
• If necessary, calls other programs
• Returns a Web page or other resource (e.g. stylesheet, image,…)
• There are many Web servers:
• General Web servers: Apache httpd, ngnix, IIS
• Web servers often used with Ruby/Rails: mongrell, unicorn, puma
• Web server that comes with Ruby: webrick

# CGI Demo

• Open a new "Start Command Prompt with Ruby"
(you can open as many of these as you want;
I recommend one for `irb`, one for webrick, and one for general commands)
• `cd` to the directory you use for this practice
• Create a directory for starting the server, and cd to it:
`mkdir webrick; cd webrick`
• Download the startup script `webrick_start.rb` from Moodle
• Start webrick with: `ruby webrick_start.rb`
• Create a Ruby CGI script in the same directory (e.g. my_first_cgi.rb)
• Open a browser and go to `http://localhost:12000/my_first_cgi.rb`
• Watch the output in the command prompt window, and check headers with browser development tools

# CGI Security

• Any Web server that executes code is a potential security problem
• Carefully check Web server settings
• Limit CGI scripts to specific directories and extensions
• Carefully check CGI scripts before activation
• Carefully escape and check all input

# More on Ruby Output

• A CGI script outputs a lot of text
• Using `puts` for each line of a Web page is quite tedious
• String literals can extend to multiple lines:
```"This is a long, long, long string."```
• Here documents are better:
```html_end = <<HTMLEND  </body>
</html>
HTMLEND```

# Exercise 4a: A Program to Convert Marks

• Write a program in a file `convert_marks.rb` to output a conversion table for all points from 0 to 100, in the following form:
```  0 points ->   0 points
1 points ->  10 points
...
...
100 points -> 100 points```
• The following function can be used to change students' marks:
```def convert_mark(mark, exponent)
(mark**exponent * (100.0/100**exponent)).round
end```

The argument `mark` is a mark between 0 and 100. The argument `exponent` changes how the conversion is done. If the `exponent`is smaller than 1, then the marks get better. If the `exponent` is greater than 1, then the marks get worse. But they always stay between 0 and 100.

• Hints:
• For formatting, use the `%` operator on the `String` class: `"%3d" % integer`.
• Check out and use `ARGV[0]` to change the exponent. As an example, calling the program with
`ruby convert_marks.rb 0.7`
should set the exponent to 0.7.
• Use an exponent of 0.5 if there is no exponent given.
• Submit the final program `convert_marks.rb` to Moodle (deadline: 17:30).

# Exercise 4b: A Web Page to Convert Marks

• Change the program from exercise 4a to a program in a file `convert_marks_page.rb`. This program creates (prints out) a Web page with a table showing the marks.
• Hints:
• Use your knowledge from lecture 1 to create the Web page.
• Use your knowledge from lecture 2 to add some table borders using styling. Put your style rules into a `style` element inside the `head` element.
• Use 'Before' and 'After' as table headings (`th`).
• Make sure you have a good `title` and `h1`.
• Use redirect to create a Web page: ```ruby convert_marks_page.rb 0.8 > convert_marks_page.html```
• Open your page in a Web browser to check it. But do not rely on the Web browser too much.
• Validate your Web page the way you have learned it in lecture 1.
• Submit the final program `convert_marks_page.rb` to Moodle (deadline: 18:00).

# Exercise 4c: A CGI Script to Convert Marks

• Change the program from exercise 4b to a CGI program in a file `convert_marks_cgi.rb`.
• Hints:
• Add output of CGI headers at the start of the output.
• Use ENV[QUERY_STRING] to get the `exponent`.
• Make sure webrick is started in the same directory as `convert_marks_cgi.rb`.
• You can change the program and reload the page without shutting down webrick.
You can also shut down and restart webrick any time you want.
• Use a browser to access `http://localhost:12000/convert_marks_cgi.rb`
• Add the exponent at the end of the URI after a question mark, e.g.:
`http://localhost:12000/convert_marks_cgi.rb?0.6`
• Submit the final program `convert_marks_cgi.rb` to Moodle (deadline: 18:30).

# Exercise 4d: Advanced Exercise (発展問題): An Advanced CGI Script to Convert Marks

• Create an improved CGI script in a file `convert_marks_advanced.rb`, with someone of the following or your own ideas:
• Provide links to pages with different exponents.
• Add a `form` element to make it easier to set the `exponent`.
• Use `require 'cgi'`, `cgi = CGI.new`, and `cgi[field_name]` to access form fields.
• Show conversions for more than one exponent in a single table.
• Shorten the table by showing conversions only for even marks, or for marks divisible by 5.
• Show the results for more than one exponent in additional rows in the table.
• Submit the final program `convert_marks_advanced.rb` to Moodle (deadline: Wednesday 19:00).
`gem install rails -v 5.2.3`
`rails --version`
• Use `irb` to play with arrays and iterators (`each`, `map`, `select`, `reject`, `inject`,…).