WebServer
This document describes the WebServer object in the JavaScript environment for app services.
Table of contents
url
A string containing the absolute base URL that can be used to access the web server.
The app service learns the URL from the incoming WebSocket connection from the app object on the PBX. So it only contains a valid URL, if the "Websocket" checkmark is set on the app object and the connection is up.
Otherwise url will point to localhost. Use onurlchanged to get notified when the actual URL is available after the app service is started.
onurlchanged
Registers a callback function that is invoked when the base URL of the web server has changed.
Parameters
function callback(string newUrl) | Called whenever WebServer.url has changed. |
Return value
WebServer | A reference to the object itself. Useful for method chaining. |
var baseUrl = WebServer.url;
log("url: " + baseUrl);
WebServer.onurlchanged(function(newUrl) {
baseUrl = newUrl;
log("url: " + baseUrl);
});
onrequest
Registers a relative URI on the web server and a callback function that is invoked on incoming requests on that URI.
Parameters
string relativeUri | A URL relative to WebServer.url. Do not prepend "/", "./". |
function requestCallback(WebServerRequest request) | The callback will be invoked on incoming HTTP requests to the given URI. If the callback is called, the application has to handle or cancel the request. |
function authenticationCallback(WebServerAuthentication auth) | Optional. If the callback is set, the webserver will do HTTP authentication for the registered path. The callback will be invoked on incoming HTTP requests to ask to app service for the password for the given user. |
Return value
WebServer | A reference to the object itself. Useful for method chaining. |
WebServer.onrequest("info.json", function(req) {
// reject request for this example
req.cancel();
});
onwebsocket
Registers a relative URI on the web server and a callback function that is invoked on incoming WebSocket connections on that URI.
Parameters
string relativeUri | A URL relative to WebServer.url. Do not prepend "/", "./". |
function websocketCallback(WebServerWebsocket websocket) | The callback will be invoked on incoming HTTP requests to the given URI. If the callback is called, the application has to handle or cancel the request. |
Return value
WebServer | A reference to the object itself. Useful for method chaining. |
WebServer.onwebsocket("websocketpath", function(websocket) {
websocket
.onmessage(function(ws, msg, isBinary) {
if (!isBinary) {
var obj = JSON.parse(msg);
if (obj.mt == "SomeMessage") {
websocket.send(JSON.stringify({ mt: "SomeMessageResult" }));
}
else if (obj.mt == "Bye") {
websocket.send(JSON.stringify({ mt: "Bye" }));
websocket. close();
}
}
})
.onclose(function() {
log("connection closed");
websocket = null;
})
.onerror(function() {
log("connection error");
websocket = null;
});
});
The WebServerRequest object passed to the application with the onrequest callback and can be used to handle incoming HTTP requests.
method
A string containing the HTTP method that was used for the request. Supported values: .
WebServer.onrequest("info.json", function(req) {
if (req.method == "GET") {
// handle GET
}
else if (req.method == "PUT") {
// handle PUT
}
else if (req.method == "POST") {
// handle POST
}
else if (req.method == "DELETE") {
// handle DELETE
}
else {
// should never happen
req.cancel();
}
});
relativeUri
A string containing the requested resource relative to the base URL given with the onrequest function.
WebServer.onrequest("weather", function(req) {
if (req.method == "GET") {
if (req.relativeUri == "/temperature") {
// ...
}
else if (req.relativeUri == "/humidity") {
// ...
}
else if (req.relativeUri == "/wind") {
// ...
}
else {
req.cancel();
}
}
else {
req.cancel();
}
});
cancel
Cancels the request. The client will get back an HTTP error.
The application will get no more callbacks from the object, especially there will be no oncomplete callback.
Parameters
uint responseCode | The HTTP status code to send with the response for the canceled request. Supported values are 404, 400, 451, 411, 402, 500. If no value is given status code 404 is used. |
Return value
WebServer.onrequest("info.json", function(req) {
// reject request with 500 Internal Server Error
req.cancel(500);
});
header
Returns the value of a given header field in the request.
Parameters
string field | The name of the header field. |
Return value
string | The value of the specified header field. |
WebServer.onrequest("info.json", function(req) {
if (req.header("X-Token") == "c29tZXRva2Vu") {
// handle request
}
else {
req.cancel();
}
});
onrecv
Sets a callback function for receiving request data. The data is received asynchronously using flow control. So only a specified number of bytes is received at a time. After invoking the onrecv callback, the library waits for the application to process the data. To receive the next chunk of data the application must call recv.
Optional. If no callback is set, the library will silently discard the request data.
Parameters
function callback(WebServerRequest request, Uint8Array data) | A callback that will be called when request data is received. If the request is finished it will be called with data set to null. |
int bufferSize | Optional. The maximum number of bytes that shall be received per callback. Defaults to 16384, if not specified. |
Return value
var requestData = "";
req.onrecv(function(req, data) {
if (data) {
requestData += new TextDecoder("utf-8").decode(data);
req.recv();
}
}, 1024);
recv
Tells the library to receive the next chunk of data.
Must be called after receiving the onrecv callback, unless data was null.
Return value
req.onrecv(function(req, data) {
if (data) {
// process data, then receive next chunk
req.recv();
}
});
onsend
Sets a callback function for sending response data. The data is sent asynchronously using flow control. So the library invokes the callback to notify the application that is ready to send data. Then it waits for the application to call send.
Optional. If no callback is set, the library will send a response with an empty body.
Parameters
function callback(WebServerRequest request) | A callback that will be called when the library is ready to send data. |
Return value
req.onsend(function(req) {
req.send(new TextEncoder("utf-8").encode("somedata"), true);
});
send
Tells the library to send the next chunk of data.
Must be called after receiving the onsend callback.
Parameters
Uint8Array data | The data to be sent. The total size of the array must not exceed 65535. |
bool last | false if there is more data to be sent and the application wants to receive another onsend callback. true for the last chunk of data. |
Return value
req.onsend(function(req) {
req.send(new TextEncoder("utf-8").encode("somedata"), true);
});
oncomplete
Sets a callback function that is invoked when the request / response is finished.
Optional.
Parameters
function callback(WebServerRequest request, bool success) | A callback that will be called when the request is complete or was aborted. |
Return value
req.oncomplete(function(req, success) {
log("WebServerRequest " + (success ? "succeeded" : "failed"));
});
sendResponse
Tells the library that the application has successfully processed the request and sets the HTTP status code that shall be sent with the response.
Before calling this function the application has to set all parameters and callbacks that are needed to create the response,
like onsend, oncomplete, responseHeader,
responseContentType,
or responseFileName.
Parameters
uint code | Optional. The HTTP response code to be sent to the client. Defaulting to 200, if not specified. Supported values are 100-999. |
string text | Optional. The HTTP response text to be sent to the client. Defaulting to the standard value for the given code. |
Return value
req.sendResponse(200);
req.sendResponse(418, "I'm a teapot");
responseHeader
Sets a custom header field that shall be sent with the HTTP response.
Parameters
string field | The name of the header field. |
string value | The value of the header field. |
Return value
req.responseHeader("X-Token","c29tZXRva2Vu");
responseContentType
Sets the content type for the data transmitted with the response.
Parameters
string contentType |
A file name extension that will be converted to an Internet Media Type value internally by the webserver. Supported values are:
- "html"
- "htm"
- "css"
- "xml"
- "xsl"
- "js"
- "json"
- "ico"
- "bin"
- "jar"
- "png"
- "gif"
- "bmp"
- "pdf"
- "wav"
- "ogg"
- "mp3"
- "txt"
- "soap"
- "svg"
- "ttf"
- "eot"
- "woff"
- "woff2"
- "g711a"
- "g711u"
- "g722"
- "g729"
- "jpeg"
- "mp4"
- "webm"
- "pem"
- "mobileconfig"
- "appcache"
- "opus-nb"
- "opus-wb"
|
Return value
req.responseContentType("json");
responseFileName
The application can set a file name for the response data. This will cause the client to handle the HTTP response as a download. Should always be used together with responseContentType
Parameters
string filename | The filename for the download. |
Return value
req.responseContentType("pdf").responseFileName("invoice.pdf");
The WebServerAuthentication object represents a HTTP authentication happening on a path that was registered using the onrequest function.
It contains the relative path and the user name of the corresponding request. The application MUST call password or reject
so the web server can complete the request. Both functions can be called directly inside the authenticationCallback from the webserver or asynchronously after leaving the callback.
host
A string containing the host name used by the HTTP client for the authentication request.
relativeUri
A string containing the requested resource relative to the base URL given with the onrequest function.
user
The username that was used by the HTTP client for authentication.
password
Sets the password that shall be used for the HTTP authentication request.
Calling the function closes the object.
Parameters
string password | The password that shall be used for the HTTP authentication request. |
WebServer.onrequest("info.json", function(req) {
// ...
}, function(auth) {
if (auth.user == admin) auth.password("pwd");
else auth.reject();
});
reject
Rejects the HTTP authentication request.
Calling the function closes the object.
WebServer.onrequest("info.json", function(req) {
// ...
}, function(auth) {
if (auth.user == admin) auth.password("pwd");
else auth.reject();
});
The WebServerWebsocket object is passed to the application with the onmessage callback and can be used to handle incoming WebSocket connections.
host
The host name that came in the header fields of the WebSocket connection.
relativeUri
A string containing the requested ressource relative to the base URL given with the onmessage function.
WebServer.onwebsocket("websocketpath", function(websocket) {
if (websocket.relativeUri == "/updates") {
// ...
}
else {
websocket.close();
}
});
close
Closes the WebSocket connection. After calling the function the object is gone and can no longer be used.
websocket.close();
send
Sends a websocket message.
Parameters
string/Uint8Array message | The message to be sent. If a string is given, a WebSocket text message will be sent. If a Uint8Array is given, a WebSocket binary message will be sent. |
Return value
websocket.send(JSON.stringify({ mt: "SomeMessage" }));
websocket.send(new Uint8Array([0x01, 0x02, 0x03, 0xff]));
onmessage
Sets a callback function that is invoked when a WebSocket message is received.
Optional.
Parameters
function callback(WebServerWebsocket websocket, string/Uint8Array message, bool isBinary) | A callback that will be called when an incoming message is received. The message is a string for isBinary==false and a Uint8Array for isBinary==true . |
Return value
websocket.onmessage(function(ws, msg, isBinary) {
if(isBinary) {
// ignore
}
else {
var obj = JSON.parse(msg);
if (obj.mt == "SomeMessage") {
websocket.send(JSON.stringify({ mt: "SomeMessageResult" }));
}
}
});
onclose
Sets a callback function that is invoked when the WebSocket connection is closed.
Optional.
Parameters
function callback(WebServerWebsocket websocket) | A callback that will be called when the connection is closed. After the callback the object is gone and can no longer be used. |
Return value
websocket.onclose(function() {
log("connection closed");
});
onerror
Sets a callback function that is invoked when an error on the WebSocket connection occurred.
Optional.
Parameters
function callback(WebServerWebsocket websocket) | A callback that will be called when the connection is closed due to an error. After the callback the object is gone and can no longer be used. |
Return value
websocket.onerror(function() {
log("connection error");
});
setFlowControl
Enables flow control for the WebSocket connection. That means that after receiving a message with the onmessage callback, the WebServerWebsocket
waits for the application to call messageComplete before receiving more messages.
Optional.
Parameters
bool enabled | True if flow control shall be used. |
Return value
websocket
.setFlowControl(true)
.onmessage(function(conn, msg) {
var obj = JSON.parse(msg);
if (obj.mt == "SomeMessage") {
websocket.send(JSON.stringify({ mt: "SomeMessageResult" }));
}
conn.messageComplete();
});
messageComplete
Tells the library to receive the next WebSocket message.
See setFlowControl for details.
Return value
websocket
.setFlowControl(true)
.onmessage(function(conn, msg) {
var obj = JSON.parse(msg);
if (obj.mt == "SomeMessage") {
websocket.send(JSON.stringify({ mt: "SomeMessageResult" }));
}
conn.messageComplete();
});
In this example we see how a simple REST API can be implemented. The REST API can read, store and delete an UTF-8 string value.
// the variable containing the string value
var value = null;
WebServer.onrequest("value", function(req) {
if (req.method == "GET") {
if (value) {
// value exists, send it back as text/plain
req.responseContentType("txt")
.sendResponse()
.onsend(function(req) {
req.send(new TextEncoder("utf-8").encode(value), true);
});
}
else {
// value does not exist, send 404 Not Found
req.cancel();
}
}
else if (req.method == "PUT") {
// overwrite existing value with newValue
var newValue = "";
req.onrecv(function(req, data) {
if (data) {
newValue += (new TextDecoder("utf-8").decode(data));
req.recv();
}
else {
value = newValue;
req.sendResponse();
}
});
}
else if (req.method == "DELETE") {
// delete value
value = null;
req.sendResponse();
}
else {
req.cancel();
}
});