diff options
Diffstat (limited to 'cgi.html')
| -rw-r--r-- | cgi.html | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/cgi.html b/cgi.html new file mode 100644 index 0000000..e1c210b --- /dev/null +++ b/cgi.html @@ -0,0 +1,268 @@ +<!DOCTYPE html> +<html lang=en> + <head> + <title>Server-Side Scripting with CGI</title> + <meta charset="utf-8"/> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" /> + <link rel='stylesheet' type='text/css' href='style.css'> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'> + </head> +<body> + <header><h1>Server-Side Scripting with CGI</h1></header> + <nav></nav> + <main> + <p> + The basic website tutorial here describes how to set up a static + website — one that just serves HTML files saved on your server, + and until you change something manually, the same content will be served + each time a given page is requested. This is perfectly enough for most + personal website needs. This is how blogs should be implemented, instead + of relying on bloatware like WordPress! + </p> + + <p> + But sometimes you genuinely <i>do</i> need something more. You need your + website to serve different contents depending on the time, on who the + requester is, on the contents of a database, or maybe process user input + from a form. + </p> + + <h2>CGI</h2> + <p> + CGI, or the Common Gateway Interface, is a specification to allow you, + the server owner, to program your web server using pretty much any + programming language you might know. The specification is almost as old + as the Internet itself and for a long time CGI scripting was the primary + method of creating dynamic websites. + </p> + + <p> + CGI is a very simple specification indeed. You write a script in your + favorite language, the script receives input about the request in + environment variables, and whatever you print to the standard output + will be the response. Most likely, though, you will want to use a + library for your language of choice that makes a lot of this + request/response handling simpler (e.g. parsing query parameters for + you, setting appropriate headers, etc.). + </p> + + <h3>Limitations of CGI</h3> + <p> + While in theory you could implement any sort of functionality with CGI + scripts, it's going to get difficult managing a lot of separate scripts + if they're supposed to be working in tandem to implement a dynamic + website. If you want to build a full out web application, you'd probably + be better off learning a web framework than gluing together Perl + scripts. + </p> + + <p> + That said, just as most of the web could be replaced with static + websites, much of the remaining non-static web could be replaced with a + few simple scripts, rather than bloated Ruby on Rails or Django + applications. + </p> + + <h2>Let's write a CGI script!</h2> + + <p> + We'll implement a simple example CGI script. I'll use Ruby for this + tutorial, but you'll be able to follow along even if you don't know + Ruby, just treat it as pseudocode then find a CGI library for your + language. + </p> + + <h3>The working example</h3> + + <p> + Our working example will be the Lazy Calculator. Yeah, you're probably + tired of seeing calculator examples in every programming tutorial, but + have you ever implemented one that takes the weekends off? + </p> + + <p> + Here's how it will work. When in a browser you submit a request to your + website like + </p> + + <pre><code>example.com/calculator.html?a=10&b=32</code></pre> + + <p> + you will receive a page with the result of the addition of 10 and 32: + 42. + </p> + + <p> + <i>Unless</i> you send your request on a weekend. Then the website will + respond with + </p> + + <pre><code>I don't get paid to work on weekends! Come back Monday.</code></pre> + + <p> + This example will show a few things that CGI scripts can do that you + wouldn't have been able to get using just file hosting in your + web server: + + <ul> + <li> getting inputs from the user; </li> + <li> + getting external information (here just the system time, but you + could imagine instead connecting to a database); + </li> + <li> using the above to create dynamic output. </li> + </ul> + + <h3>The code</h3> + + <p> + Here's an implementation of the lazy calculator as a Ruby CGI script: + </p> + + <pre><code>#!/bin/env ruby + +require 'cgi' +require 'date' + +cgi = CGI.new +today = Date::today + +a = cgi["a"].to_i +b = cgi["b"].to_i + +if today.saturday? || today.sunday? + cgi.out do + "I don't get paid to work on weekends! Come back Monday." + end +else + cgi.out do + (a + b).to_s + end +end</code></pre> + + <p> + Let's go through what's happening here. + </p> + + <h3>The shebang line</h3> + <p> + CGI works by pointing your web server to an executable program. A Ruby + or Python script by itself is not immediately executable by a computer. + But on Unix-like systems you can specify the program that will be able + to execute your file in its first line if it starts with <code>#!</code> + (known as the shebang; read more about it on + <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">Wikipedia</a>). + </p> + + <p> + So if you're going to be using a scripting language, you'll probably + need the appropriate shebang line at the top of your script. If you use + a compiled language, you'll just point your web server to the compiled + executable binary. + </p> + + <h3>Query parameters</h3> + <p> + The next interesting lines of code are where we set the variables + <code>a</code> and <code>b</code>. Here we are getting user inputs from + the request. + </p> + + <p> + In the example request we mentioned above + (<code>example.com/calculator.html?a=10&b=32</code>), the part + starting from the question mark, <code>?a=10&b=32</code>, is the + <i>query string</i>. This is how users can submit parameters with their + web requests. Usually these parameters are set by e.g. a form on your + website, but in our simple example we'll be just manually manipulating + the URL. + </p> + + <p> + The query string contains key-value pairs. The Ruby CGI library makes + them available in the <code>CGI</code> object it provides. We just need + to index it with the desired key, and we'll get the corresponding value. + </p> + + <h3>Wrapping it up</h3> + <p> + The remaining parts of the code should be pretty self-explanatory. We + get today's date, check if it's a Saturday or a Sunday, and depending on + that, we instruct the CGI library to output either the answer, or a + "come back later" message. + </p> + + <p> + The Ruby library by default returns an HTML response, so we really + should have wrapped our outputs in some <code>html</code>, + <code>body</code>, etc. tags. Alternatively, we could have specified + that the response is just plain text with + </p> + + <pre><code>cgi.out 'text/plain' do</code></pre> + + <p> + In general, your CGI library will probably have ways of specifying all + sorts of HTTP response headers, like status code, content type, etc. + </p> + + <h2>Making it work</h2> + <p> + We have a CGI script, now let's point our web server to it. + </p> + + <h3>Installing FastCGI</h3> + + <p> + If you're using Nginx, install <code>fcgiwrap</code>: + </p> + + <pre><code>apt install fcgiwrap</code></pre> + + <p> + This installs the necessary packages for Nginx to use FastCGI — a + layer between your web server and CGI script that allows for faster + handling of scripts than if the web server had to handle it all by + itself. + </p> + + <p> + Other web servers will probably have a similarly simple way of enabling + FastCGI, or you can look into other methods for launching CGI scripts. + </p> + + <h3>Nginx configuration</h3> + <p> + In the configuration file for your website, add something like the + following: + </p> + +<pre><code>location /calculator.html { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME /usr/local/bin/lazy-calculator.rb; + fastcgi_param QUERY_STRING $query_string; + fastcgi_pass unix:/run/fcgiwrap.socket; +}</code></pre> + + <p> + <code>fastcgi_param</code> directives specify various parameters for + FastCGI. <code>SCRIPT_FILENAME</code> should point to your executable. + For <code>QUERY_STRING</code>, we just copy Nginx's + <code>$query_string</code> variable. You might want to pass other + information to your CGI script as well, see for example + <a href="https://wiki.debian.org/nginx/FastCGI">the Debian wiki</a> for + a more detailed example, including pointing to an entire directory of + CGI scripts, rather than adding each one by hand to your web server + config. + </p> + + <h2>Contribution</h2> + <ul> + <li>Martin Chrzanowski -- <a + href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li> + </ul> + </main> + <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="donate-bitcoin.html"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="donate-monero.html"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer> +</body> +</html> |
