Chapter 7—Web and Email Communications

You can build “low-level” Web- and Email-based communications into your Omnis applications using a number of different techniques or commands: this includes support for HTTP, SMTP, POP3, IMAP, and FTP communications and protocols; with the addition in Studio 10 support for JavaScript (Node.js), CRYPTO, HASH, and OAUTH2. The technique you choose to implement such support will depend on the breadth of support you require and the version of Omnis Studio you are using. The following techniques are available:

Supported protocol Omnis Studio version Implementation
OW3 Worker Objects (OW3) HTTP, SMTP, POP3, IMAP, FTP & SFTP, JavaScript (Node.js), CRYPTO, HASH, OAUTH2* Studio 10
*Studio 10.2
Objvar.$method
OW3 Worker Objects (OW3) HTTP, SMTP, FTP (not secure), IMAP Studio 8.1 Objvar.$method
Web Worker Objects (OWEB) HTTP, SMTP Studio 6.1.2 Objvar.$method
External Commands
(Note these are obsolete in Studio 10 & are no longer available)
HTTP, FTP, SMTP, POP3, and IMAP Studio 1.x (previously called Web Enabler in Omnis 7) External Commands group

We recommend you use the OW3 Worker Objects (OW3) for all new development, since the older Web Worker Objects are no longer supported.

An example library for each Web or Email protocol is available in the Samples group under the Hub to demonstrate the use of the OW3 Worker Objects; look for HTTP, SMTP, FTP and IMAP in the list (these were added in Studio 8.1.1).

OW3 Worker Objects

Using the OW3 Worker Objects you can execute a long-running task on a background thread, such as running a large mailshot, that reports back to the main thread when the task is complete. Indeed, the OW3 workers allow you to execute multiple tasks simultaneously allowing you to increase the efficiency and workload of your app. There is an example library under the ‘Samples’ section in the Hub (available when you start Omnis Studio) for each type of OW3 Worker Object.

The OW3 worker objects use the open source CURL library, and native secure connection implementations for Windows and macOS, so they should have fewer deployment issues than the implementations available in previous versions.

The web and email commands in OW3 are accessed via a new set of worker objects available under the OW3 Worker Objects group in the Object Selection dialog in the Method Editor (not the Web Worker Objects group which contains the OWEB worker objects). To use the web and email commands, you need to create an Object variable and set its subtype to one of the OW3 worker objects, either the HTTPClientWorker, SMTPClientWorker, or FTPClientWorker object under the OW3 Worker Objects group. Having created the variable you can call the web or email commands (methods) using OBJECTVAR.$methodname.

The new OW3 worker objects use the same programming model as the SQL DAM workers, and the old OWEB workers, available in previous versions. All OW3 worker objects share the same base functionality, plus they have additional functions specific to their respective web or email protocol.

Base Worker Properties

OW3 worker objects all have these properties:

Property Description
$state A kWorkerState... constant that indicates the current state of the worker object.
$errorcode Error code associated with the last action (zero means no error).
$errortext Error text associated with the last action (empty means no error).
$threadcount The number of active background threads for all instances of this type of worker object. In this case, type means the type of the subclass of the common base class e.g. HTTP.
$timeout The timeout (in seconds) for requests. Zero means requests do not time out. The desired value must be set before calling $run or $start. Defaults to 10.
$protocollog If non-zero, the worker adds a log of protocol activity as a column named log to its wResults row. The desired value must be set before calling $run or $start. Defaults to kOW3logNone. Otherwise, a sum of kOW3log... constants; see below
$callprogress If true, and the worker is invoked to execute asynchronously using $start, the worker periodically generates a notification to $progress as it executes. Must be set before calling $start.
The $progress method is described in the Methods section below.
$curloptions Use this property to set internal CURL options not otherwise exposed by the worker. A two-column list, where column 1 is a number (the CURL easy option number) and column 2 is a string. The internal option must use either an integer or string value.
Normally, you would not use this property, but if you do use it, you will need to consult the libcurl header files and documentation to obtain easy option numbers and values. You should use this option with care, as there is a chance you could cause Omnis to crash by passing an incorrect option value.
$alwaysfinish Allows asynchronous requests to continue to completion after the instance containing the OW3 object destructs; see below

Request Completion

The $alwaysfinish property allows asynchronous requests to continue to completion after the instance containing the OW3 object destructs; the property applies to the HTTP, IMAP, SMTP, POP3 and FTP workers.

When the instance containing an OW3 worker closes, and the OW3 worker is executing via a call to $start(), the worker thread continues executing until completion in the background: in this case, no notifications will be generated, as there is not a suitable instance to receive them.

Note that even if $alwaysfinish is true, if you shut down Omnis before the request has completed, OW3 will cancel the request so that shutdown works correctly.

Base Worker Constants

Protocol Logging

OW3 worker objects can all use these constants to control protocol logging. Sum the constants to select the desired logging.

Constant Description
kOW3logNone No protocol logging occurs. Obviously, this value needs to be used on its own.
kOW3logBasic Basic protocol information such as headers is logged.
kOW3logData Application data sent or received is logged up to a maximum of 16k for each direction. If the data is not consistent with UTF-8 encoding, it is logged as a binary dump format rather than character.
kOW3logSecureData Secure connection data is logged.
kOW3logHTML The content of the generated log is HTML rather than plain text. This can be written to a file and displayed using OBROWSER on Windows and macOS platforms.

Base Worker Methods

OW3 worker objects all have the methods described in this section. There are normal methods that you call, and callback methods that you override to receive a notification.

Normal methods

$run

Runs the worker on the main thread. Returns true if the worker executed successfully. The callback $completed will be called with the results of the request.

$start

Runs the worker on a background thread; can be called multiple times to run different threads simultaneously to perform different tasks at the same time. Returns true if the worker was successfully started. The callback $completed will be called with the results of the request, or alternatively $cancelled will be called if the request is cancelled.

$cancel

Cancels execution of worker on a background thread. Will not return until the request has been cancelled.

$getsecureoptions

$getsecureoptions([&bVerifyPeer,&bVerifyHost,&cCertFile,&cPrivKeyFile, &cPrivKeyPassword])

Gets the options that affect how secure connections are established.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
bVerifyPeer If true, the worker verifies the server certificate. The default is true, and this results in greater security.
bVerifyHost If true, the worker verifies that the server certificate is for the server it is known as. The default is true, and this results in greater security.
cCertFile For macOS, the pathname of the .p12 file containing the client certificate and private key, or its keychain name.
For other platforms, the pathname of the client certificate .pem file. Empty if a client certificate is not required.
cPrivKeyFile Ignored on macOS.
For other platforms, the pathname of the private key .pem file. Empty if a client certificate is not required
cPrivKeyPassword The private key password. Empty if a client certificate is not required

$setsecureoptions

$setsecureoptions([bVerifyPeer=kTrue,bVerifyHost=kTrue,cCertFile='',cPrivKeyFile='',cPrivKeyPassword=''])

Sets the options that affect how secure connections are established (call $setsecureoptions before calling $run or $start).

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
bVerifyPeer If true, the worker verifies the server certificate. The default is true, and this results in greater security.
bVerifyHost If true, the worker verifies that the server certificate is for the server it is known as. The default is true, and this results in greater security.
cCertFile For macOS, the pathname of the .p12 file containing the client certificate and private key, or its keychain name. For other platforms, the pathname of the client certificate .pem file. Empty if a client certificate is not required.
cPrivKeyFile Ignored on macOS. For other platforms, the pathname of the private key .pem file.Empty if a client certificate is not required
cPrivKeyPassword The private key password. Empty if a client certificate is not required

$splitmultipart

Allows you to split multipart content of a rest call, plus the MIME list returned by the OW3 methods that contain body part headers.

OW3.$splitmultipart(cContentType, xContent, &lMIMEList [,iDefCharSet=kUniTypeUTF8, &cErrorText])

Splits MIME-encoded multi-part xContent into lMIMEList.cContentType must include a boundary parameter.Returns true if successful

ContentType:The content type header (must contain a boundary parameter)

Content:The binary content to split

MIMEList:Receives the MIME list created by splitting the MIME content. See the documentation for the MailSplit command to see how a MIME list is structured;however note that the charset in the OW3 MIME list is a kUniType... constant

DefCharSet:The default character set used to convert character data when there is no charset specified for a MIME text body part. A kUniType... constant (not Character/Auto/Binary)

cErrorText:If supplied,receives text describing the error that caused $splitmultipart to return false

The MIME list (for this call and for the other OW3 calls that generate a MIME list) now contains an additional column named bodypartheaders. This is a row containing a column for each non-empty header present for the body part. In addition, it has a column named "name" which contains the content-disposition header name parameter. All header names are normalized in the same way as those passed to RESTful services, that is, lower-case with any - characters removed.

Callback methods

$completed

When a worker is started using either $run or $start, it reports its completion by calling $completed. Override the $completed method of the worker object to receive this notification. It is called with a single row variable parameter. The columns of the row are specific to each type of worker object, so we describe them in each specific worker object section.

$cancelled

To receive a notification that a request has been cancelled using $cancel, override the $cancelled method of the worker object. It is called with no parameters.

$progress

To receive progress notifications, override the $progress method of the worker object. OW3 worker objects generate notifications to $progress as and when some data has been transferred. Progress notifications will not be generated any more than once a second. Each notification receives a row variable parameter. The row has 4 columns.

Column Description
downloadTotalBytesExpected The total number of bytes expected to be downloaded from the server. This may always be zero, for example when the server is using chunked HTTP transfer encoding.
downloadBytesSoFar The number of bytes downloaded from the server so far.
uploadTotalBytesExpected The total number of bytes expected to be uploaded to the server.
uploadBytesSoFar The number of bytes uploaded so far.

For the OW3 FTP worker, $progress can be called for synchronous operations.

OAUTH2 Worker Object

Support for OAUTH2 authorization has been added to Studio 10.2 by adding a new OAUTH2 Worker Object in the OW3 Worker component package, while the HTTP, IMAP, POP3, and SMTP workers have been modified to support OAUTH2 authorization via the new dedicated worker object.

Why use OAUTH2

