Networking

_images/unicon.png

Index Unicon

Unicon Networking

Ahh, the network. Unicon supports client server computing.

Note

Update: Nov 16 2016

Unicon has been setup to run on SourceForge. CGI and other browser friendly demonstrations will be posted. For instance:

Simple CGI form echo

Network mode

Network mode n is the network client mode of open.

Network mode na is network accept (blocking server) mode of open.

Network mode nl is network listen (non-blocking server) mode of open.

Protocols include:

  • TCP Transmission Control Protocol
  • UDP User Datagram Protocol (add u to the open mode; for example “nua” for a blocking UDP server)

Message mode

Message mode m is a special network mode of open.

HTTP

HyperText Transport Protocol. A text based protocol used in much of the modern web.

Unicon handles HTTP by using open with a mode of m (or ms if only HTTP headers are needed, and no page data).

#
# http.icn
#
procedure main()
    # pull in the page
    url := "http://example.com"
    web := open(url, "m") | stop("Can't open " || url)
    page := ""
    while page ||:= read(web) || "\n"

    # pull out any title    
    page ? {
        tab(find("<title")) & tab(find(">")) & move(1) &
        title := tab(find("</title"))
    }
    close(web)

    # display the title, if any, and then the page
    write("Page title: ", \title)
    write(page)
end

examples/http.icn

Giving:

Page title: Example Domain
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

HTTPS

Secure (encrypted) HTTP. The text based HTTP protocol wrapped in encrypted packets. These packets use TLS and/or SSL encryption technology, a certificate based key pairing. An initial usually verified certificate is hosted by the server and temporary tokens are delivered to the client (browser) for single pair communications. This avoids clear text messaging, a rather easy thing to eavesdrop on, and or change in transit.

As of early Unicon 13 alpha releases, HTTPS is not quite ready. The encryption works, once setup. It is the setup that is not quite ready. It is not the smooth setup that will eventually be part of Unicon builds. There is internal certificate management issues that may require end user intervention. It will be advertised as ready when a basic build of Unicon does not require any extraordinary effort on behalf of a Unicon programmer. For example, the sample below required an externally set SSL_CERT_DIR environment variable before Jafar fixed the search path settings in SVN revision 4474 of the Unicon code base.

Note

Leaving the sample in, as it doesn’t “hurt”, but this override is no longer required (at least for Ubuntu based Unicon built from source).

#
# https.icn, read and show a secure webpage, extract title 
#
procedure main()
    local url, web, page, title

    # pull in the page
    url := "https://example.com"
    web := open(url, "m-") | stop("Can't open " || url)
    page := ""
    while page ||:= read(web) || "\n"

    # pull out any title    
    page ? {
        tab(find("<title")) & tab(find(">")) & move(1) &
        title := tab(find("</title"))
    }
    close(web)

    # display the title, if any, and then the page
    write("Page title: ", \title)
    write(page)
end

examples/https-full.icn

prompt$ SSL_CERT_DIR=/usr/lib/ssl/certs unicon https-full.icn -x
Parsing https-full.icn: .
/home/btiffin/uni13/unicon/bin/icont -c   -O https-full.icn /tmp/uni58860726
Translating:
https-full.icn:
  main
No errors
/home/btiffin/uni13/unicon/bin/icont  https-full.u -x
Linking:
Executing:
Page title: Example Domain
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

Without the external certificate finder, the program does did not function properly. Now, the environment setting is unnecessary.

prompt$ unicon https-full.icn -x
Parsing https-full.icn: .
/home/btiffin/uni13/unicon/bin/icont -c   -O https-full.icn /tmp/uni58860726
Translating:
https-full.icn:
  main
No errors
/home/btiffin/uni13/unicon/bin/icont  https-full.u -x
Linking:
Executing:
Page title: Example Domain
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

Verify

Messaging mode (open mode “m”) with https adds a new, optional, - flag, for skipping certificate verification. The default is to try and validate a certificate. "m" is more secure than "m-", but does require some external setup for certificate pairing. Otherwise the system will block access with:

cannot verify peer's certificate

When validation fails, open will fail.

More HTTPS

