-
Notifications
You must be signed in to change notification settings - Fork 108
HTTP on Soletta flows
These nodes implement the client and server side of the protocols HTTP and HTTPS. It allows one to make any kind of request, i. e. set custom headers, data, method and so on. Also, it's possible to serve the basic types such as booleans, strings, integers and floats. Also there is node to deal with OAuth authentication process.
Soletta™ Framework has plenty of utility nodes dealing with HTTP in both sides, client and server:
-
http-client/int
http-client/string
http-client/boolean
http-client/float
http-client/get-string
http-client/get-blob
http-client/get-json
http-client/request
http-client/get-url
http-client/get-response-code
http-client/get-content-type
http-client/get-content
http-client/get-headers
http-client/get-cookies
All the client nodes have in common two options, url
(optionally it can be set using an input port) and machine_id
that
is an unique identifier of the device.
The basic type client nodes are meant to interface with their respective server
counterparts only. Each of them is capable of either GET
ing or POST
ing the
respective types they treat. Naturally, the get method will produce output on their
OUT
ports with the value coming from the respective server node. We have four
types of basic type client nodes:
It makes a request, both methods GET and POST are possible, for an url
and parse the response to its type. These nodes were designed to be used
with the http-server basic types http-server
.
server(http-server/int:path=/irange)
keyboard(keyboard/int) OUT -> POST irange(http-client/int:url="http://127.0.0.1:8080/irange")
keyboard2(keyboard/boolean:binary_code=98,toggle=true) -> GET drange(http-client/float:url="http://127.0.0.1:8080/drange")
irange OUT -> IN console(console)
drange OUT -> IN console
The following example:
_(constant/int:value=1) OUT -> POST irange(http-client/int:url="http://127.0.0.1:8080/irange")
can easily be mapped to curl
:
curl --data="value=1" http://127.0.0.1:8080/irange
This category of client nodes makes it possible to do generic GET
requests without try to parse the response's contents. Using these
nodes the one will be able to enforce the content-type and with the
properly node get the converted output.
If one wants to get the entire contents of a web page, the
http-client/get-string
does the job:
get_string(http-client/get-string:url="http://www.google.com") OUT -> IN StringResponse(console)
but if the idea is to transfer binary data, then one can use http-client/get-blob
BlobPath(app/argv:index=1)
_(constant/string:value="https://raw.githubusercontent.com/solettaproject/soletta/master/doc/node-types-html/images/button_back.png") OUT -> URL get_blob(http-client/get-blob)
get_blob OUT -> IN Writer(file/writer:permissions=777)
BlobPath OUT -> PATH Writer
_(constant/empty) OUT -> GET get_blob
Finally, if it's more convenient to have output as json, the
http-client/get-json
should be used. The response of this node
is deliveried as a json-object
or as json-array
.
Now, if more granularity and power are necessary,
http-client/request
node and its helpers certainly should be
used. With this family of nodes, one will be able to set all aspects
from a request, and get/split all properties of a response such as,
timeout, method, query parameters, content type, user/password,
cookies, and so on. This family of low level HTTP requests is made up
by the following nodes:
-
http-client/request
-
http-client/get-url
-
http-client/get-response-code
-
http-client/get-content-type
-
http-client/get-content
-
http-client/get-headers
-
http-client/get-cookies
Here's an example of their usage:
HttpHead(http-client/request:url="https://github.com/solettaproject/soletta", method="HEAD") ERROR -> IN Error(console)
Start(constant/empty) OUT -> TRIGGER HttpHead
HttpHead OUT -> IN HTTP_Packet(console)
HttpHead OUT -> IN _(http-client/get-response-code) OUT -> IN ResponseCode(console)
HttpHead OUT -> IN _(http-client/get-content-type) OUT -> IN ContentType(console)
HttpHead OUT -> IN _(http-client/get-url) OUT -> IN Url(console)
HttpHead OUT -> IN _(http-client/get-content) OUT -> IN Content(console)
HttpHead OUT -> IN _(http-client/get-headers:key="Date") OUT -> IN HeaderDate(console)
HttpHead OUT -> IN _(http-client/get-cookies:key="A cookie") OUT -> IN SetCookie(console)
The server node family allows one to serve Soletta framework's basic types to the counterpart client nodes. The most common use of these simple, direct nodes would be serve the states of sensors via HTTP. Their values/states can naturally be changed by packets in the IN port or through a POST. There's also a node to serve static files.
All nodes bind to all host's interfaces in the port specified in the options. If no port is given the node uses the default port set on build. The server nodes are the following:
The following example shows how to expose a resource, like a led, using a HTTP server. In this example the led can be controlled through a button or HTTP. In order to make the sample simpler, the GTK led node is used, instead of a real GPIO one.
switch(gtk/toggle) OUT -> IN boolean(http-server/boolean:path=/boolean,value=false)
constant(constant/boolean:value=false) OUT -> IN led(gtk/led:rgb=255|0|0)
boolean OUT -> IN led
To get the led state is easy using a HTTP request curl http://127.0.0.1:8080/boolean
, where 127.0.0.1
must be replaced
with the machine's ip in case of a request from other host.
Now, if one wants to serve static files, like any ordinary HTTP
server, the http-server/static
should be used. In this node one
must give the directory where the static files are (path
parameter) and the namespace where this files will be accessible from
(namespace
parameter). Also it's possible to set if the files will
be served as soon as the node is instantiated or not. One can stop
to serve the files at anytime just sending a packet in the ENABLED
port.
# Reads key 'a' (code 97) from keyboard (stdin) to enable/disable.
keyboard(keyboard/boolean:binary_code=97,toggle=true) OUT -> ENABLED static(http-server/static:path="/tmp/www/",namespace="/static",start=false)
The OAuth node simplifies the oauth authentication process. It makes easy for one to get the access tokens from web services that uses this kind of authentication.
The following example can be used to authenticate one on twitter:
oauth(oauth/v1:request_token_url="https://api.twitter.com/oauth/request_token",consumer_key="<consumer_token>",namespace="/twitter",consumer_key_secret="<consumer_private>",authorize_token_url="https://api.twitter.com/oauth/authorize",access_token_url="https://api.twitter.com/oauth/access_token")
oauth TOKEN -> IN console(console)
just replacing consumer_key
and consumer_key_secret
with
the proper twitter application values. In the example above, one
should access the link
http://the_host_ip_here:8080/twitter/oauth_start
to start the
authentication process. Then one will be redirected to
twitter(http://twitter.com) to authorize the application and at the end
of the process the tokens will be sent to the TOKEN
port.
The authentication will always start at http://<the_host_ip_here>:8080/<namespace>/oauth_start
,
where <namespace>
is given in the namespace
option.