Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a "Hello, World" CGI with Rebol 3?

Tags:

cgi

rebol

rebol3

Lets start with something simple: a form with a field which gets echoed.

like image 267
dt2 Avatar asked Jan 02 '13 14:01

dt2


1 Answers

At the time of this writing (2013-01), Rebol 3 still lacks the few CGI-supporting functions which were bundled with Rebol 2. However, if you are fine with hacking up the missing CGI support yourself, you can still get going right away.

Before we start, you need to store the R3 binary on the machine you want to run your CGI, and you need to know the full path to where you stored it (for simplicity's sake). The following examples assume a Unix-style machine with the R3 binary in /usr/local/bin/rebol3.

Let's start with something even more simple than you requested: a CGI just sending a "Hello, World!" page:

#!/usr/local/bin/rebol3 -cs
REBOL []
prin [
    "Content-type: text/html" crlf
    crlf
    <!doctype html>
    <title> "Rebol 3 CGI Sample: Hello" </title>
    "Hello, World!"
]

This is identical to what you'd write in R2.

Onward to something slightly more interesting: reading and parsing a HTML form submission, as you requested.

For this we need to know two things about CGI: submitted data is passed as standard input to the CGI; other CGI-specific information is passed from the webserver via environment variables. We can access the input data in R3 via the system/ports/input port, and read environment variables by using the get-env native.

Let's embed the HTML form itself into the CGI, and do a mode switch within the CGI: if no data was submitted, show the HTML form; if data was submitted, process it and show an appropriate response. We can do that by writing a form that submits data via HTTP method POST, and then checking within the CGI if it was invoked via HTTP method GET (no data) or POST (form data). The method a CGI script was invoked with is available via the REQUEST_METHOD environment variable.

With all that said, here's the full script without further ado:

#!/usr/local/bin/rebol3 -cs
REBOL []

handle-get: function [] [
    prin [
        "Content-type: text/html" crlf
        crlf
        <!doctype html>
        <title> "Rebol 3 CGI Sample: Form" </title>
        <form method="POST">
            "Your name:"
            <input type="text" name="field">
            <input type="submit">
        </form>
    ]   
]

handle-post: function [] [
    data: to string! read system/ports/input
    fields: parse data "&="
    value: dehex select fields "field"
    prin [
        "Content-type: text/html" crlf
        crlf
        <!doctype html>
        <title> "Rebol 3 CGI Sample: Response" </title>
        "Hello," (join value "!")
    ]
]

main: does [
    switch get-env "REQUEST_METHOD" [
        "GET" [handle-get]
        "POST" [handle-post]
    ]
]

main

The final piece to understanding this script is how to actually parse HTML form data sent to the CGI. Rebol 2 had a decode-cgi helper function for this, which Rebol 3 currently lacks.

However, for basic forms, it suffices to know that CGI data is sent in an encoding that seperates fields with & and the field's name and value with =; everthing is URL-encoded. So if we submit the form embedded above with a value of "Charlie", the CGI will receive field=Charlie as input. Submitting "Foo Bar" sends "field=Foo%20Bar". So, again: for basic forms, the combination of parse ... "&=" (for splitting up fields and field names and values) and dehex (for decoding the URL-encoding) as shown above will suffice.

like image 103
earl Avatar answered Jan 04 '23 15:01

earl