GEhttpd

Goals

After this tutorial, you should be able to

  1. Install the GEhttpd server
  2. Configure the server settings
  3. Create URL routes to map to GAUSS procs
  4. Rules for passing data to GAUSS
  5. Test URLs from separate clients

Install

  1. Prerequisite: The GAUSS Engine must first be installed. Note the installation path for configuring the server settings. The default paths will be C:\mteng19 for Windows and ~/mteng19 for non-Windows installations.
  2. Unzip gehttpd.zip to a directory of your choice.

TODO: Add Windows/Linux service scripts


Configure

Open gehttpd/etc/gehttpd.ini in an editor of your choice that will maintain the correct line endings (ie do not use Notepad). In most cases the default settings will suffice, but can be modified. Only basic settings will be covered here.

Fields are described in comments.

  1. Edit host / port settings. Default settings should suffice.
    [listener]
    ; uncomment the below line to specify a specific address to bind to.
    ; the default is to bind to all available IPv4/IPv6 network interfaces
    ;host=127.0.0.1
     
    ; the default port is 5050. since this is most beneficial to run as
    ; an application server, not running on port 80/443 allows a separate
    ; traditional web server such as apache or nginx to run alongside it.
    port=5050
  2. Edit GAUSS routes
    [gehttpd]
    ; specify the GAUSS Engine installation path.
    home=C:/mteng19
     
    ; specify the GAUSS source files to parse. multiple files are 
    ; separated with the pipe '|' character and the path is relative
    ; to the root of the gehttpd directory
    filenames=test/sample.e|test/echo.e
     
    ; setting persistent workspace to 1 enables session handling.
    ; each individual client will have their own GAUSS workspace
    ; stored in a session, meaning subsequent requests can access
    ; or modify global symbols from previous requests. 
    ; disabling this option means a clean workspace will be used 
    ; with each new request
    persistentWorkspace=0
  3. (Optional) Edit logging location.
    [logging]
    ; default log location is gehttpd/logs/gehttpd.log
    ; comment out the below line to have all activity logged to
    ; the console
    fileName=../logs/gehttpd.log

Create URL routes to map to GAUSS procs

These files are to be included in the filenames key of the gehttpd.ini configuration file.

A URL route to GAUSS proc mapping consists of 3 steps:

  1. Include the gehttpdroutes.src file. This is only necessary once per source file.
  2. Define the GAUSS proc
  3. Use the route function to tell gehttpd how to handle the proc and associated URL path.

The 'route' function explained

/*
**> route
**
**  Purpose:    Register a URL route with the gehttpd web server.
**
**  Format:     route(url, procname, args);
**
**  Input:      url    string, the relative path used to access the GAUSS proc
**                     from a client. Always starts with a forward-slash '/'.
**
**                     Can have multiple forms:
**                       1. "/sample" : The most traditional URL style, where all 
**                          arguments (or none) are passed to the web server as GET 
**                          or POST parameters.
**
**                       2. "/sample/<foo>/<bar>" : A REST style URL. Arguments are 
**                          specified directly in the URL surrounded by brackets. 
**                          These argument names must match up to the argument names 
**                          in the third argument of the 'route' method.
**
**                          NOTE: The order does not have to be the same as the order
**                                specifed in 'args'.
**
**          procname    string, the name of the GAUSS proc to execute when the 
**                      specified URL is accessed.
**
**              args    string, ordered comma-delimited list of arguments that the 
**                      proc accepts. These argument names must match the web request 
**                      parameter names exactly. This argument determines the correct
**                      ordering when calling the GAUSS proc.
**
**                      NOTE: Prefixing an argument with the '$' character denotes that
**                            this argument will always be converted to a string when
**                            the GAUSS proc is executed.
**
*/
proc route(url, procname, args);

Example 1

The following example will cover the most basic proc possible. A simple echo proc that returns the argument passed in.

// Step 1: Include the gehttpdroutes.src file
#include gehttpdroutes.src

// Step 2: Define the GAUSS proc
proc (1) = echo(v);
    retp(v);
endp;

// Step 3: Instruct gehttpd how to handle this proc.
route("/echo", "echo", "v");

Testing this example

http://localhost:5050/echo?v=50

Example 2