The Unicon project is on SourceForge. And the Allura system that makes up most of the forge user interface supports a rich API.

Apache Allura public API

To get the download counts for Unicon, using Unicon:

#
# https-json.icn, Try HTTPS with a SourceForge JSON query
#
# tectonics:
#     unicon -s https-json.icn -x | jq .downloads[-4:-1]
#
procedure main()
    uri := "https://sourceforge.net/projects/unicon/files/stats/json" ||
           "?start_date=2010-10-01&end_date=2110-10-01"
    web := open(uri, "m-") | stop("Can't open ", uri)
    showHeaders(web)

    size := 0 < integer(web["Content-Length"]) | stop("can't get the file size")
    data := reads(web, size) | stop("failed to reads ", size, " bytes")
    write(data)
    close(web)
end

# write HTTPS response headers to standard error
procedure showHeaders(m)
    local k
    every k := key(\m) do write(&errout, left(k||":", 32), m[k])
end

examples/https-json.icn

That program will pull down a JSON response from SourceForge. The captured command output asks jq (JSON query) for the last entry from the downloads list from the data displayed by Unicon. Web server response headers are also displayed from Unicon, directed to standard error to not interfere with the JSON data passed to the jq command. The capture only includes a limited range of the header lines from the output, hence the ellipsis.

prompt$ unicon -s https-json.icn -x | jq .downloads[-4:-1]
Status-Code:                    200
Reason-Phrase:                  OK
Server:                         nginx
Date:                           Wed, 13 Sep 2017 06:53:09 GMT
...
[
  [
    "2017-06-01 00:00:00",
    30
  ],
  [
    "2017-07-01 00:00:00",
    46
  ],
  [
    "2017-08-01 00:00:00",
    26
  ]
]

SMTP

Simple Mail Transfer Protocol

Todo

add a mail sending sample

POP

Post Office Protocol

You’ve got mail.

Todo

add a mail reader sample

CGI

There is a Technical Report (UTR4a 2011/02/04) Writing CGI and PHP Scripts in Icon and Unicon that details and lists working samples of Common Gateway Interface programming with Unicon. Methods for integrating Unicon with PHP is also explained.

http://unicon.org/utr/utr4.html

A CGI support layer is built along with unicon, so programmers only need to link cgi to take advantage of CGI features.

There is a small sample now hosted on SourceForge, to show off a very simple Unicon CGI program. simple-cgi.icn can be tried using a form posted at:

http://btiffin.users.sourceforge.net/form.html

form-cgi.html

<!-- Simple Unicon CGI example form -->
<HTML>
<HEAD>
<title>A Unicon HTML Form Example</title>
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 12;
        padding: 4;
        font-family: "Open Sans", "Helvetica Neue", Helvetica,
                      Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>
</HEAD>
<BODY>
<h1> A <tt>cgi.icn</tt> Demonstration</h1>
<form method="GET" action="/cgi-bin/simple.cgi">
    1. Name: <input type="text" name="name" size=25> <p>
    2. Age: <input type="text" name="age" size=3> &nbsp;Years <p>
    3. Quest:
        <input type="checkbox" name="fame">Fame</input>
        <input type="checkbox" name="fortune">Fortune</input>
        <input type="checkbox" name="grail">Grail</input><p>
    4. Favorite Color:
        <select name="color">
            <option>Red
            <option>Green
            <option>Blue
            <option selected>Don't Know (Aaagh!)
        </select><p>
    Comments:<br>
        <textarea rows=5 cols=60 name="comments"></textarea><p>
        <input type="submit" value="Submit Data">
        <input type="reset" value="Reset Form">
</form>
</BODY>
</HTML>

examples/simple-form.html

That form invokes:

simple-cgi.icn