OAUTH 2.0 provides much improved security over and above simple username and password schemes. It is commonly used by many different service providers, such as Google mail, for which its use will become mandatory in 2020 (meaning less secure apps will no longer be supported). You can read about OAUTH 2.0 in RFC 6749 (https://tools.ietf.org/html/rfc6749)

An application wishing to use a service (using HTTP, IMAP, POP3, or SMTP) requires an Access Token of type “bearer”. The application needs to be registered with the service, so it can identify itself to the service, and the registration process provides the application with a Client Id and a Client Secret, that identify the application to the service.

As an initial step, the user of the service must authorize the application to use the service. To do this:

  1. The application opens a Web browser at the Authorization Endpoint (a URL) of the service.

  2. The authenticated user agrees that the application can access the service.

  3. The server hosting the Authorization URL redirects the browser to a URL supplied when opening the Web browser. This request contains an Authorization Code.

  4. The application makes a request to the Token Endpoint (a URL) sending it the Authorization Code.

  5. The server hosting the Token URL returns various pieces of information to the application, including: Access Token, Expiry of Access Token (recommended but not mandatory), Refresh Token (optional).

At this point, the application can use the Access Token to make requests to the service. Access Tokens are short-lived, typically being valid for about an hour. If the Token URL server also returned a Refresh Token, the application can use that after the Access Token has expired to obtain a new Access Token, without any further interaction with the user. Refresh Tokens typically have a long lifetime, but may be invalidated for various reasons, depending on the service implementation.

Obtaining Authorization

The OAUTH2 Worker allows you to obtain an Authorization Code, exchange it for tokens, and refresh tokens, using the $authorize() method on a background thread. The worker also contains methods to save and load the tokens and other related information to and from an encrypted binary block of data, which helps to protect key pieces of information such as the Refresh Token and Client Secret.

Note that you must always use an Object Reference to create the OAUTH2Worker object – this eliminates potential issues with the way Omnis uses the OAUTH2Worker as a property value.

The object reference to an OAUTH2Worker object containing the authorization information can be passed to the $oauth2 property in the HTTP, IMAP, POP3, and SMTP Workers to provide authorization.

OAUTH2 Properties

These properties are specific to OAUTH2.

Property Description
$accesstoken The access token to be used with HTTP, IMAP, POP3 and SMTP connections.
$accesstokenexpiry The expiry date and time of the access token (in UTC time). #NULL means no access expiry date and time is available.
$authorizeurl The URL of the OAUTH2 authorization endpoint.
$clientid The Client Id used in conjunction with the client secret to identify the application to the OAUTH2 authorization server.
$clientsecret The Client Secret used in conjunction with the Client Id to identify the application to the OAUTH2 authorization server.
$redirecturiserveraddress If not empty (the default value), this property overrides localhost in the redirect URI server address, replacing localhost with the value of this property. The default is localhost rather than 127.0.0.1 when generating redirect URIs when running in a thick client remote task
$refreshtoken The Refresh Token to be used to request a new access token after the access token has expired.
$scope A string identifying the type of access required. Used as part of the URL used to open the Web Browser at the authorization endpoint. For example, when using Google to access GMAIL, specify the scope as "https://mail.google.com/".
$tokenurl The URL of the OAUTH2 token endpoint.

HTTP and General Properties

In addition to the OAUTH2 properties, the OAUTH2Worker also has various HTTP and general OW3 properties, that for example affect how the HTTP requests it makes are executed: the OAUTH2Worker makes two different HTTP requests: a request to exchange an Authorization Code for an Access Token, and a request to obtain a new Access Token using the Refresh Token.

Property Description
$errorcode Error code associated with the last action (zero means no error).
$errortext Error text associated with the last action (empty means no error).
$followredirects If true, the HTTP request will follow a server redirect in order to complete the request. Defaults to false
$proxyserver The URI of the proxy server to use for all requests from this object e.g. http://www.myproxy.com:8080. Must be set before executing $run or $start. Defaults to empty (no proxy server).
$proxytunnel If true, and $proxyserver is not empty, requests are tunnelled through the HTTP proxy
$proxyauthtype The type of HTTP authentication to use when connecting to $proxyserver. A kOW3httpAuthType... constant (see below).
$proxyauthusername The username used to authenticate the user when connecting to $proxyserver using $proxyauthtype.
$proxyauthpassword The password used to authenticate the user when connecting to $proxyserver using $proxyauthtype.
$state A kWorkerState... constant that indicates the current state of the worker object.
$threadcount The number of active background threads for all instances of this type of worker object.
$timeout The timeout (in seconds) for requests. Defaults to 60 with a minimum value of 10.
$protocollog If non-zero, the worker adds a log of protocol activity as a column named log to its wResults row. The desired value must be set before calling $run or $start. Defaults to kOW3logNone. Otherwise, a sum of kOW3log... constants.

OAUTH2 Standard Methods

$authorize

$authorize([iAuthFlow=kOW3OAUTH2authFlowCodeWithPKCE])

Starts the OAUTH2 authorization flow iAuthFlow on a background thread. Returns true if the thread was successfully started. Properties of the object cannot be assigned while $authorize() is running.

$authorize() opens a Web Browser at the authorization URL, passing the URL various parameters in the query string, such as the Client Id using the value of the $clientid property.

How the Web Browser is opened depends on the context in which $authorize() is called.

When executed within the context of a thick client (non-remote) task, $authorize() uses the $webbrowser property to control which browser it opens (note that you cannot use $authorize() with a thick client task when running in the headless server). It should be noted that when running in the thick client, $authorize() always uses a web browser rather than an embedded obrowser control due to best practice considerations documented in RFC 8252: https://www.rfc-editor.org/rfc/rfc8252.txt

When executed within the context of a remote task, $authorize() will only work if the remote task is a JavaScript Client remote task. In this case, it uses the $showurl() mechanism of the JavaScript Client to open a browser window or tab. Note that in this case, you cannot execute both $authorize() and $showurl() in response to the same JavaScript client event.

When using the authorization flows that redirect the browser to a URI, $authorize() determines the redirect URI as follows.

For the thick client, it uses a loopback URI, to 127.0.0.1. Note that if the version of Omnis is not a server version, Omnis will still open a server port with limited support for OAUTH2 only, to allow the Authorization Code to be received via the redirect URI.

For the JavaScript client, $authorize() uses the RESTful URI determined from the Omnis server configuration. Note that this means that if you are using a Web Server to handle requests for your Omnis server, you need to set up the Omnis Web Server plugin for both the JavaScript client and RESTful requests.

$authorize() takes a single parameter, iAuthFlow, which can have one of the following constant values (kOW3OAUTH2authFlowCodeWithPKCE is the default):

Constant Description
kOW3OAUTH2authFlowCode The normal OAUTH2 authorization flow, where the authorization code will be received by redirecting the browser to a URI served by Omnis.
kOW3OAUTH2authFlow
CodeWithPKCE
Identical to kOW3OAUTH2authFlowCode, except that the worker uses PKCE to further secure its requests for an authorization code; the default iAuthFlow (see https://tools.ietf.org/html/rfc7636).
kOW3OAUTH2authFlow
ManualCode
Like kOW3OAUTH2authFlowCode, except that the redirect URI is urn:ietf:wg:oauth:2.0:oob. This means that instead of the authorization code arriving at Omnis via the redirect URI, the user must copy the authorization code to the clipboard from the browser window, and paste it into Omnis or the JavaScript client; after pasting, the Omnis application must call the method $setauthcode() (described below).
kOW3OAUTH2authFlow
ManualCodeWithPKCE
Like kOW3OAUTH2authFlowManualCode, but also uses PKCE.

Note that you would normally use PKCE unless the service does not support it.

Manual code support, via the clipboard, is provided in case you do not want to open up a port for the redirect URI when running in the thick client; however, note that not all services support the redirect URI urn:ietf:wg:oauth:2.0:oob.

When $authorize() completes (which if successful means that is has opened the browser, received the Authorization Code, and exchanged it for an Access Token etc) it generates a call to the callback method $completed().

$setauthcode

$setauthcode(cAuthCode)

Returns Boolean true for success.

Only applicable to kOW3OAUTH2authFlowManualCode and kOW3OAUTH2authFlowManualCodeWithPKCE, when the $authorize() thread is waiting for the Authorization Code. Called from the application to supply the pasted Authorization Code using the cAuthCode parameter.

$save

$save(&xOAUTH2[,xKey])

Saves the properties ($clientid, $clientsecret, $authorizeurl, $tokenurl, $scope, $accesstoken, $refreshtoken and $accesstokenexpiry) to the encrypted binary buffer xOAUTH2.

xKey is a 256 bit AES encryption key. If you omit xKey, OW3 uses a hard-coded default key.

Returns Boolean true for success.

$save provides a convenient way to save all of the OAUTH2 parameters required for communicating with a service. In particular, it lets you safely store the Refresh Token, so you can minimise the number of occasions on which a user needs to authorize access using $authorize().

You can further protect your client secret, by including the encrypted buffer generated by $save in your release tree.

$load

$load(xOAUTH2[,xKey])

Loads the properties ($clientid, $clientsecret, $authorizeurl, $tokenurl, $scope, $accesstoken, $refreshtoken and $accesstokenexpiry) from the encrypted binary buffer xOAUTH2 previously generated using $save().

xKey is a 256 bit AES encryption key. If you omit xKey, OW3 uses a hard-coded default key. You must use the same key as that used when calling $save().

Returns Boolean true for success.

OAUTH2 Callback Methods

$tokensrefreshed

The OAUTH2Worker has one non-standard callback method, $tokensrefreshed. The OAUTH2Worker generates a call to this method after it has successfully refreshed the tokens while it is being used in conjunction with the HTTP/IMAP/POP3/SMTP worker.

$tokensrefreshed() is called with no parameters; at this point, the worker has been updated with the new Access Token, Access Token Expiry and Refresh Token. A typical implementation of $tokensrefreshed() would use $save() to save the current tokens etc and then write the encrypted buffer to disk. It should be noted that calling the server to refresh tokens can result in a different updated Refresh Token - this needs to be used to refresh tokens the next time a refresh is required.

HTTP and General Methods

The OAUTH2Worker supports the normal methods $cancel(), $getsecureoptions() and $setsecureoptions(). The latter two relate to how secure connections to the Token URL are established.

HTTP Callback Methods

The OAUTH2Worker generates calls to the standard callback methods $cancelled() and $completed(). These correspond to a call to $authorize() to start the authorization code flow. The completion row passed as a parameter to $completed() has columns as follows:

Column Description
errorCode An integer error code indicating if the request was successful. Zero means success. If successful, $accesstoken, $accesstokenexpiry and $refreshtoken have been updated using the content received from the server; if no Access Token Expiry was received, $accesstokenexpiry is #NULL; if no Refresh Token was received, $refreshtoken is empty.
errorInfo A text string providing information about the error if any.
scope The scope returned from the server when requesting the Access Token, if different to the requested scope.
log If you used $protocollog to generate a log, this column contains the log data, either as character data, or UTF-8 HTML. Otherwise, the log column is empty.

HTTP, IMAP, POP3, and SMTP Workers

Once you have used $authorize() to obtain an Access Token, you need to make the Access Token available to the worker with which OAUTH2 authorization is required. You do this by assigning a new $oauth2 property of the HTTP, IMAP, POP3, or SMTP worker:

  1. $oauth2
    Property that is an object reference to an OAUTH2Worker object containing the authorization information required to make requests to the server. Clear this property by assigning #NULL to it. $authorize() cannot run while the OAUTH2Worker is assigned to $oauth2

The supported workers use $oauth2 to obtain the Access Token for the request. To do this, it uses the following logic:

  1. If there is no Refresh Token ($refreshtoken is empty), it uses $accesstoken.

  2. If the $accesstokenexpiry is #NULL (there is no expiry date and time), it uses $accesstoken.

  3. If the expiry date time is more than 5 seconds away, it uses $accesstoken

  4. Finally, it uses $refreshtoken to refresh the token(s). If successful, it generates a call to $tokensrefreshed() in the OAUTH2Worker and it uses the new $accesstoken

You should note that there is a chance the request will fail when it is made near to the 5 second window before the Access Token expires. You should be prepared to handle this type of error in $completed, possibly retrying the request.

HTTP

After assigning $oauth2, the parameters iAuthType, cUserName, and cPassword passed to $init() are ignored in favour of using the Access Token stored in $oauth2.

IMAP, POP3, SMTP

After assigning $oauth2, the cPassword parameter passed to $init() is ignored in favour of using the Access Token stored in $oauth2. Note that cUserName is still required.

HTTP Worker

The HTTPClientWorker provides client HTTP support. For example, you can POST data to a server, execute a RESTful request, or download a file from a server.

The HTTP Worker supports the following externals:

  1. curl version 7.65.3

  2. libssh2 version 1.9.0

  3. mbedTLS version 2.16.2

Properties

The HTTPClientWorker has the following properties in addition to the base worker properties described earlier:

Property Description
$followredirects If true, the HTTP request will follow a server redirect in order to complete the request. The desired value must be set before calling $run or $start. Defaults to false
$proxyserver The URI of the proxy server to use for all requests from this object e.g. http://www.myproxy.com:8080. Must be set before executing $run or $start. Defaults to empty (no proxy server).
$proxytunnel If true, and $proxyserver is not empty, requests are tunnelled through the HTTP proxy
$proxyauthtype The type of HTTP authentication to use when connecting to $proxyserver. A kOW3httpAuthType... constant. kOW3httpAuthType constants are described in the Constants section below.
$proxyauthusername The user name used to authenticate the user when connecting to $proxyserver using $proxyauthtype.
$proxyauthpassword The password used to authenticate the user when connecting to $proxyserver using $proxyauthtype.
$responsepath If not empty, the worker writes response content to the file with this path rather then adding it to the wResults row. The file must not already exist. The desired value must be set before calling $run or $start. Defaults to empty
$oauth2 An object reference to an OAUTH2Worker object containing the authorization information required to make requests to the server: see OAUTH2 section

Constants

The HTTPClientWorker uses the following constants, specified in the iMethod parameter in the $init method, in addition to the base worker constants described earlier:

Constant Description
kOW3httpMethodDelete Sends a DELETE method
kOW3httpMethodGet Sends a GET method
kOW3httpMethodHead Sends a HEAD method
kOW3httpMethodOptions Sends a OPTIONS method
kOW3httpMethodPatch Sends a PATCH method
kOW3httpMethodPost Sends a POST method
kOW3httpMethodPut Sends a PUT method
kOW3httpMethodTrace Sends a TRACE method
kOW3httpAuthTypeNone Indicates that no HTTP authentication is required (in this case a user name and password do not need to be supplied)
kOW3httpAuthTypeBasic Indicates that basic HTTP authentication is required
kOW3httpAuthTypeDigest Indicates that digest HTTP authentication is required
kOW3httpMultiPartFormData Indicates that HTTP multipart/form-data content is to be sent (this is described below)

Methods

HTTPClientWorker has the methods described in this section in addition to the base worker methods described earlier.

Normal methods

$init

$init(cURI [,iMethod=kOW3httpMethodGet, lHeaders=#NULL, vContent='', iAuthType=kOW3httpAuthTypeNone, cUserName='',cPassword=''])

Called to prepare the object to execute a request, before calling $run or $start; the URI is the only required parameter.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cURI The URI of the resource, optionally including the URI scheme (http or https) e.g. http://www.myserver.com/myresource. If you omit the URI scheme e.g. www.myserver.com/myresource,the URI scheme defaults to http. You can also include query string parameters if desired e.g. http://www.myserver.com/myresource?param1=test&param2=test
iMethod A kOW3httpMethod... constant that identifies the HTTP method to perform
lHeaders A two-column list where each row is an HTTP header to add to the HTTP request Column 1 is the HTTP header name e.g. 'content-type' and column 2 is the HTTP header value e.g. ‘application/json'. If you do not supply the header “accept-encoding” the worker automatically decompresses content compressed using gzip or deflate; however, if you supply this header, the worker does not perform automatic decompression.
vContent kOW3httpMultiPartFormData or a binary, character or row variable containing content to send with the request. kOW3httpMultiPartFormData means send the content built using the $multipart… methods described below. The worker sends binary data as it is. The worker converts character data to UTF-8 and sends the UTF-8. A row must have a single column containing the path of the file containing the content to send. If you do not specify a content-type header in lHeaders, the worker will generate a suitable type if it recognises the file extension when using a row, or when using a character value it will use text/plain;charset=utf-8. Otherwise, it will use application/octet-stream. In addition, the worker will automatically add a content-length header, so there is no need to pass this in lHeaders.
iAuthType A kOW3httpAuthType... constant that specifies the type of authentication required for this request. If you omit this and the remaining parameters, authentication defaults to kOW3httpAuthTypeNone.
cUserName The user name to use with authentication types kOW3httpAuthTypeBasic and kOW3httpAuthTypeDigest.
cPassword The password to use with authentication types kOW3httpAuthTypeBasic and kOW3httpAuthTypeDigest

NOTE: If you call $init when a request is already running on a background thread, the object will cancel the running request, and wait for the request to abort before continuing with $init.

Example

The following code could be used to prepare an HTTPClientworker object using $init, and then $run can be used to execute the HTTP method. The method returns the content of the web page stored in iURI, e.g. ww.omnis.net.

# $execute method
Do method checkHttpObject ## sets up the HTTP object ref var
Do method setupLogging ## sets up logging based on user choice
If len(iTempContent)
    Do iHttp.$init(
iURI,iMethodList.iMethod,iHeaderList,iTempContent,iAuthList.iAuthType,iUser,iPasswordReturns lOk
Else
    If iSendContentMode=1
        Do iHttp.$init(
iURI,iMethodList.iMethod,iHeaderList,row(iContentPath),iAuthList.iAuthType,iUser,iPasswordReturns lOk
    Else If iSendContentMode=2
        Do iHttp.$buildmultipart(iContentPath)
        Do iHttp.$init(
iURI,iMethodList.iMethod,iHeaderList,kOW3httpMultiPartFormData,iAuthList.iAuthType,iUser,iPasswordReturns lOk
    Else If iSendContentMode=0
        Do iHttp.$init(
iURI,iMethodList.iMethod,iHeaderList,iContent,iAuthList.iAuthType,iUser,iPasswordReturns lOk
    End If
End If
If not(lOk)
    OK message {Error [iHttp.$errorcode]: [iHttp.$errortext]}
    Quit method kFalse
End If
If pRun
    Do iHttp.$run() Returns lOk
Else
    Do iHttp.$start() Returns lOk
    If lOk
        Calculate $cinst.$objs.ScrollBox.$objs.cancel.$enabled as kTrue
        Calculate $cinst.$objs.ScrollBox.$objs.execute.$enabled as kFalse
        Calculate $cinst.$objs.ScrollBox.$objs.executethencancel.$enabled as kFalse
    End If
End If
If not(lOk)
    OK message {Error [iHttp.$errorcode]: [iHttp.$errortext]}
    Quit method kFalse
End If
Quit method kTrue

$multipartclear

$multipartclear()

Frees any previously generated multipart/form-data content. Note that calling $run or $start with kOW3httpMultiPartFormData results in the multipart/form-data content being automatically freed after use.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

$multipartaddfield

$multipartaddfield(cName, cFieldData [,lPartHeaders])

Adds a field part to the multipart/form-data content stored in the worker object. To send this content specify kOW3httpMultiPartFormData as the vContent parameter to $init().

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cName The name of the multipart/form-data field part.
cFieldData The value of the multipart/form-data field.
lPartHeaders A two-column list where each row is a header to add to the part. Column 1 is the header name and column 2 is the header value.

$multipartaddfile

$multipartaddfile(cName, vFileData [,cFileName=‘', lPartHeaders])

Adds a file part to the multipart/form-data content stored in the worker object. A file part indicates to the server that a file is being uploaded. To send this content specify kOW3httpMultiPartFormData as the vContent parameter to $init().

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cName The name of the multipart/form-data file part.
vFileData A binary, character or row variable containing the file data for the part. The worker sends binary data as it is. The worker converts character data to UTF-8 and sends the UTF-8. A row must have a single column containing the path of the file containing the content to send. If you do not specify a content-type header in lPartHeaders, the worker will generate a suitable type if it recognises the file extension when using a row, or when using a character value it will use text/plain;charset=utf-8. Otherwise, it will use application/octet-stream.
cFileName The filename of the part. Must be specified if vFileData is binary or character. If vFileData is a row (identifying a file) then this overrides the default filename (the name of the file).
lPartHeaders A two-column list where each row is a header to add to the part. Column 1 is the header name and column 2 is the header value.

Callback methods

$completed

The standard $completed callback is passed a row variable parameter with the following columns:

Column Description
errorCode An integer error code indicating if the request was successful. Zero means success i.e. the HTTP request was issued and a response received - you also need to check the httpStatusCode to know if the HTTP request itself worked.
errorInfo A text string providing information about the error if any.
httpStatusCode A standard HTTP status code that indicates the result received from the HTTP server.
httpStatusText The HTTP status text received from the HTTP server.
responseHeaders A row containing the headers received in the response from the HTTP server.
The header values are stored in columns of the row.
The column name is the header name converted to lower case with any - characters removed, so for example the Content-Length header would have the column name contentlength.
If the client receives multiple headers with the same name, it combines them into a single header with a comma separated list of the received header values. This is consistent with the HTTP specification.
responseContent If you have not used $responsepath to write the received content directly to a file, this is a binary column containing the content received from the server.
log If you used $protocollog to generate a log, this column contains the log data, either as character data, or UTF-8 HTML. Otherwise, the log column is empty.

WebSocket Client Support

$init

To initialise the OW3 HTTP worker object so that it is ready to create a WebSocket client connection, call $init with parameters as follows:

Parameter Description
cURI The URI of the WebSocket server, which must include the URI scheme (ws or wss) e.g. wss://demos.kaazing.com/echo
You cannot omit the URI scheme, because the HTTP worker defaults to using http.
iMethod Must be kOW3httpMethodGet
lHeaders A two column list where each row is an HTTP header to add to the HTTP request.
The worker automatically adds these headers when connecting to a WebSocket server, so do not add these headers:
connection: upgrade upgrade: websocket
sec-websocket-version: 13
sec-websocket-key: <key value>
vContent Not used
iAuthType A kOW3httpAuthType... constant that specifies the type of authentication required for this request. If you omit this and the remaining parameters, authentication defaults to kOW3httpAuthTypeNone.
cUserName The user name to use with authentication types kOW3httpAuthTypeBasic and kOW3httpAuthTypeDigest.
cPassword The password to use with authentication types kOW3httpAuthTypeBasic and kOW3httpAuthTypeDigest

The standard OW3 properties $state, $errortext, $errorcode, $threadcount, $protocollog, $timeout, $callprogress and $curloptions all apply when connecting to a WebSocket server.

The standard OW3 methods $getsecureoptions and $setsecureoptions apply when connecting to a WebSocket server.

$run and $start

You cannot use $run to establish a WebSocket connection, since multiple threads are required to make it usable. So if you try to use $run, the worker returns kFalse and sets $errorcode and $errortext.

To establish a WebSocket connection, call $start. If $start succeeds, then the worker attempts to establish the connection to the WebSocket server in another thread.

If the connection cannot be established, the worker generates a notification to $completed, with a non-zero value in the errorCode member of the notification row parameter.

If the connection is established successfully (and is therefore open and ready for data transfer), the worker generates a notification to the new method $ws_onconnect. Override this method to receive this notification. $ws_onconnect receives a single row variable as its parameter. This row variable has a single column, responseHeaders, which is a row with a single column for each response header received from the server in the final HTTP protocol exchange resulting in the 101 (web socket protocol handshake) HTTP status code.

As soon as you have received the $ws_onconnect notification, the WebSocket is ready to send and receive data.

$wssend

After you have received the $ws_onconnect notification, you can send data using the method $wssend:

$wssend(vMessage)

Sends the supplied message on a connected web socket. Returns true if successful, which means the message has been queued for sending.

If vMessage is a character value, the worker converts it to UTF-8 before sending it as a text message; otherwise the value is treated as binary and sent as a binary message.

Receiving Data

Each message received from the WebSocket server generates a $ws_onmessage notification. Override this method to receive these notifications. $ws_onmessage receives a single row variable parameter, with 2 columns (named data and utf8). Column data is the binary data and column utf8 is boolean true if the data is UTF-8.

$wsclose

The client can close the WebSocket connection by calling the method $wsclose:

$wsclose([bDiscardUnsentMessages=kFalse,iStatusCode=1000,cReason=‘'])

Closes the connection to the web socket server. $completed() will be notified when the connection has closed. The row passed to $completed has closeStatus and closeReason columns that receive the values sent in the close frame to the server.

Pass bDiscardUnsentMessages as kTrue, to discard any completely unsent queued messages before sending the close frame to the server.

iStatusCode is an integer status code that indicates the reason for closure (one of the values in section 7.4 of RFC6455).

cReason is some optional text that indicates the reason for closure.

Server close

The server can send a close frame to the client, telling the client it is closing the connection. The client responds with a close frame, before the connection closes. Again, $completed is notified to tell the object that the connection has closed.

The row passed to $completed has closeStatus and closeReason columns that receive the values sent in the close frame from the server.

$cancel

You can use $cancel to terminate the connection in a non-graceful manner.

Ping-pong

If the client receives a Ping from the server, it automatically responds with a Pong. You can also set up the client to automatically Ping the server, and generate an error (closing the connection) if a Pong is not received. To do this, use these two properties:

$wspinginterval: If non-zero, and the connection is to a web socket server, the HTTP worker sends a Ping frame to the server every $wspinginterval seconds of inactivity, and closes the connection if a Pong frame is not received after $wspongtimeout seconds. Defaults to zero.

$wspongtimeout: The number of seconds (1-60, default 5) the client waits to receive a Pong frame after sending a Ping frame as a result of the $wspinginterval timeout expiring.

Timeout

The object restarts the $timeout timer each time it sends or receives some data.

SMTP Worker

The SMTPClientWorker provides client SMTP support, allowing you to use the worker to send emails, including bulk emails via a mailshot. The following sections describe the SMTP worker properties, constants and methods.

Properties

The SMTPClientWorker has the following properties in addition to the base worker properties described earlier:

Property Description
$requiresecureconnection If true, and the URI is not a secure URI, the connection starts as a non-secure connection which must be upgraded to a secure connection (using the STARTTLS command). If it cannot be upgraded then the request fails. Defaults to false
$keepconnectionopen If true, the worker can leave the connection to the server open when it completes its request. Defaults to false. Note that even when this property is set to true, a protocol error may cause the connection to close. Use true if you are likely to send more emails using the same server fairly soon.
$callmailshotprogress If true, and the worker is sending a mailshot asynchronously via $start, the worker generates notifications to $mailshotprogress as it executes. $callmailshotprogress must be set before calling $start. Defaults to false
$oauth2 An object reference to an OAUTH2Worker object containing the authorization information required to make requests to the server: see OAUTH2 section

Constants

The SMTPClientWorker uses the following constants in addition to the base worker constants described earlier:

Constant Description
kOW3msgPriorityLowest The message has the lowest priority
kOW3msgPriorityLow The message has low priority
kOW3msgPriorityNormal The message has normal priority
kOW3msgPriorityHigh The message has high priority
kOW3msgPriorityHighest The message has the highest priority

Methods

SMTPClientWorker has the methods described in this section in addition to the base worker methods described earlier.

Normal methods

$init

$init(cURI, cUser, cPassword, vFrom, lTo, lCc, lBcc, cSubject, cPriority, lHeaders, vContent [,bMailshot=kFalse])

Called to prepare the object to execute a request, before calling $run or $start.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cURI The URI of the server, optionally including the URI scheme (smtp or smtps), e.g. smtp://test.com. If you omit the URI scheme e.g. smtp.myserver.com the URI scheme defaults to smtp. If the server uses a non-standard port, you can include it in the URI like this example smtp://smtp.myserver.com:2525
cUser The user name to be used to log on to the SMTP server.
cPassword The password to be used to log on to the SMTP server
vFrom The email address of the message sender. Either a character value e.g. user@test.com or a row with 2 columns where column 1 is the email address e.g. user@test.com and column 2 is descriptive text for the sender, typically their name
lTo A one or two column list where each row identifies a primary recipient of the message. Column 1 contains the email address e.g. user@test.com and column 2 if present contains descriptive text for the recipient, typically their name
lCc Empty if there are no CC recipients, or a one or two column list where each row identifies a carbon copied recipient of the message. Column 1 contains the email address e.g. user@test.com and column 2 if present contains descriptive text for the recipient, typically their name
lBcc Empty if there are no BCC recipients, or a single column list where each row contains the email address of a blind carbon copied recipient of the message e.g. user@test.com. Unlike lTo and lCc, lBcc does not allow more than 1 column, as blind carbon copied recipients are not added to the message header and therefore the descriptive text is not required.
cSubject The subject of the message
iPriority A kOW3msgPriority... constant that specifies the priority of the message
lHeaders A two-column list where each row is an additional SMTP header to send with the message. Column 1 is the header name e.g. 'X-OriginalArrivalTime' and column 2 is the header value e.g. ’23:02'
vContent Message content. Either binary raw content (which the worker sends exactly as it is), or a list to be sent as MIME. See the documentation for the MailSplit command to see how a MIME list is structured; however, note that the charset in the worker MIME list is a kUniType... constant rather than a character string.
bMailshot Allows a mailshot to be sent (default is kFalse). If true, the worker sends a separate copy of the message to each recipient in the lTo list (so that each recipient cannot see the addresses of the others); only lTo is used, and lCc and lBcc must be empty.

NOTE: If you call $init when a request is already running on a background thread, the object will cancel the running request, and wait for the request to abort before continuing with $init.

Example

The $init method can be used to prepare the SMTPClientWorker object to be executed using the $run or $start method. In this case, iSmtp is an object reference variable with its subtype set to an object class, which has its $superclass set to the SMTPClientWorker in the OW3 worker objects group.

# $start method
Do method setupLogging ## set up logging
Calculate iSmtp.$timeout as iTimeout ## set properties via window fields
Calculate iSmtp.$callprogress as iCallProgress
Calculate iSmtp.$keepconnectionopen as iKeepConnectionOpen
Calculate iSmtp.$requiresecureconnection as iRequireSecureConnection
Calculate iSmtp.$callmailshotprogress as iCallMailshotProgress
Do method $splitaddressentry (iFrom,lFromAddress,lFromDescriptionReturns lOk
If not(lOk)
    OK message {From "[iFrom]" is invalid}
    Quit method kFalse
End If
Calculate lOk as $cinst.$makerecipientlist(lToList,iTo)
If not(lOk)
    OK message {From "[iTo]" is invalid}
    Quit method kFalse
End If
Calculate lOk as $cinst.$makerecipientlist(lCcList,iCc)
If not(lOk)
    OK message {From "[iCc]" is invalid}
    Quit method kFalse
End If
Calculate lOk as $cinst.$makerecipientlist(lBccList,iBcc)
If not(lOk)
    OK message {From "[iBcc]" is invalid}
    Quit method kFalse
End If
If iCallMailshotProgress
    Set reference lMailshotProgressItem to $clib.$windows.wMailshotProgress.$openmodal("*",kWindowCenterRelative,$cinst,lToList.$linecount,$cinst)
End If
Do iSmtp.$setMailshotProgressInst(lMailshotProgressItem)
If iNoMIME
    If len(lFromDescription)
        Do iSmtp.$init(
iServerURI,iUser,iPassword,row(lFromAddress,lFromDescription),lToList,lCcList,lBccList,iSubject,iPriorityList.iPriorityValue,iExtraHeaderList,lBinContent,iMailshotReturns lOk
    Else
        Do iSmtp.$init(
iServerURI,iUser,iPassword,lFromAddress,lToList,lCcList,lBccList,iSubject,iPriorityList.iPriorityValue,iExtraHeaderList,lBinContent,iMailshotReturns lOk
    End If
Else
    If len(lFromDescription)
        Do iSmtp.$init(
iServerURI,iUser,iPassword,row(lFromAddress,lFromDescription),lToList,lCcList,lBccList,iSubject,iPriorityList.iPriorityValue,iExtraHeaderList,lMIMElist,iMailshotReturns lOk
    Else
        Do iSmtp.$init(iServerURI,iUser,iPassword,lFromAddress,lToList,lCcList,lBccList,iSubject,iPriorityList.iPriorityValue,iExtraHeaderList,lMIMElist,iMailshotReturns lOk
    End If
End If
If not(lOk)
    OK message {$init error [iSmtp.$errorcode]: [iSmtp.$errortext]}
    Quit method kFalse
End If
If pRun
    Do iSmtp.$run() Returns lOk
Else
    Do iSmtp.$start() Returns lOk
End If
If not(lOk)
    OK message {$run error [iSmtp.$errorcode]: [iSmtp.$errortext]}
    Quit method kFalse
Else If not(pRun)
    Calculate $cinst.$objs.scrollbox.$objs.cancel.$enabled as kTrue
    Calculate $cinst.$objs.scrollbox.$objs.start.$enabled as kFalse
    Calculate $cinst.$objs.scrollbox.$objs.startthencancel.$enabled as kFalse
End If
Quit method kTrue

Callback methods

$completed

The standard $completed callback is passed a row variable parameter with the following columns:

Column Description
errorCode An integer error code indicating if the request was successful. Zero means success i.e. the message was successfully sent.
errorInfo A text string providing information about the error if any.
log If you used $protocollog to generate a log, this column contains the log data, either as character data, or UTF-8 HTML. Otherwise, the log column is empty.

$mailshotprogress

If the request is a mailshot, and $callmailshotprogress is kTrue, the worker generates a notification to $mailshotprogress each time it sends (or fails to send) the message to a recipient. $mailshotprogress is passed a row variable parameter with the following columns:

Column Description
address The email address of the recipient.
sent Boolean, true if the message was successfully sent to this recipient

FTP Worker

The FTPClientWorker provides client FTP support, allowing you to use the worker to transfer files. The following sections describe the FTP worker properties, constants and methods.

Properties

The FTPClientWorker has the following properties in addition to the base worker properties described earlier:

Property Description
$requiresecureconnection If true, and the URI is not a secure URI, the connection starts as a non-secure connection which must be upgraded to a secure connection (using the STARTTLS command). If it cannot be upgraded then the request fails. Defaults to false
$keepconnectionopen If true, the worker can leave the connection to the server open when it completes its request. Defaults to false. Note that even when this property is set to true, a protocol error may cause the connection to close. Use true if you are likely to use the same server quite soon.
$servercharset The character set used by the server to encode file names in commands and file lists. Default kUniTypeAuto (meaning UTF-8 if the server supports it or kUniTypeNativeCharacters if not). Otherwise a kUniType... constant for 8-bit character sets.
$responsepath If not empty, the worker writes response content to the file with this path rather then adding it to the wResults row. The file must not already exist. The desired value must be set before calling $run or $start. Defaults to empty

Constants

The FTPClientWorker uses the following constants in addition to the base worker constants described earlier. These constants are all actions specified in the iAction parameter used with the $init method to indicate the action to perform, so this section should be read in conjunction with the section describing the $init method:

Constant Description
kOW3ftpActionPutFile Upload file data to file cServerPath on FTP server.
vParam is file data (binary, character or row).
Worker converts character to server character set.
Row must have one column (path of file containing data to upload).
Note that all file transfers use FTP binary mode.
kOW3ftpActionPutFileMulti Upload multiple files to the FTP server. vParam is a 2 column list (col1: full local pathname, col2: full server pathname). cServerPath must be empty; see below
kOW3ftpActionAppendFile Identical to kOW3ftpActionPutFile except the action appends the file data to an existing file on the FTP server, or creates a new file containing the supplied data if the file does not exist on the FTP server.
kOW3ftpActionGetFile Download file cServerPath from FTP server. Downloaded file data is either written to $responsepath (if not empty) or returned in the wResults row. vParam is not required.
Note that all file transfers use FTP binary mode.
kOW3ftpActionGetFileMulti Download multiple files from the FTP server. vParam is a 2 column list (col1: full local pathname, col2: full server pathname). cServerPath must be empty; see below
kOW3ftpActionDelete Delete directory or file cServerPath from the FTP server. vParam is Boolean true if cServerPath is a directory, false if it is a file.
kOW3ftpActionCreateDirectory Create directory cServerPath on the FTP server. vParam is not required.
kOW3ftpActionListDirectory List the contents of directory cServerPath on the FTP server returned to wResults.resultList. vParam is Boolean true to list file names only (single column list), or false to get a detailed list with 8 columns: see below.
kOW3ftpActionSetPermissions Set the permissions of file or directory cServerPath on the FTP server. vParam is a character string specifying the new permissions of the file or directory.
Note that not all servers support the SITE CHMOD command used by this action.
kOW3ftpActionExecute If cServerPath is not empty, CWD cServerPath.
Then execute FTP control connection commands in vParam.
vParam is either a character string or a single column list of commands. E.g. to rename a file, you could use:
RNFR oldname.txt
RNTO newname.txt
as two lines in the command list.
wResults.resultList has a row for each command response.

Directory list for kOW3ftpActionListDirectory

FTP does not have a standard syntax for the data returned by the LIST command, so the FTP worker attempts to parse the results of the ListDirectory action, based on some typical syntaxes supported by many servers. The detailed list has 8 columns, as follows:

  1. The full text returned by the server. This maintains compatibility with previous versions of the OW3 FTP worker, and may contain additional information not extracted by the parser.

  2. The file name.

  3. Boolean. True if the entry is probably a directory.

  4. Boolean. True if the entry is probably a file.

  5. File size in bytes.

  6. Modification date of the file.

  7. Boolean. True if the modification date is in the local time zone of the client. False means the time zone of the modification date is unknown.

  8. If not empty, the server id of the file or directory. A character string.

Uploading or downloading multiple files

When using kOW3ftpActionGetFileMulti or kOW3ftpActionPutFileMulti, to upload or download multiple files, the row passed to $progress has an extra column (requestNumber) which corresponds to the line number in the vParam list currently being transferred.

The $completed method is called with a successful status if all transfers are completed successfully. If at least one failed, the error code is 10312 (at least one transfer during a kOW3ftpActionGetFileMulti or kOW3ftpActionPutFileMulti action failed). In addition, the resultList column contains a list with a line for each transfer, containing error code, error info and FTP status code.

Methods

FTPClientWorker has the methods described in this section in addition to the base worker methods described earlier. $progress can be called for synchronous (as well as asynchronous) operations for the FTP worker.

Normal methods

$init

$init(cURI, cUser, cPassword, iAction, cServerPath, vParam)

Called to prepare the object to execute a request, before calling $run or $start.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cURI The URI of the server, optionally including the URI scheme (ftp or ftps) e.g.
ftp://ftp.myserver.com.
If you omit the URI scheme
e.g. ftp.myserver.com
the URI scheme defaults to ftp
cUser The user name to be used to log on to the FTP server.
cPassword The password to be used to log on to the FTP server
iAction A kOW3ftpAction… constant that specifies the action to perform.
cServerPath A pathname on the FTP server. Paths are relative to the current working directory on the FTP server. The worker only changes directory if you supply a non-empty cServerPath parameter to kOW3ftpActionExecute, so unless you do this, paths are relative to the root.
After changing working directory, if you supply cServerPath prefixed with // then the path is relative to the root, e.g.
/myfile or
myfile
is a path relative to the current working directory, whereas
//myfile
is a path relative to the root.
vParam A parameter specific to the action. See the constant descriptions for details of vParam for each action.

NOTE: If you call $init when a request is already running on a background thread, the object will cancel the running request, and wait for the request to abort before continuing with $init.

Example

You could create an FTP client window with various fields for FTP host name, username, password, timeout setting, server character set, and a list of FTP commands or actions as they are defined in the $init() method. A button could initiate the FTP command, executing the appropriate action depending on the one chosen by the end user, using the following code:

# start() method
# iFtp is an Object reference variable with the FTPClientWorker as Subtype
# iActionList (List) variable assigned to list of actions on the window
Do method setupLogging
Calculate iFtp.$timeout as iTimeout ## fields on the FTP window
Calculate iFtp.$callprogress as iCallProgress
Calculate iFtp.$keepconnectionopen as iKeepConnectionOpen
Calculate iFtp.$requiresecureconnection as iRequireSecureConnection
Calculate iFtp.$servercharset as iServerCharsetList.C2
Calculate iFtp.$responsepath as iResponsePath
If iActionList.C2=kOW3ftpActionPutFile.C2=kOW3ftpActionAppendFile
    If iSendContentMode=0
        ReadBinFile (iContentPath,iContent)
        Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,iContentReturns lOk
    Else
        Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,row(iContentPath)) Returns lOk
    End If
Else If iActionList.C2=kOW3ftpActionSetPermissions
    Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,iPermissionsReturns lOk
Else If iActionList.C2=kOW3ftpActionExecute
    Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,iCommandListReturns lOk
Else If iActionList.C2=kOW3ftpActionListDirectory
    Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,iNamesOnlyReturns lOk
Else If iActionList.C2=kOW3ftpActionDelete
    Do iFtp.$init(
iServerURI,iUser,iPassword,iActionList.C2,iServerPath,iPathIsDirectoryReturns lOk
Else
    Do iFtp.$init(iServerURI,iUser,iPassword,iActionList.C2,iServerPathReturns lOk
End If
# then $run or $start is called
If not(lOk)
    OK message {$init error [iFtp.$errorcode]: [iFtp.$errortext]}
    Quit method kFalse
End If
If pRun
    Do iFtp.$run() Returns lOk
Else
    Do iFtp.$start() Returns lOk
End If
If not(lOk)
    OK message {$run error [iFtp.$errorcode]: [iFtp.$errortext]}
    Quit method kFalse
Else If not(pRun)
    Calculate $cinst.$objs.scrollbox.$objs.cancel.$enabled as kTrue
    Calculate $cinst.$objs.scrollbox.$objs.start.$enabled as kFalse
    Calculate $cinst.$objs.scrollbox.$objs.startthencancel.$enabled as kFalse
End If
Quit method kTrue

Callback methods

$completed

The standard $completed callback is passed a row variable parameter with the following columns:

Column Description
errorCode An integer error code indicating if the request was successful. Zero means success i.e. the message was successfully sent.
errorInfo A text string providing information about the error if any.
ftpResponseCode The FTP response code from the last FTP command executed when performing the action. An integer.
fileData Used for kOW3ftpActionGetFile only. If you have not used $responsepath to write the file data directly to a file, this is a binary column containing the file data received from the server.
resultList For kOW3ftpActionList:
A single character column list, containing the list entries received from the server.
For kOW3ftpActionExecute:
A 2 column list, containing an entry for each command supplied in vParam that was successfully executed. Command execution stops as soon as a command fails; the status of the failed command becomes the main error information in the row passed to $completed.
Each row of the list contains the ftpResponseCode for the command, and the response text that was received from the server.
log If you used $protocollog to generate a log, this column contains the log data, either as character data, or UTF-8 HTML. Otherwise, the log column is empty.

Example

Following on from the $init example above, you could create code in the $completed method to handle the response from the FTP server returned in the pResults parameter: the code writes the log to an HTML file and displays it in the oBrowser object.

# $completed method
Calculate iResponse as pResults
Calculate iErrorCode as pResults.errorCode
Calculate iErrorText as pResults.errorInfo
If iUsingLogBrowser
    Do FileOps.$deletefile(iLogHTMLPath)
    WriteBinFile (iLogHTMLPath,iResponse.log)
    Calculate iLogBrowser.$urlorcontrolname as con("file://",replaceall(iLogHTMLPath," ","%20"))
Else
    Calculate iLog as iResponse.log
End If
Do $cinst.$redraw()
Calculate $cinst.$objs.tabpane.$currenttab as 3

Secure FTP (SFTP)

The FTP Worker Object supports Secure FTP (SFTP). There are some differences in functionality when using SFTP:

  1. You use URLs of the form SFTP:// to request an SFTP connection.

  2. You must explicitly select a server character set - kUniTypeAuto will cause the worker to return an error.

  3. The append file action is not supported.

  4. If you have written code that uses the execute action, be aware that SFTP servers support different commands to FTP servers.

  5. The remaining actions work as expected.

In addition, there are some properties and methods, primarily related to how a connection is authenticated. SFTP does not use TLS, so the secure options related to that only affect FTPS and FTP connections to be upgraded to TLS.

The FTP worker object has the properties:

  1. $sshenablecompression
    If true, SSH compression is enabled for SFTP connections, resulting in a request to the server to enable compression; the server may ignore the request. Defaults to false

  2. $sshknownhostsfile
    The full pathname of the SSH known hosts file used for SFTP. Defaults to the path of clientserver/client/ow3_sftp_known_hosts in the Studio tree. Set this to empty to allow connections (insecurely) to any host

  3. $sshknownhostsaction
    A sum of kOW3sshKHAction... constants (default kOW3sshKHActionReject) specifying what occurs if $sshknownhostsfile is present, and a connection is to be made to a server not in the file, or a server in the file with a host key mismatch

  4. $sshauthtypes
    A sum of kOW3sshAuthType... constants (default kOW3sshAuthTypePublicKey+kOW3sshAuthTypePassword+kOW3sshAuthTypeHost+kOW3sshAuthTypeAgent) specifying the allowed authentication types when establishing a connection to the server

The FTP worker object has the methods:

  1. $getsshoptions()
    $getsshoptions([&cServerPublicKeyMD5,&cClientPublicKeyFile,&cPrivKeyFile,&cPrivKeyPassword]) gets the options that affect how SSH connections are established for SFTP

  2. $setsshoptions()
    $setsshoptions([cServerPublicKeyMD5='',cClientPublicKeyFile='',cPrivKeyFile='',cPrivKeyPassword='']) sets the options that affect how SSH connections are established for SFTP. The parameters are:
    cServerPublicKeyMD5:The 128 bit MD5 checksum of the server's public key (supplied as a 32 character ASCII hex string).If not empty,the SFTP client will reject the connection to the server unless the MD5 checksums match
    cClientPublicKeyFile:The pathname of the client's public key. If empty,the client will try to compute the public key from the private key
    cPrivKeyFile:The pathname of the client's private key file
    cPrivKeyPassword:The private key file password

Some or all of the SSH options may be optional, depending on the authentication type chosen.

IMAP Worker

The IMAPClientWorker provides client IMAP support, allowing you to use the worker to manage emails stored on an IMAP server. The following sections describe the IMAP worker properties, constants and methods. (IMAP was added in Studio 8.1.1.)

Properties

The IMAPClientWorker has the following properties in addition to the base worker properties described earlier:

Property Description
$requiresecureconnection If true, and the URI is not a secure URI, the connection starts as a non-secure connection which must be upgraded to a secure connection (using the STARTTLS command). If it cannot be upgraded then the request fails. Defaults to false
$keepconnectionopen If true, the worker can leave the connection to the server open when it completes its request. Defaults to false.
Note that even when this property is set to true, a protocol error may cause the connection to close. Use true if you are likely to use the same server fairly soon.
$splitfetchedmessage If true, the worker splits the fetched message into headers and a MIME list for any content. Defaults to true. If false, the worker simply returns the raw fetched message data.
$defaultcharset Used when kOW3imapActionFetchMessage splits the message, and no character set is specified for a MIME text body part. The character set used to convert to character. Default kUniTypeUTF8. A kUniType... constant (not Character/Auto/Binary).
$removemessageid If true, the worker removes the Message-id header from the message when performing the action kOW3imapActionAppendMessage. Defaults to true.
Duplicating message ids may cause the IMAP server to discard messages with duplicate ids, hence this property.
$oauth2 An object reference to an OAUTH2Worker object containing the authorization information required to make requests to the server: see OAUTH2 section

Constants

The IMAPClientWorker uses the following constants in addition to the base worker constants described earlier. These constants are all actions used with the $init method to indicate the action to perform, so this section should be read in conjunction with the section describing the $init method:

Constant Description
kOW3imapActionListMailboxes List mailboxes in reference name cMailboxName.
vParam1 specifies the names to list. This becomes the “mailbox name with possible wildcards” parameter of the IMAP LIST or LSUB command (see RFC 3501).
vParam2 (optional, default false) is Boolean true to list subscribed mailboxes only.
kOW3imapActionListMessages Selects mailbox cMailboxName and lists the messages it contains.
vParam1 (optional), if present, it is a single column list of additional mail header names to retrieve in addition to the standard mailbox list information e.g. the list could have 2 rows, “Subject” and “X-Priority” to retrieve the message subject and priority for each message.
vParam2 (optional) is an IMAP search query selecting messages to list, e.g. UNSEEN to fetch the unread messages.
kOW3imapActionFetchMessage Selects mailbox cMailboxName and fetches the message with UID vParam1.
vParam2 (optional, default false) is Boolean true to fetch message headers only.
kOW3imapActionSetMessageFlags Selects mailbox cMailboxName and sets flags for message with UID vParam1.
vParam2 is a row of flags with values kFalse, kTrue or kUnknown (leave flag unchanged):
row(answered, deleted, draft, flagged, seen)
kOW3imapActionAppendMessage Selects mailbox cMailboxName and appends a message to the mailbox.
You can either:
Supply the entire message as binary data in vParam1 or
Supply a 2 character column list in vParam1 (columns are header name and header value) with binary raw content in vParam2
or
Supply a 2 character column list in vParam1 (columns are header name and header value) with the content specified by a MIME list in vParam2. See the documentation for the MailSplit command to see how a MIME list is structured; however note that the charset in the worker MIME list is a kUniType... constant rather than a character string.
kOW3imapActionExecute If cMailboxName is not empty select mailbox cMailboxName.
Then execute IMAP commands in vParam1. vParam1 is either a binary value or a single column list of binary values. wResults.resultList has a row for each command response.
Each binary value is an IMAP command to execute, e.g. EXAMINE. You can generate binary values using the correct character set required by the IMAP protocol using the $chartoutf7 method of the IMAPClientWorker.
The sequence of actions will stop as soon as an error occurs.

Methods

IMAPClientWorker has the methods described in this section in addition to the base worker methods described earlier.

Normal methods

$init

$init(cURI, cUser, cPassword, iAction, cMailboxName, vParam1, vParam2) Called to prepare the object to execute a request, before calling $run or $start.

Returns Boolean true for success, or returns false and sets $errorcode and $errortext if an error occurs.

The parameters are:

Parameter Description
cURI The URI of the server, optionally including the URI scheme (imap or imaps), e.g. imap://ftp.myserver.com. If you omit the URI scheme, e.g. imap.myserver.com, the URI scheme defaults to map
cUser The user name to be used to log on to the FTP server.
cPassword The password to be used to log on to the FTP server
iAction A kOW3imapAction… constant that specifies the action to perform.
cMailboxName The IMAP mailbox name (ignored for kOWEimapActionListMailboxes). If you are using non-ASCII characters in mailbox names, you may need to normalise the name using the Omnis nfd() or nfc() function before passing it to $init().
vParam1 A parameter specific to the action. See the constant descriptions for details of vParam1 for each action.
vParam2 A parameter specific to the action. See the constant descriptions for details of vParam2 for each action.

NOTE: If you call $init when a request is already running on a background thread, the object will cancel the running request, and wait for the request to abort before continuing with $init.

$chartoutf7

$chartoutf7(cChar)

Returns a binary value (containing 7 bit characters) that is the IMAP UTF-7 representation of cChar (note that IMAP uses a special variant of UTF-7, and this method generates that variant).

The parameters are:

Parameter Description
cChar A character string to be converted to IMAP UTF-7

$utf7tochar

$utf7tochar(xUtf7[,bAllowCRLF=kTrue])

Converts IMAP UTF-7 xUtf7 to character and returns the result. Optionally allows CRLF sequences in the data and replaces them with CR in the result (note that IMAP uses a special variant of UTF-7, and this method expects that variant in xUtf7).

The parameters are:

Parameter Description
xUtf7 A binary value containing IMAP UTF-7 to be converted to character.
bAllowCRLF If true, CRLF sequences are to be expected in the UTF-7 stream - they are replaced with CR.

Callback methods

$completed

The standard $completed callback is passed a row variable parameter with the following columns:

Column Description
errorCode An integer error code indicating if the request was successful. Zero means success i.e. the message was successfully sent.
errorInfo A text string providing information about the error if any.
resultList This column receives a list, the content of which depends on the action. The action-specific lists returned here are described below (actions kOW3imapActionSetMessageFlags and kOW3imapActionAppendMessage do not return any data in this column).
log If you used $protocollog to generate a log, this column contains the log data, either as character data, or UTF-8 HTML. Otherwise, the log column is empty.
<action-specific> Column 5 is present for certain actions, and contains action- specific data. The action-specific data is described below.

kOW3imapActionListMailboxes:

Column Description
resultList The list of mailboxes that match the criteria pass to $init(). A 7 column list, with columns as follows (see RFC 3501 for more details - the data in these columns is populated using the LIST or LSUB response):
hasChildren: Boolean true if the mailbox has child mailboxes.
noInferiors: Boolean true if it is not possible for any child levels of hierarchy to exist under this name; no child levels exist now and none can be created in the future.
noSelect: Boolean true if it is not possible to use this name as a selectable mailbox.
marked: Boolean true if the mailbox has been marked "interesting" by the server; the mailbox probably contains messages that have been added since the last time the mailbox was selected.
unMarked: Boolean true if the mailbox does not contain any additional messages since the last time the mailbox was selected.
separator: The mailbox hierarchy delimiter.
mailboxName: The name of the mailbox.
<action‑specific> No action specific column.

kOW3imapActionListMessages:

Column Description
resultList The list of messages in the mailbox. This is a list with 9 standard columns, followed by a column for each header specified in vParam2 when calling $init() to prepare for this action. The additional header columns are named by removing - characters from the header name, and converting the result to lower case.

The 9 standard columns in the message list are:
UID: The unsigned integer UID of the message
size: The size of the message in bytes
internalDate: The internal date of the message.
answered: The Boolean answered flag for the message.
deleted: The Boolean deleted flag for the message.
draft: The Boolean draft flag for the message.
flagged: The Boolean flagged flag for the message.
recent: The Boolean recent flag for the message.
seen: The Boolean seen flag for the message.
<action‑specific> No action specific column.

kOW3imapActionFetchMessage:

Column Description
resultList

If $splitfetchedmessage is kFalse, this column is not populated. Otherwise, this column is a 2 character column list of mail headers:

Column 1 is the header name.
Column 2 is the header value.

<action‑specific> If the action fetches the message content as well as the headers, this column receives the content. It is either:
rawData: A binary column that receives the un-split fetched message data
or
mimeList: A MIME list containing the content. See the documentation for the MailSplit command to see how a MIME list is structured; however note that the charset in the worker MIME list is a kUniType... constant rather than a character string.

kOW3imapActionSetMessageFlags:

Column Description
resultList Not populated.
<action‑specific> No action specific column.

kOW3imapActionAppendMessage:

Column Description
resultList Not populated.
<action‑specific> If possible, the action extracts the UID of the appended message from the IMAP server response. The UID is returned to this column (named UID) and is non-zero if the UID could be extracted. (Note that not all servers return the UID of an appended message).

kOW3imapActionExecute:

Column Description
resultList A single column list of binary values. Each row of the list contains the sequence of responses returned from the server when executing the corresponding command in the list (or single binary value) passed to $init(). You would typically decode this using $utf7tochar, using the option to expect CRLF and replace with CR.
<action‑specific> No action specific column.

JavaScript Worker Object

The node.js framework contains many open source third-party modules that can be used from inside your Omnis code: node.js is embedded into Omnis Studio. The JavaScript Worker Object allows you to execute JavaScript methods inside node.js by making the request in Omnis code by calling a worker object method, and receiving the results via a worker callback. For example, the library ‘xml2js’ is included in Omnis Studio, which converts XML to JSON: in addition, support for ZIP can be added using the node.js jszip module, which is described at the end of this section.

Enabling Javascript Methods

There is a JS file, ow3javascript.js, located in the clientserver/server/remotedebug program folder, that is the entry point for all method calls: on macOS, the remotedebug folder is in the Resources folder in the Omnis.app bundle. Method calls arrive as an HTTP request from Omnis, and respond with their results as HTTP content. A worker executes methods sequentially.

Omnis has a simple structure where you can write a JavaScript module containing one or more methods, and then call methods via their module and method name.

In the Omnis data folder, there is a new folder called node_modules, where modules required by ow3javascript.js are located. You can install additional node.js modules in this folder using the npm -i command when running in the folder - these might be modules for which you want to provide an interface from Omnis.

There are two key files in this folder, which must always be present:

omnis_calls.js - a module which provides an interface for methods to return their results to Omnis.

omnis_modules.js - a module which provides a table of modules that can be called from Omnis.

There are also two example module files, omnis_test.js and omnis_xml2js.js. These provide Omnis modules named test and xml2js. Each module file must have an entry in omnis_modules.js. Each module file provides a table of methods that can be called from Omnis.

Note that node_modules in the data folder may not be considered suitable for deployment, since the data folder is writeable. The worker provides the ability for you to structure things differently when you deploy your application, but is fine for development.

Creating the worker

The sub-type of the external object is OW3 Worker Objects\JAVASCRIPTWorker. You can use either an Object variable or an Object Reference variable, either directly if you set $callbackinst to receive results, or by subclassing the external object with an Omnis object.

Properties

The JavaScript worker only has the standard worker properties: $state, $threadcount, $errorcode and $errortext.

Methods

Called Methods

$init()

$init([cPath, bDebugNodeJs=kFalse])

Initialize the object so it is ready to execute JavaScript method calls. Returns true if successful. You must call $init() before any other methods.

  1. cPath
    allows you to override the default NODE_PATH module search path set by the worker. The default path is <Omnis data folder>/node_modules. If you override this path, the various JavaScript modules that are mandatory for the worker to operate must still be able to be located.

  2. bDebugNodeJs
    is a Boolean that indicates if you want to be able to debug node.js, for example using Chrome. It is possible that you may not be able to start the worker if you set this for more than one active JavaScript worker, as node.js requires a debug port to be available. To debug the JavaScript in Chrome, navigate to chrome://inspect, and then open the dedicated debug tools for node.js via the link.

$start()

$start()

Runs the JavaScript worker in a background thread. Returns true if the worker was successfully started.

After you call $start(), the background thread starts up a node.js process which will process JavaScript method calls. You can make multiple method calls to the same process, so there is no need to call $start() frequently, which means the overhead of starting the node.js process is minimal.

$cancel()

$cancel()

Use this to terminate the node.js process. Any in-progress method calls may not complete.

$callmethod()

$callmethod(cModule, cMethod, vListOrRow [,bWait=kFalse, &cErrorText])

Call the method passing it a single parameter which is the JavaScript object representation of vListOrRow. Optionally wait for the method to complete. Returns true if successful.

cModule and cMethod identify a module, and a method within the module, to call, as described above.

vListOrRow will be converted to JSON and passed to the method as its parameter. This means that you should be aware of data that will not map to JSON, and avoid trying to pass that to $callmethod.

bWait indicates if the caller wishes to suspend execution until the method completes. If you use bWait, then a completion callback will occur before $callmethod returns.

cErrorText receives text describing the error if $callmethod fails.

Callback Methods

$cancelled

Override this to receive a notification that the request to cancel the worker has succeeded.

$workererror

$workererror(wError)

Override this method to receive reports of errors from the worker that are not related to calling a method, e.g. failure to start node.js. The worker thread exits after generating this notification.

wError has two columns, an Integer named errorCode and a Character string named errorInfo.

$methoderror

$methoderror(wError)

Override this method to receive reports of the failure of an attempt to call a method with $callmethod.

wError has two columns, an Integer named errorCode and a Character string named errorInfo.

If an unhandled exception occurs causing node.js to exit, Omnis adds the stack traceback of the exception to the errorInfo column.

$methodreturn

$methodreturn(wReturn)

Method called with the results of a call to $callmethod.

wReturn is a list/row parameter with two columns: __module and __method. If the parameter is a list, then __module and __method are only populated for the first line of the list.

If the JavaScript method returns an object, this is the Omnis equivalent of the object, created by converting the JSON to a row. If the JavaScript method returns some other data, e.g. a picture, this is a row with a single column named content, which contains the data returned by the method.

The content column for non-JSON content returned from a worker method is of type character when the content type is text/.

Example: Adding ZIP support

You could add support for ZIP files. To do this, install the node.js jszip module by running the npm command in the node_modules folder:

npm i jszip
(the npm command is installed with node.js, available on the web)

Edit omnis_modules.js as by adding this line after the other require() lines:

const zipModule = require('omnis_zip.js');

Add this entry to the moduleMapClass:

zip(method, obj, response) {
return zipModule.call(method, obj, response);
}

You can then make calls from Omnis code as follows:

 Do lRow.$cols.$add("path",kCharacter,kSimplechar)
 Calculate lRow.path as iZipPath
 Do iJS.$callmethod("zip","loadZip",lRow,kTrue,lErrorTextReturns lOK

POP3 Worker Object

The POP3 worker is similar to other OW3 workers, in that you pass an action to $init and action specific parameters, and use $run or $start to execute the request. There is a sample app in the HUB in the Studio Browser.

Methods

$init()

The $init method has the following syntax:

$init(cURI,cUser,cPassword,iAction[,iMessageNumber,cPostCommand])

Initialises the object so it is ready to perform the specified action using POP3. Returns true if successful

The $init parameters are:

Parameter Description
cURI The URI of the server, optionally including the URI scheme (pop3 or pop3s) e.g. pop3://pop3.myserver.com. If you omit the URI scheme, e.g. pop3.myserver.com, the URI scheme defaults to pop3
cUser The username to be used to log on to the POP3 server
cPassword The password to be used to log on to the POP3 server
iAction A kOW3pop3Action... constant that specifies the action to perform; see below
iMessageNumber The message number to get (applies to actions kOW3pop3ActionGetMessage, kOW3pop3ActionGetHeaders and kOW3pop3ActionDeleteMessage)
cPostCommand Only applies to action kOW3pop3ActionGetMessage. If not empty, a command to send to the server after getting the message. This would typically be RSET to undelete messages or QUIT to delete messages

The Actions are:

  1. kOW3pop3ActionStat Gets maildrop status. For a successful request, wResults has 2 columns returning the stat information, messageCount and maildropSize

  2. kOW3pop3ActionList Lists messages. For a successful request, wResults has a column named messageList which contains a 2 column list, with columns messageNumber and messageSize

  3. kOW3pop3ActionGetMessage Gets specified message. For a successful request, wResults has either a column rawData or columns headerList and mimeList (depending on the value of $splitfetchedmessage

  4. kOW3pop3ActionGetHeaders Gets headers for a specified message. For a successful request, wResults has either a column rawData or a column headerList (depending on the value of $splitfetchedmessage)

  5. kOW3pop3ActionDeleteMessage Deletes the specified message from the maildrop

  6. kOW3pop3ActionQuit Sends a QUIT command to the server to ensure that any messages marked for deletion are deleted

Properties

The OW3 POP3 worker has the following properties in addition to those supported by all OW3 worker objects:

Property Description
$splitfetchedmessage If true, worker splits fetched message into headers and MIME list for any content. Defaults to true. If false, the worker simply returns the raw fetched message data (Applies to kOW3imapActionFetchMessage and kOW3pop3ActionGetMessage)
$defaultcharset Used by kOW3imapActionFetchMessage and kOW3pop3ActionGetMessage when there is no charset for a MIME text body part. The charset used to convert to character. Default kUniTypeUTF8.A kUniType... constant (not Character/Auto/Binary)
$keepconnectionopen If true, the worker can leave the connection to the server open when it completes its request. Defaults to false. Note that even when this property is set to true, a protocol error may cause the connection to close.
$requiresecureconnection If true, and the URI is not a secure URI, the connection starts as a non-secure connection which must be upgraded to a secure connection (using STARTTLS or STLS). If it cannot be upgraded then the request fails. Defaults to false
$oauth2 An object reference to an OAUTH2Worker object containing the authorization information required to make requests to the server: see OAUTH2 section

CRYPTO Worker Object

A CRYPTO Worker Object has been added to the OW3 Worker Objects to allow you to perform encryption and decryption of data. The encryption types you can use include AES, Camellia, DES, and Blowfish.

The CRYPTO worker is similar to other OW3 workers, in that you pass an action to $init and action specific parameters, and use $run or $start to execute the request. There is a new sample app in the HUB in the Studio Browser to demo the CRYPTO Worker Object.

To use the worker object, create a variable with its subtype set to the CRYPTOWorker object which is contained in the OW3 Worker Objects group in the Select Object dialog, or subclass the external object.

The CRYPTO worker has the following methods:

  1. $start, $run and $cancel
    Standard worker methods

  2. $completed and $cancelled
    Standard worker completion methods

  3. $makerandom
    $makerandom(iBytes,&xRandomData) generates some random data with the specified length in bytes. This is suitable for use as an encryption key or initialization vector. Returns true if successful (if an error occurs, the standard properties $errorcode and $errortext describe the error).
    iBytes is the number of bytes of random data to generate
    xRandomData is a binary variable that receives the random data

As with the other worker objects you can use the $init method with various input parameters to initialize the object, while the action can be to Encrypt or Decrypt:

  1. $init
    $init(iAction, iEncryptionType, iCipherMode, iPadding, xKey, xIV, vInputData [,cOutputPath]) initialises the object ready to perform the encryption or decryption. Returns true if successful

iAction can be either:

  1. kOW3cryptoActionEncrypt
    Encrypt the data using the specified encryption scheme and parameters

  2. kOW3cryptoActionDecrypt
    Decrypt the data using the specified encryption scheme and parameters

iEncryptionType can be one of:

  1. kOW3cryptoTypeAES
    AES encryption. Key size must be 128, 192 or 256 bits

  2. kOW3cryptoTypeCamellia
    Camellia encryption. Key size must be 128, 192 or 256 bits

  3. kOW3cryptoTypeDES
    DES encryption. Key size must be 64 or 192 bits. Uses Triple DES if key size is 192 bits

  4. kOW3cryptoTypeBlowfish
    Blowfish encryption. Key size must be 128 bits

iCipherMode can be one of:

  1. kOW3cryptoCipherModeCBC
    CBC (Cipher Block Chaining)

  2. kOW3cryptoCipherModeECB
    EBC (Electronic Code Book)

  3. kOW3cryptoCipherModeCTR
    CTR (Counter). Not supported for kOW3cryptoTypeDES

iPadding can be one of:

  1. kOW3cryptoPaddingNone
    No padding (use this for cipher modes other than CBC and EBC)

  2. kOW3cryptoPaddingPKCS7
    PKCS7 padding

  3. kOW3cryptoPaddingOneAndZeros
    One and zeros padding (ISO/IEC 7816-4)

  4. kOW3cryptoPaddingZerosAndLen
    Pad with N-1 zero bytes followed by a byte with value N, where N is the number of padding bytes (ANSI X.923)

  5. kOW3cryptoPaddingZeros
    Pad with N zero bytes, where N is the number of padding bytes

Note that PKCS7 is the most common and allows binary data to be correctly decrypted, for example, kOW3cryptoPaddingZeros can lead to extra bytes being stripped from decrypted binary data.

xKey is a binary containing the key. See the encryption types for details of supported key lengths.

xIV is a binary containing the Initialization Vector (IV) (random data that can be used to make the same encrypted data different when using the same key). This must be 8 bytes long for DES and Blowfish, and 16 bytes long for AES and Camellia.

vInputData is the data to be encrypted. Either a character value which is the pathname of the file containing the data to encrypt or decrypt, or a binary variable containing the data to encrypt or decrypt.

cOutputPath is:

  1. Either omitted or empty meaning that the encrypted or decrypted data is supplied to $completed in the data column of the results row parameter (this column has type binary)

  2. Or the pathname of a file (which must not already exist) to which the worker will write the encrypted or decrypted data

The results row passed to $completed has 3 columns: errorCode, errorInfo and data. The error columns behave in the same way as the other OW3 workers: note that a negative error code is a code returned by the mbedTLS library. The data column is only used when cOutputPath was omitted when calling $init.

The worker has properties as follows:

  1. $errorcode, $errortext, $state and $threadcount
    Standard worker properties

  2. $useexplicitiv
    If true, a random IV is added to the start of the data when encrypting or the first IV size bytes is removed from decrypted data. Only applies to CBC cipher mode. This means that a user can decrypt data without knowing the IV (any IV can be used for decryption, which will result in just the first IV size bytes being decrypted incorrectly, because of the way the CBC cipher mode works)

HASH Worker Object

The HASH Worker Object allows you to hash data using SHA1, SHA2, SHA3, MD5, and RIPEMD hash types, which are primarily for signature purposes, while PBKDF2 is available for password hashing. You use the $inithash() method to initialise the object, passing the binary or character data to be hashed, and the hash type represented by a constant, as follows:

Hash type Constant
SHA1 kOW3hashSHA1
SHA2 incl hash output 256, 384, 512 kOW3hashSHA2_256
kOW3hashSHA2_384
kOW3hashSHA2_512
SHA3 incl hash output 256, 384, 512 kOW3hashSHA3_256
kOW3hashSHA3_384
kOW3hashSHA3_512
MD5 kOW3hashMD5
RIPEMD_160 kOW3hashRIPEMD_160
PBKDF2 kOW3hashPBKDF2

You can use $initverifyhash to verify or compare some data against previously hashed data generated using $inithash. Having called the $init… methods, you can use $run or $start to execute the request.

To use the worker object, create a variable with its subtype set to the HASHWorker object which is contained in the OW3 Worker Objects group in the Select Object dialog, or subclass the external object. There is a new sample app in the HUB in the Studio Browser to demo the HASH Worker Object.

The HASH worker object has methods as follows:

  1. $start, $run and $cancel
    Standard worker methods

  2. $completed and $cancelled
    Standard worker completion methods

  3. $inithash()
    $inithash(vData,iHashType,wHashParameters) initialises the object so it is ready to hash data using the specified hash type
    vData is the data to hash. Either binary or character. A binary value is used directly. Otherwise, for PBKDF2 the worker converts character data to UTF-8 before generating the hash, and for other hash types, a character parameter is the pathname of the file containing the data to hash.
    iHashType the hash type, a kOW3hash… constant.
    wHashParameters A row of parameters that control the hash. For all except PBKDF2, an empty row(). For PBKDF2, a row with 3 integer columns in the order saltLength, keyLength, iterations.
    Salt length - the length of the random salt (generated by the worker). A good value for this is 16. Must be 8 to 64 inclusive
    Key length - the length of the hashed key to be generated. A good value is 32. Must be between 16 and 256 inclusive
    Iterations - the number of iterations to perform to generate the hash. A good value for iterations is at least 100000 - the higher the value, the more secure the hash, traded off against a longer execution time. Must be between 1 and 256000 inclusive

  4. $initverifyhash()
    $initverifyhash(vData,iHashType,vHash) Initialises the object so it is ready to generate the hash for vData using iHashType and compare it against previously generated vHash (vHash includes the hash parameters used to generate the original hash), e.g. you could create a hash using $inithash and store that for future use. To verify a password or document you call $initverifyhash, with vData as the password or document to verify, and vHash as the stored hash from your call to $inithash.

After calling one of the $init… methods, you call $run or $start. The results row passed to $completed has 3 columns: errorCode, errorInfo and data. The error columns behave in the same way as the other OW3 workers - note that a negative error code is a code returned by the mbedTLS library. The data column is only used for $inithash() and it contains the generated binary hash, provided that no error occurred – you may want to convert this to base64 before storing it, but note that if you do this you will need to convert it back to binary before using it to verify data. For $initverifyhash(), the errorCode is zero if and only if the hash was successfully verified.

The worker has properties as follows:

  1. $errorcode, $errortext, $state and $threadcount
    Standard worker properties

HMACs

HMACs can be generated for all hash types except PBKDF2 and the SHA3 hashes; the maximum key length for an HMAC is 64.

To generate an HMAC rather than a hash, supply the binary key as the hash parameters parameter of $inithash() – an empty row as this parameter generates a hash rather than HMAC. To verify an HMAC rather than a hash, supply the binary key as a new binary last parameter to $initverifyhash() – this is optional and its presence indicates HMAC.

Web Worker Objects

The following section refers to the Web Worker Objects (OWEB) available in Omnis Studio prior to Studio 8.1 (introduced in Studio 6.1.2): note they require Java to be installed and are therefore no longer supported in Studio 10.x onwards: you should consider moving to the OW3 Worker objects model.

SMTP Client Workers

The SMTP worker object allows you to submit email(s) to an SMTP server in a background thread, working in a similar way to the existing “worker objects” for DAMs, HTTP and Timers. In addition, it provides support for authentication methods not supported by the existing SMTPSend command including DIGEST-MD5, NTLM and OAUTH2.

In addition to the SMTP worker object, there is an object called EMAILMessage, which you use to build the message to be sent by the worker.

Software Requirements

The SMTP worker object relies on Java, and therefore relies on some Java files located in the ‘java/axis/lib’ folder in the main Omnis Studio folder: see the Java Objects chapter for details about running Java in Omnis.

EMAILMessage Object

The EMAILMessage object is used to construct the message to be sent to the SMTP Client worker. The EMAILMessage object has methods to manipulate the MIME body parts of the message. Each body part has a non-zero integer identifier that uniquely identifies the body part within the context of the object instance. EMAILmessage needs to remain in scope until the worker $completed or $cancelled message is called.

Note: If you specify a charset of kUniTypeAuto for binary or file body parts, the object will inspect the data, and set its charset according to the presence of a BOM (Byte Order Marker) to kUniTypeUTF8, kUniTypeUTF16BE, kUniTypeUTF16LE, kUniTypeUTF32BE or kUniTypeUTF32LE. If there is no BOM, the charset will be kUniTypeNativeCharacters, resulting in iso-8859-1 for Linux, macintosh for macOS or windows-1252 for Windows.

Methods

$createbodypartfromfile

$createbodypartfromfile(cPath[,cMIMEType,iCharset,cEncoding,cDisposition,cFilename])

Creates a MIME file body part. Returns non-zero integer body part id (unique for this EMAILMessage object) or zero if an error occurs.

Parameter Description
cPath The pathname of the file containing the body part data.The name of the file will also be used to set the filename for the attachment if you do not also pass the cFilename parameter
cMIMEType The MIME type of the body part,in the standard syntax of type/subtype. If you omit this, the object will use a mapping table built into oweb.jar to generate the MIME type from the file extension; if this mapping fails, the type defaults to application/octet-stream.
iCharset A kUniType... constant (default kUniTypeAuto) indicating the charset of MIME type text/... (cannot be kUniTypeBinary or kUniTypeCharacter). If this body part needs a charset,it is assumed to be already encoded using this charset.
cEncoding The encoding to be used to transfer the body part data e.g. ‘BASE64’. If omitted,the mail client chooses a default.
cDisposition The content disposition value to be used for the body part e.g. ‘inline’ or ‘attachment’. If omitted, the mail client will use the default disposition.
cFilename The name sent as the filename of the body part.Defaults to the file name component of cPath if omitted.

$createbodypartfromchar

$createbodypartfromchar(cData[,cMIMEType,iCharset,cEncoding,cDisposition,cFilename])

Creates a MIME body part from character data. Returns non-zero integer body part id (unique for this EMAILMessage object) or zero if an error occurs.

Parameter Description
cData The character data to be used as the content of the body part.
cMIMEType The MIME type of the body part,in the standard syntax of type/subtype. If you omit this, the type defaults to text/plain.
iCharset A kUniType... constant(default kUniTypeUTF8) indicating the charset to be used for the character data (cannot be kUniTypeAuto, kUniTypeBinary or kUniTypeCharacter).
cEncoding The encoding to be used to transfer the body part data e.g. ‘BASE64’. If omitted,the mail client chooses a default.
cDisposition The content disposition value to be used for the body part e.g. ‘inline’ or ‘attachment’. If omitted, the mail client will use the default disposition.
cFilename The name sent as the filename of the body part. If omitted, no filename will be used.

$createbodypartfrombin

$createbodypartfrombin(xBin[,cMIMEType,iCharset,cEncoding,cDisposition,cFilename])

Creates a MIME body part from binary data. Returns non-zero integer body part id (unique for this EMAILMessage object) or zero if an error occurs.

Parameter Description
xBin The binary data to be used as the content of the body part.
cMIMEType The MIME type of the body part,in the standard syntax of type/subtype. If you omit this, the type defaults to application/octet-stream.
iCharset A kUniType... constant (default kUniTypeAuto) indicating the charset of MIME type text/... (cannot be kUniTypeBinary or kUniTypeCharacter). If this body part needs a charset,it is assumed to be already encoded using this charset.
cEncoding The encoding to be used to transfer the body part data e.g. ‘BASE64’. If omitted, the mail client chooses a default.
cDisposition The content disposition value to be used for the body part e.g. ‘inline’ or ‘attachment’. If omitted, the mail client will use the default disposition.
cFilename The name sent as the filename of the body part. If omitted, no filename will be used.

$createbodypartfromparts

$createbodypartfromparts(cMultiType,vPart[,iPart2,...])

Creates a MIME multi-part body part containing specified body parts. Returns non-zero integer body part id (unique for this EMAILMessage object) or zero if an error occurs.

Parameter Description
cMultiType The type of multi-part body part being created e.g. mixed
vPart Either an integer body part id for a previously created body part in the EMAILMessage object or a single column list of integer body part ids for previously created body parts.
iPart2 An integer body part id for a previously created body part in the EMAILMessage
Further parameters can be integer body part ids for previously created body parts.

Note that each body part can only be used once in a multi-part body.

$deleteaallbodyparts

$deleteaallbodyparts()

Deletes all body parts that have been created using a $createbodypart... method. Also sets property $contentid to zero.

Properties

The EMAILMessage object has the following properties:

Property Description
$errorcode Error code associated with the last action (method call or property assignment) (zero means no error)
$errortext Error text associated with the last action (method call or property assignment) (empty means no error)
$from The email address of the sender
$subject The subject of the message
$to A space separated list of email addresses of the primary recipients of the message
$cc A space separated list of email addresses of the carbon copied recipients of the message
$bcc A space separated list of email addresses of the blind carbon copied recipients of the message
$priority A kOWEBmsgPriority... constant that specifies the priority of the message. Defaults to kOWEBmsgPriorityNormal.
$extraheaders A list with 2 character columns (name and value). Each row in the list is an additional SMTP header to be sent to the server when submitting the message.
$contentid The id of the content to be sent with this email message. An integer body part id (returned by one of the $createbodypart... methods).

Constants

The EMAILMessage object has the following constants:

Constant Description
kOWEBmsgPriorityLowest The message has the lowest priority.
kOWEBmsgPriorityLow The message has low priority.
kOWEBmsgPriorityNormal The message has normal priority.
kOWEBmsgPriorityHigh The message has high priority.
kOWEBmsgPriorityHighest The message has the highest priority.

SMTPClientWorker Object

The SMTPClientWorker object uses the standard worker mechanism, with methods $init, $start, $run and $cancel, and callbacks $completed and $cancelled. In addition, there are some properties which further control the behavior of the object.

Methods

$init

$init(zMessage,cServer[,iSecure=kOWEBsmtpSecureNotSecure,
iAuthType=kOWEBsmtpAuthTypeNone,cUser,cPassword,cOAUTH2,
cRealm,cNTLMDomain,lProps, bMailShot=kFalse ])

Initialize the worker object so it is ready to send message oMessage. Returns true if successful.

Parameter Description
zMessage An object reference to the EMAILMessage to send.
cServer The SMTP server that will send the message.Either a domain name or IP address.You can optionally specify the server port by appending ':<port number>’.
iSecure A kOWEBsmtpSecure... constant that indicates if and how the connection is to be made secure.
iAuthType A sum of kOWEBsmtpAuthType... constants that specify the allowed authentication types.
cUser The user name that will be used to log on to the SMTP server.
cPassword The password that will be used to log on to the SMTP server.
OAUTH2 The SMTPClientWorker can manage OAUTH2 authentication for you. If you want it to do this, then this parameter is the name of the authority responsible for OAUTH2 authentication. This name is the name of a folder (which must exist) in secure/oauth2/smtp in the Omnis folder (the authority folder contains configuration and assets for this authority). In this case, cPassword is not used if OAUTH2 is the authentication mechanism chosen by the mail client. If you want to manage OAUTH2 yourself, then OAUTH2 must be empty or omitted, and the password must be the OAUTH2 access token. See the section on OAUTH2 for more details.
cRealm The realm used for DIGEST-MD5 authentication.
cNTLMDomain The domain used for NTLM authentication.
lProps A list with 2 character columns (name and value). A list of properties to be set for the JavaMail SMTP session object (see docs for package com.sun.mail.smtp at https://javamail.java.net/nonav/docs/api/). The SMTPClientWorker sets these properties as a final step, meaning that this can be used to override properties set by the worker, or to set other properties.
bMailShot If bMailShot is true (the default is false), the worker sends a separate copy of the message to each recipient (each recipient cannot see the email address of the other recipients). In this case, only 'to' recipients can be specified.

$run

$run([cOAUTH2authCode])

Runs the worker on current thread. Returns true if the worker executed successfully. The cOAUTH2authCode parameter is discussed in the section on OAUTH2. It is not required in the initial call to $run to send an email.

$start

$start([cOAUTH2authCode])

Runs the worker on background thread. Returns true if the worker was successfully started. The cOAUTH2authCode parameter is discussed in the section on OAUTH2. It is not required in the initial call to $start to send an email.

$cancel

$cancel()

If required,cancels execution of worker on background thread. Will not return until the request has been cancelled.

$completed

$completed(wResults)

Callback method called when the request completes. Typically, you would subclass the SMTPClientWorker, and override $completed in order to receive the results. wResults is a row containing the results of executing the request. It has columns as follows:

Column name Description
errorCode An integer indicating the error that has occurred. Zero means no error occurred, and the email was successfully sent.
errorInfo Error text that describes the error. Empty if no error occurred.
log If the property $debuglog was set to kTrue before calling $init, this character column contains debugging information, including a log of the interaction with the SMTP server.
oauth2_authcodeurl Only applies when using OAUTH2 authentication managed by the SMTPClientWorker, and when errorCode is kOWEBsmtpErrorOAUTH2authCodeRequired. The URL to which the user needs to navigate in order to obtain an OAUTH2 authorisation code. See the section on OAUTH2 for more details.

$cancelled

$cancelled()

Callback method called when the request has been cancelled by a call to $cancel(). Typically, you would subclass the SMTPClientWorker, and override $cancelled.

Properties

The SMTPClientWorker object has the following properties:

Property Description
$state A kWorkerState... constant that indicates the current state of the worker object.
$errorcode Error code associated with the last action (zero means no error).
$errortext Error text associated with the last action (empty means no error).
$threadcount The number of active background threads for all instances of this type of worker object.
$debuglog If true,when the worker executes it generates a log of the interaction with the SMTP server.Must be set before executing $init for this object.The log is supplied as a column of the row variable parameter passed to $completed.
$timeout The timeout (in seconds) for SMTP requests (default is 30). Zero means infinite. Must be set before executing $init for this object.
$clientsecret The OAUTH2 client secret to be used to obtain tokens for OAUTH2. Must be set before executing $init for this object. Overrides the clientSecret (if any) in the OAUTH2 authority file. See the section on OAUTH2 for more details. This property is only relevant if the SMTPClientWorker is managing OAUTH2 authentication using an OAUTH2 authority.

Constants

Authentication Types

These constants can be added together in order to form a bit mask of allowed authentication types:

Constant Description
kOWEBsmtpAuthTypeNone This has value zero, as a convenient way to indicate that no SMTP authentication is required.
kOWEBsmtpAuthTypeLOGIN SMTP LOGIN authentication is allowed if the server supports it.
kOWEBsmtpAuthTypePLAIN SMTP PLAIN authentication is allowed if the server supports it.
kOWEBsmtpAuthTypeDIGESTMD5 SMTP DIGEST-MD5 authentication is allowed if the server supports it.
kOWEBsmtpAuthTypeNTLM SMTP NTLM authentication is allowed if the server supports it.
kOWEBsmtpAuthTypeCRAMMD5 SMTP CRAM-MD5 authentication is allowed if the server supports it.
kOWEBsmtpAuthTypeOAUTH2 SMTP OAUTH2 authentication is allowed if the server supports it

Secure Connection Type

These constants indicate how the connection is to be made secure:

Constant Description
kOWEBsmtpSecureNotSecure The connection between client and server is not secure.
kOWEBsmtpSecureSSL The connection between client and server uses SSL.
kOWEBsmtpSecureSTARTTLS The connection between client and server is to be made secure by using the STARTTLS command.

OAUTH2

This section provides an overview of OAUTH2, including some key terms.

OAUTH2 provides a way for applications to perform actions on behalf of a user, provided that they have the permission of the user. So in the case of the SMTPClientWorker, when using OAUTH2 authentication, the Omnis Studio client needs to be given permission to send the email.

This all occurs in the context of an OAUTH2 authority, so for example if you are using GMAIL, the OAUTH2 authority is Google, or if you are using Windows mail, the OAUTH2 authority is Microsoft. he client application (Omnis Studio or more typically your application) needs to be registered as an application with the OAUTH2 authority; this gives it two key pieces of information:

  1. Client ID. A unique identifier for the client application.

  2. Client secret. A string used in requests to the OAUTH2 authority that authenticates the application. This needs to be kept as private as possible.

How you register your application with the OAUTH2 authority depends on the particular authority. For example:

  1. For Google
    go to the Google Developers Console (https://console.developers.google.com) and create a new project. On the credentials screen, create a new client ID for an installed application of type other.

  2. For Microsoft
    go to the Microsoft account Developer centre (https://account.live.com/developers/applications/) and create an application.
    In the API Settings make sure “Mobile or desktop client app” is set to Yes.

The user interfaces for these developer consoles allow you to obtain the client ID and client secret.

In order to use OAUTH2 authentication, the application needs to supply an OAUTH2 access token as the password. An access token is a short-lived password that is typically valid for an hour. The first time the application needs an access token, there has to be some interaction at the user interface:

  1. The application opens a browser window at the OAUTH2 authorisation code URL for the authority. Note that this URL includes a scope which indicates what type of permission is being requested. Each authority has a scope value which indicates that the user wants to manage email.

  2. The browser window may ask the user to log on to their account with the relevant authority. Once logged on, it will ask the user if they give the particular application permission to use their email. If the user agrees, the browser redirects to a URI called the redirect URI, passing an authorisation code to the URI. There are special redirect URIs for OAUTH2 authorities which cause the authorisation code to be available in the browser window after the user agrees - you need to use these special redirect URIs to use the SMTPClientWorker.

  3. The user copies the authorisation code from the browser window, and pastes it into the application.

  4. The application uses the authorisation code, client secret, client id and redirect URI to make an HTTP request to the token URL. A successful call to this URL returns an access token, expiry information for the access token (how long it is valid) and a refresh token.

  5. The application uses the access token as the password.

As part of the process described above, the application stores the access token, expiry information, and refresh token in permanent storage. The next time the application needs to log on, the application reads this information. If the access token is probably still valid, based on the expiry information, the application uses it. If not, the application uses the refresh token to make a slightly different request to the token URL, in order to get a new access token, which it then stores and uses to log on. Note:

  1. If the log on fails using the saved access token (with an authentication failure), the application will then try to use the refresh token to obtain a new access token.

  2. The refresh token may be invalidated by the authority at some point. For this, and various other reasons, log on may fail with an authentication failure. In that case, the application needs to return to the initial step of opening the browser window at the OAUTH2 authorisation code URL, so that it can obtain the user’s permission, and a new access token and refresh token.

OAUTH2 for SMTPClientWorker

This section describes how the OAUTH2 support for the SMTPClientWorker works.

Authority Configuration

Each authority has a folder with the authority name in the folder secure/oauth2/smtp, in the Omnis data folder. In the installed tree, there are folders for two authorities, and each folder includes a file called config.json; this is a JSON file that configures the authority for use with the SMTPClientWorker. The installed authorities, and their JSON files, are:

gmail:

{

"authURL": "https://accounts.google.com/o/oauth2/auth",

"tokenURL": "https://www.googleapis.com/oauth2/v3/token",

"proxyServer": "",

"scope": "http://mail.google.com/",

"redirectURI": "urn:ietf:wg:oauth:2.0:oob",

"clientID": "",

"clientSecret": ""

}

outlook:

{

"authURL": "https://login.live.com/oauth20_authorize.srf",

"tokenURL": "https://login.live.com/oauth20_token.srf",

"proxyServer": "",

"scope": "wl.imap,wl.offline_access",

"redirectURI": "https://login.live.com/oauth20_desktop.srf",

"clientID": "",

"clientSecret": ""

}

When using these authorities, you need to supply your client ID. You can optionally store your client secret here, or if you want to keep it in another more secure location, you can store it how you like, and then supply it to the SMTPClientWorker using the $clientsecret property.

The proxyServer only requires a value if your client system is using a proxy server; the SMTPClientWorker uses this when making HTTP requests to the token URL.

User Storage

The SMTPClientWorker stores the access token, expiry information, and refresh token for a user in the file <user>.info in the authority folder, where <user> is typically the email address of the authorising user. This file is a JSON file, that is automatically handled by the SMTPClientWorker, so you should not need to edit this file.

Application Logic

After you have configured the authority, to use OAUTH2 in your application with the SMTPClientWorker, there is only one additional step you need to code in your application. Essentially, this comprises:

  1. Opening a browser window at the OAUTH2 authorisation code URL.

  2. Accepting the pasted authorisation code.

  3. Calling $run or $start for a second time, this time also passing the authorisation code.

For example, in $completed:

If pResults.errorCode=kOWEBsmtpErrorOAUTH2authCodeRequired

  OK message {A browser window will open so that you can   authorize sending email.//Please follow the instructions and   then paste the authorization code into the following dialog...}

  Launch program ,[pResults.oauth2_authcodeurl]

  While len(lAuthCode)=0
    Prompt for input Authorization code Returns lAuthCode (Cancel button)
    If flag false
      Yes/No message {Are you sure you want to cancel?}
      If flag true
        Quit method
      End If
    End If
  End While
  Do $cinst.$start(lAuthCode)
End If

External Commands

Note the Web and Email external commands are obsolete and are no longer supported in Studio 10.x onwards: you should consider moving to the new OW3 Worker objects model. The following protocols were supported: HTTP, FTP, SMTP, POP3, and IMAP. The external commands are prefixed with the respective protocol name, e.g. HTTPSend, FTPConnect, etc.

The Web and Email external commands are not displayed in the Code Editor since the ‘Exclude Old Commands’ filter is selected in the Code Editor (if you select No Filter from the Modify menu they will be available); these commands are described in the Command Reference and the Omnis Help (press F1).

Multi-threading

The Web and Email external commands are multi-threaded, when running on a multi-threaded Omnis Server. The Web commands allow another thread to execute in the multi-threaded server while the current command runs. Note that the same socket cannot safely be used concurrently by more than one thread. See also the ‘SMTP Client Workers’ section for using email in multi-threaded environment.

MailSplit

If the encoding cannot be determined from the MIME, MailSplit uses $importencoding as the default encoding rather than UTF-8, provided that $importencoding is an 8 bit encoding, that is, anything except kUniTypeUTF16, kUniTypeUTF16BE and kUniTypeUTF16LE.

Email Headers

The SMTPSend and MailSplit commands support international characters in email headers (using RFC2047). The character limit of 76 for RFC2047 encoded words for mail headers has been removed in the MailSplit command.

SSL Security

The Web and Email external commands allow support for secure connections using Secure Sockets Layer (SSL) technology. However, Transport Layer Security (TLS) supersedes SSL and should be used in new development. Applications that require a high level of interoperability should support SSL 3.0 and TLS.

The HTTP, FTP, SMTP, POP3, and IMAP client commands that establish a connection to a server allow you to control if and how a secure connection is used. The commands which allow secure connections are:

FTPConnect IMAPConnect
HTTPGet POP3Connect
HTTPOpen POP3Recv
HTTPPost POP3Stat
HTTPSetProxyServer SMTPSend

The parameters Secure and Verify allow you to enable support for secure connections. The parameters behave as follows:

  1. Secure
    is an optional Boolean* parameter which indicates if a secure connection is required to the server. Pass kFalse for non-secure (the default). Pass kTrue (value 1) for a secure connection; this enables the Verify option.
    *In addition, you can pass value 2 to some of the commands to enable specific types of authentication. The SSL package installed on yours or the client’s system is used (Windows: Schannel, or macOS: Secure Transport). FTPS resumes the TLS session for data connections. In addition, it automatically sends PBSZ and PROT commands to the server after establishing a secure control connection

  2. Verify
    is an optional Boolean parameter which is only significant when Secure is not kFalse. When Verify is kTrue, the command instructs the SSL package to verify the server's identity using its certificate; if the verification fails, the connection will not be established. You can pass Verify as kFalse, to turn off the verification; in this case, the connection will still be encrypted, but there is a chance the server is an impostor.

For example, the FTPConnect command allows you to establish a secure connection to the specified FTP server; the full syntax of the command is:

FTPConnect (
serveraddr, username, password
[,port, errorprotocoltext,
secure
 {Default zero insecure;1 secure;2 use AUTH TLS},
verify {Default kTrue}])
Returns socket

where Secure is an optional Boolean parameter which indicates if a secure connection is required to the server. Pass kTrue for a secure connection. If you pass secure with the value 2, the connection is initially not secure, but after the initial exchange with the server, FTPConnect issues an AUTH TLS FTP command to make the connection secure if the server supports it (see RFC 4217 for details), followed by further commands necessary to set up the secure connection. Authentication occurs after a successful AUTH TLS command. Note that if you use either of the secure options, all data connections are also secure, and all data transfer uses passive FTP.

HTTPPage

The HTTPPage command has an additional parameter to allow you to ignore SSL. The full syntax of the command is:

HTTPPage (url[,Service|Port,pVerify]) Returns html-text

When passed as false, the pVerify argument prevents SSL verification when using a secure URL, so you can use:

HTTPPage (url,,kFalse)

SSL Packages

In order to use SSL or TLS in the Web and Email external commands the Secure Channel (Schannel) package on Windows, or Secure Transport on macOS must be installed on your development computer or a client’s computer: these are present by default on their respective platforms.

OpenSSL

Existing Users should note: The Web and Email external commands relied on OpenSSL in previous versions to provide secure communications. Support for OpenSSL has been removed for these commands and support for SSL and TLS relies on the built-in security for each platform.

If you have used OpenSSL to provide secure comms for these commands in existing applications, you will need to switch to using either Schannel or Secure Transport depending on what platform your app is running on.

Certificate Authority Certificates

In order to perform the verification (when the Verify parameter is kTrue), the SSL package uses the Certificate Authority Certificates in the cacerts sub-folder of the secure folder in the Omnis folder. If you use your own Certificate Authority to self-sign certificates, you can place its certificate in the cacerts folder, and the SSL package will use it after you restart Omnis.

Web Command Error Codes

Error codes marked with * are received in responses from the FTP server, and then returned as the result of FTP command execution.

Error Code Error Text
-501 Incorrect parameter type
-502 Error getting information about a parameter
-503 Incorrect number of parameters
-504 The command can only decode streams of characters (in a character variable)
-506 Unrecognised command
-507 Error locking handle
-508 Bad list generated by command
-509 Bad socket passed to command
-511 No address specified
-512 Could not open ICMP handle
-513 Could not start timer
-516 The end-user cancelled the request
-517 Bad option passed to TCPClose
-522 Timeout while waiting for response or request
-523 Badly formatted response from server
-524 Response from server is too short
-525 Response from server has incorrect syntax
-1010 Out of memory
-1012 Unix TCPPing requires a raw socket: only processes with an effective user id of zero or the CAP_NET_RAW capability are allowed to open raw sockets
-1013 Cannot do TCPPing on Win32 without icmp.dll
-1014 Attempt to perform secure operation on non-secure connection
-1015 Attempt to make an already secure connection secure
-1016 Cannot load wesecure.so/dll. Perhaps OpenSSL is not installed
-1017 A required function is missing from wesecure.so/dll
-1018 Cannot request a partial closure of a secure connection
-1019 Error setting up secure library threading
-1020 Error seeding Pseudo Random Number Generator
-1021 The OpenSSL library returned an error; call WebDevGetSecureError for more information
-1022 Invalid secure object passed to wesecure
-1023 Unknown error returned by OpenSSL library
-1024 Unable to get a suitable Omnis folder for CA certificates
-1025 Cannot open cacerts.pem
-1026 Cannot get find handle to list CA certificates
-1027 cacerts folder does not contain any CA certificates
-1028 Error getting next certificate file
-1029 Unable to open CA certificate
-1030 Wesecure initialization failed
-1031 Error establishing secure connection
-1032 Buffer overflow would occur because a field is too long
-1033 Not used
-1034 A connection time out
-1105* Need FTP account for storing files
-1106* Requested FTP action aborted: page type unknown
-1107* Requested FTP file action aborted. Exceeded storage allocation (for current directory or dataset)
-1108* Requested FTP action not taken. File name not allowed
-1109* Requested FTP action aborted: local error in processing
-1110* FTP file not found, or no access to file
-1116 Parameter passed to FTP command is too long
-1117 Parameter passed to FTP command contains invalid characters
-1119* FTP Restart marker reply
-1120* FTP serviceready in nnn minutes
-1121* FTP data connection already open; transfer starting
-1122* FTP file status okay; about to open data connection
-1123* FTP user name okay, need password
-1124* Unrecognised FTP positive preliminary reply
-1125* Unrecognised FTP positive intermediate reply
-1126* Unrecognised FTP transient negative completion reply
-1127* Unrecognised FTP permanent negative completion reply
-1129 Could not extract server IP address and port from response to FTP command PASV
-1130 FTP transfer type must be zero (for ASCII) or one (for binary)
-1131 FTP could not open local file
-1132 Error while FTP was reading or writing the local file
-1134* Need account for FTP login
-1135* Requested FTP file action pending further information
-1136* FTP service not available, closing control connection
-1137* Cannot open FTP data connection
-1138* FTP connection closed; transfer aborted
-1139* Requested FTP file action not taken. File unavailable (e.g., file busy)
-1142* Requested FTP action not taken. Insufficient storage space in system
-1143* Syntax error: FTP command unrecognized or too long
-1144* Syntax error in FTP parameters or arguments
-1145* FTP command not implemented
-1146* Bad sequence of FTP commands
-1147* FTP command not implemented for that parameter
-1148* Not logged in to FTP server
-1149* Unrecognised response from FTP server
-1150 Must use passive FTP when the connection is secure
-1151 FTP server response to AUTH TLS command does not allow a secure connection to be established
-1154 Unable to determine end of HTTP header
-1161 Incomplete HTML tag
-1180 Parameter passed to HTTP command is too long
-1181 Post with CGI parameters sends CGI parameters as content: cannot supply content-type/length header in header list
-1182 Received HTTP request is badly formatted
-1183 Received HTTP request does not contain the HTTP version
-1184 Received HTTP request contains badly formatted CGI parameters
-1185 Invalid HTTP status code - must be 1-999
-1186 The client HTTP application closed the connection
-1187 The client HTTP application did not send a Content-Length header
-1188 The maximum response size specified in the call to HTTPRead was exceeded
-1205 SMTP: 435 Unable to authenticate at present
-1206 The SMTP server does not support authentication
-1207 SMTP: 535 Incorrect authentication data
-1208 SMTP: 432 A password transition is needed
-1209 SMTP: 534 The authentication mechanism is too weak
-1210 SMTP: 538 Encryption is required for requested authentication mechanism
-1211 SMTP: 454 Temporary authentication failure
-1212 SMTP: 530 Authentication is required
-1213 Unexpected response from server during authentication
-1214 SMTP: OK Authenticated
-1215 SMTP: continue command
-1216 Required type of authentication (PLAIN or LOGIN) not supported by SMTP server
-1217 The response to the EHLO command could not be parsed
-1218 Parameter passed to mail command is too long
-1219 SMTP: Unrecognised response from SMTP server
-1220 SMTP: 211 System status, or system help reply
-1221 SMTP: 214 Help message
-1222 SMTP: 220 <domain> Service ready
-1223 SMTP: 221 <domain> Service closing transmission channel
-1224 SMTP: 250 Requested mail action okay, completed
-1225 SMTP: 251 User not local; will forward to <forward-path>
-1226 SMTP: 354 Start mail input; end with <CRLF>.<CRLF>
-1227 SMTP: 421 <domain> Service not available, closing transmission channel
-1228 SMTP: 450 Requested mail action not taken: mailbox unavailable [E.g., mailbox busy]
-1229 SMTP: 451 Requested action aborted: local error in processing
-1230 SMTP: 452 Requested action not taken: insufficient system storage
-1231 SMTP: 500 Syntax error, command unrecognized
-1232 SMTP: 501 Syntax error in parameters or arguments
-1233 SMTP: 502 Command not implemented
-1234 SMTP: 503 Bad sequence of commands
-1235 SMTP: 504 Command parameter not implemented
-1236 SMTP: 550 Requested action not taken: mailbox unavailable
-1237 SMTP: 551 User not local; please try <forward-path>
-1238 SMTP: 552 Requested mail action aborted: exceeded storage allocation
-1239 SMTP: 553 Requested action not taken: mailbox name not allowed
-1240 SMTP: 554 Transaction failed
-1241 Error decoding quoted printable or base 64 encoded data
-1242 Body part list is inconsistent - cannot build MIME content
-1244 POP3: error received from server
-1245 POP3: could not extract message size from response to LIST command
-1246 POP3: message received from server is too large (does not match size in LIST command response)
-1260 IMAP: invalid response received from server
-1261 IMAP: invalid tag received from server
-1262 IMAP: invalid greeting message received from server
-1263 IMAP: connection rejected by server (BYE received in greeting message)
-1264 IMAP: the server does not support plain or CRAM-MD5 authentication
-1265 IMAP: the server does not support the STARTTLS command, so a secure connection cannot be established
-1266 IMAP: the server response to the CAPABILITY command was incorrect
-1267 IMAP: the server must support IMAP4rev1, but it does not indicate that in its CAPABILITY response
-1268 IMAP: the server response to the STARTTLS command was incorrect
-1269 IMAP: parameter passed to command is too long
-1270 IMAP: login was rejected because the user name or password was incorrect
-1271 IMAP: the server response to the LOGIN command was incorrect
-1272 IMAP: the server response to the LOGOUT command was incorrect (network connection has been closed)
-1273 IMAP: the secure parameter to IMAPConnect is invalid
-1274 IMAP: the server response to the AUTHENTICATE CRAM-MD5 command was incorrect
-1275 IMAP: error decoding base64 response to AUTHENTICATE CRAM-MD5 command
-1276 IMAP: the server response to the LIST or LSUB command was incorrect
-1277 IMAP: the server response to the SELECT command was incorrect
-1278 IMAP: missing output list parameter
-1279 IMAP: the server response to the SUBSCRIBE command was incorrect
-1280 IMAP: the server response to the UNSUBSCRIBE command was incorrect
-1281 IMAP: the server response to the STORE command was incorrect
-1282 IMAP: the server response to the RENAME command was incorrect
-1283 IMAP: the server response to the EXPUNGE command was incorrect
-1284 IMAP: the server response to the DELETE command was incorrect
-1285 IMAP: the server response to the CREATE command was incorrect
-1286 IMAP: the server response to the COPY command was incorrect
-1287 IMAP: Incorrect FETCH response message sequence number when listing messages
-1288 IMAP: the server response to the FETCH command was incorrect when listing messages
-1289 IMAP: No flags returned in FETCH response when listing messages
-1290 IMAP: No size returned in FETCH response when listing messages
-1291 IMAP: No UID returned in FETCH response when listing messages
-1292 IMAP: Flags in response are not terminated by close parenthesis
-1293 IMAP: Invalid integer value in FETCH response when listing messages
-1294 IMAP: FETCH response not terminated with close parenthesis when listing messages
-1295 IMAP: No INTERNALDATE returned in FETCH response when listing messages
-1296 IMAP: INTERNALDATE returned in FETCH response when listing messages is not correctly enclosed in double quotes
-1297 IMAP: FETCH response incomplete
-1298 IMAP: the server response to the FETCH command was incorrect when receiving a message or headers
-1299 IMAP: bad message length in FETCH response
-1300 IMAP: unrecognized data item in response when FETCHing message or headers
-1301 IMAP: the server response to the NOOP command was incorrect
-1302 IMAP: the server response to the CHECK command was incorrect
-10004 Socket error: Interrupted function call
-10009 Socket error: Bad file descriptor
-10013 Socket error: Permission denied
-10014 Socket error: Bad address
-10022 Socket error: Invalid argument
-10024 Socket error: Too many open files
-10035 Socket error: The command would block
-10036 Socket error: Operation now in progress
-10037 Socket error: Operation already in progress
-10038 Socket error: Socket operation on non-socket
-10039 Socket error: Destination address required
-10040 Socket error: Message too long
-10041 Socket error: Protocol wrong type for socket
-10042 Socket error: Bad protocol option
-10043 Socket error: Protocol not supported
-10044 Socket error: Socket type not supported
-10045 Socket error: Operation not supported
-10046 Socket error: Protocol family not supported
-10047 Socket error: Address family not supported by protocol family
-10048 Socket error: Address already in use
-10049 Socket error: Cannot assign requested address
-10050 Socket error: Network is down
-10051 Socket error: Network is unreachable
-10052 Socket error: Network dropped connection on reset
-10053 Socket error: Software caused connection abort
-10054 Socket error: Connection reset by peer
-10055 Socket error: No buffer space available
-10056 Socket error: Socket is already connected
-10057 Socket error: Socket is not connected
-10058 Socket error: Cannot send after socket shutdown
-10059 Socket error: Too many references; cannot splice
-10060 Socket error: Connection timed out
-10061 Socket error: Connection refused
-10062 Socket error: Too many levels of symbolic links
-10063 Socket error: File name too long
-10064 Socket error: Host is down
-10065 Socket error: No route to host
-10066 Socket error: Directory not empty
-10067 Socket error: Too many processes
-10068 Socket error: Too many users
-10069 Socket error: Disk quota exceeded
-10070 Socket error: Stale NFS file handle
-10071 Socket error: Too many levels of remote in path
-10091 Socket error: Network subsystem is unavailable
-10092 Socket error: WINSOCK.DLL version out of range
-10093 Socket error: Successful WSAStartup() not yet performed
-10101 Socket error: Graceful shutdown in progress
-11001 Lookup error: Host not found
-11002 Lookup error: Non-authoritative host not found
-11003 Lookup error: This is a non-recoverable error
-11004 Lookup error: Valid name, no data record of requested type