This example will show how to force certain proc arguments to be strings. This can be helpful in cases where the client passes a numeric parameter but the GAUSS proc argument expects a string.

#include gehttpdroutes.src

proc (1) = hello(name);
    retp("Hello " $+ name);
endp;

// Two separate styles
route("/hello", "hello", "$name");

// note that the URL does not have to match the name of the proc
route("/say_hi_to/<name>", "hello", "$name");

Testing this example

  1. http://localhost:5050/hello?name=Alice
  2. http://localhost:5050/say_hi_to/Alice

Example 3

This example will show to pass multiple arguments into a proc using both traditional and REST style paths.

#include gehttpdroutes.src

proc (1) = subtract(a, b);
    retp(a-b);
endp;

route("/minus", "subtract", "a,b");

// this REST style shows how multiple path separators can be used
// NOTE that we can also specify the REST arguments in any order we choose as
// long as we correctly specify the order correctly in the third argument.
// (ie 'b' and 'a' could be swapped in the path)
route("/<a>/minus/<b>", "subtract", "a,b");

Testing this example

  1. http://localhost:5050/minus?a=10&b=5
  2. http://localhost:5050/minus?b=5&a=10
  3. http://localhost:5050/10/minus/5

Rules for passing data to GAUSS

The following rules describe acceptable ways to pass data via GET or POST requests to GAUSS. Python will be used to illustrate the rules.

If submitting as a POST request, then the entire POST body can also be JSON encoded. This is most useful in the context of JSON-encoding an entire dictionary as opposed to each argument individually.

Scalars / Strings

Scalar arguments can be set directly (do not have to be JSON-encoded with type)

# GET
r = requests.get('http://localhost:5050/minus', params={'a': 50, 'b': 25})
# GET
r = requests.get('http://localhost:5050/echo', params={'v': 'hello world'})
# POST - not necessary to use json.dumps when passing scalars only
r = requests.post('http://localhost:5050/minus', data={'a': 50, 'b': 25})

Matrices and string arrays

Matrices or string arrays are required to be JSON-encoded. Please note the json.dumps

args = {
    'a': json.dumps({
        'type': 6,
        'rows': 2,
        'cols': 2,
        'data': [1, 2, 3, 4]
    }),
    'b': 1
}

# GET
r = requests.get('http://localhost:5050/minus', params=args)

#POST
r = requests.post('http://localhost:5050/minus', data=args)

String arrays are dealt with the same as matrices.

args = {
    'v': json.dumps({
        'type': 13,
        'data': ["one", "two", "three", "four"]
    })
}

# GET
r = requests.get('http://localhost:5050/echo', params=args)

#POST
r = requests.post('http://localhost:5050/echo', data=args)

Test URLs from separate clients

The tests below are based off the previous examples. More examples are located in the gehttpd/test/test.py file.

Python

The following Python tests make use of the requests package. This can be installed via pip install requests

  1. Test the echo proc with a number

    import requests
    import json
    
    r = requests.get('http://localhost:5050/echo', params={'v': 5})
    
    # the response will by default be json and parsable as such
    # {"success":true,"results":[{"type":6,"rows":1,"cols":1,"data":[5.0]}]}
    
    print("Echo returned {}".format(json.loads(r.text)["results"][0]["data"][0]))
  2. Test the echo proc with a string and specify return format as raw

    import requests
    
    r = requests.get('http://localhost:5050/echo', 
                      params={'v': 'Hello World', 'fmt':'raw'})
    print(r.text) # prints 'Hello World' directly
  3. Test the 'subtract' proc with a POST style request

    import requests
    import json
    
    r = requests.post('http://localhost:5050/minus',
                      data=json.dumps({'a': 25, 'b': 5}))
    print(json.loads(r.text))

PHP

  1. Test the echo proc with a number
    <?php
    $args = http_build_query(array("v"=>5));
    $data = file_get_contents("http://localhost:5050/echo?".$args);
    $r = json_decode($data, true);
    print_r("Echo returned ".$r["results"][0]["data"][0].PHP_EOL);
    ?>

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.

Try GAUSS for 14 days for FREE

See what GAUSS can do for your data

© Aptech Systems, Inc. All rights reserved.

Privacy Policy