#
# simple-cgi.icn
# tectonics:
#    unicon -B simple-cgi.icn
#    mv simple ../cgi-bin/simple.cgi
#
link cgi
procedure cgimain()
    # set defaults for both CGI and AJAX usage
    if /cgi["name"] | cgi["name"] === "" then cgi["name"] := "Guest"
    if /cgi["age"] | cgi["age"] === "" then cgi["age"] := "no"
    if /cgi["comments"] then cgi["comments"] := ""
    if /cgi["word"] then cgi["word"] := "" 

    # remove any potentially dangerous characters
    cgi["name"] := map(cgi["name"], "<>&%", "....")
    cgi["age"] := map(cgi["age"], "<>&%", "....")
    cgi["comments"] := map(cgi["comments"], "<>&%", "....")
    cgi["word"] := map(cgi["word"], "<>&%", "....")

    # output for the web
    cgiEcho("Hello, ", cgi["name"], "!")
    cgiEcho("Are you really ", cgi["age"], " years old?")
    cgiEcho("You seek: ", cgi["fame"]==="on" & "fame")
    cgiEcho("You seek: ", cgi["fortune"]==="on" & "fortune")
    cgiEcho("You seek: ", cgi["grail"]==="on" & "grail")
    cgiEcho("Your favorite color is: ", cgi["color"])
    cgiEcho("Your comments: ", cgi["comments"])
    cgiEcho("")
    cgiEcho("Your AJAX word: ", cgi["word"])
    cgiEcho("")
    cgiEcho("<a href=\"/demos/\">Home</a> / " || 
        "<a href=\"/demos/simple-form.html\">Back to HTML form</a> / " || 
        "<a href=\"/demos/simple-ajax.html\">Back to AJAX form</a>")
end

examples/simple-cgi.icn

Unicon was built on a SourceForge hosted CentOS server using a Developer Web Services shell. Details of how this was set up is documented in a blog entry, SourceForge. There will be more examples posted. An index page will be placed at

http://btiffin.users.sourceforge.net/demos/index.html

CGI 1.1

The full CGI 1.1 specification is referenced in RFC3875,

https://tools.ietf.org/html/rfc3875

AJAX

The simple.cgi demo can also be put to work with an AJAX interface.

<!-- simple-ajax.html, Unicon AJAX example -->
<html>
<head>
<title>Simple AJAX Example with Unicon</title>
<script language="Javascript">
function xmlhttpPost(strURL) {
    var xmlHttpReq = false;
    var self = this;
    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', strURL, true);
    self.xmlHttpReq.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded');
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            updatepage(self.xmlHttpReq.responseText);
        }
    }
    self.xmlHttpReq.send(getquerystring());
}

<!-- pass the form query -->
function getquerystring() {
    var form     = document.forms['form1'];
    var word = form.word.value;
    var name = form.name.value;
    var age = form.age.value;
    qstr = 'word=' + escape(word) + '&name=' + escape(name) +
           '&age=' + escape(age);
    return qstr;
}

<!-- change the result DOM div -->
function updatepage(str){
    document.getElementById("result").innerHTML = str;
}
</script>
</head>
<body>
An asynchronous Javascript to Unicon example.<br>
Pressing <b>Go</b> will cause an AJAX call to the server,
and CGI results will appear below
<form name="form1">
  <p>Name: <input name="name" type="text" size="25"></p>
  <p> Age: <input name="age" type="text" size="2"></p>
  <p>word: <input name="word" type="text">
  <input value="Go" type="button" 
      onclick='javascript:xmlhttpPost("/cgi-bin/simple.cgi")'></p>
  <div id="result"></div>
</form>
</body>
</html>

examples/simple-ajax.html

That AJAX example invokes the same server side simple-cgi.icn as the CGI form. The server side program is not a CGI application in this case, and there is not the same set of environment variables that a web server will set up for CGI programs, but the example program accounts for this to produce AJAX ready output.

PHP

PHP (initially PHP/FI, Personal Home Page/Forms Interpreter, now know as PHP: Hypertext Preprocessor) is a widely used server side scripting language. PHP was never really meant to be a programming language, but has attained a lead position as a tool of choice for many web applications.

“I don’t know how to stop it, there was never any intent to write a programming language […] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way.”

—Rasmus Lerdorf

Unicon can leverage that unstoppable project. PHP is almost always available along side any web server install, and is a feature rich and well supported web development environment.

Todo

add Unicon, PHP integration sample


Index | Previous: Database | Next: Threading