Operations Quick-Start Guide General Information Release Notes FastCGI, NSAPI, ISAPI
Scripting Template Language Template Commands Server-side JavaScript Standard Templates &
URL Codes
Product Features WebX/Distributed WebX/Multi WebX/Chat Direct Access Protocol

Visit the Web Crossing Conference to find a wealth of WebX info and a community of WebX experts on the Web!

Web Crossing Server-side JavaScript

Table of Contents

Overview

Processing an HTTP Request

Object-Oriented Database

Global Functions and Properties

Helper Objects

Remote Procedure Calls


» Overview

Web Crossing supports built-in server-side JavaScript 1.5. You can use JavaScript to totally customize Web Crossing, to write your own dynamic Web pages, and to process Web-based forms.

Web Crossing's JavaScript environment is specifically designed to build Web pages. Each request from a Web browser can be served by a combination of HTML text and JavaScript functions.

Special objects are provided to access the incoming request, work with input form variables, and produce a response page. You have total control over the response, including the ability to easily forward to another location, set cookies, and so on.

Web Crossing's JavaScript environment is nicely coupled to its built-in database, giving you access to a user directory and to hierarchical, extensible, object-oriented data items. (If you prefer, you can use external services for persistent storage. You are never required to exclusively use the tools built into Web Crossing.)

» JavaScript function library

You can pre-load any number of JavaScript functions, so they are immediately available for processing any request. This allows you to build your own function library of JavaScript objects, and to initialize these objects. It provides very high performance by caching pre-compiled scripts and objects.

Pre-loaded JavaScript functions can be used to process Web-Crossing-specific requests, or to define your own dynamic pages.

A file named webx.tpl is used for pre-loaded JavaScript functions. This file can include any number of function definitions and initialization functions.

The syntax for JavaScript functions in the webx.tpl file is

A "command" or "function" statement in a webx.tpl file results in a JavaScript function being pre-compiled for later use. A command can be used in a URL, while a function can only be called internally. (You can have any number of commands or functions, and any number of lines of code, between the %%...%% delimiters.)

For example, here is the classic "Hello world" application written in JavaScript for Web Crossing:

(Note that this uses command instead of function, so that this JavaScript function can be used directly to process incoming URLs.) You would get to this function by issuing a URL in your Web browser:

where "...webx" is the URL to access your Web Crossing server, "hello" is the command for Web Crossing to execute (our "Hello world" function).

» Including server-side JavaScript files

You can include files into webx.tpl by using the following directive:

where filename is the file to include. You must use this syntax exactly: spaces, capitalization, and all.

It is often convenient to use separate files for each new JavaScript object or set of related functionality.

» Shorthand for appending to the response page

When you are using server-side JavaScript, you often need to append text to the response page. Web Crossing provides a shorthand notation for doing this.

Any JavaScript statement that starts with a plus sign (+) is evaluated as an expression and then appended to the response page. That is, the statement

is the same as writing

» Mixing HTML and JavaScript code

In Web Crossing, you can embed HTML text directly into JavaScript functions, by just enclosing this text between %% delimiters (as %%...HTML text...%%). Embedded text is automatically translated into the appropriate JavaScript calls to append the text to the response page. For example,

is evaluated as if it was

All embedded text is automatically escaped and quoted correctly for JavaScript compilation.

In addition, you can use the \ character to suppress the end-of-line characters, so you can break up long HTML lines into smaller pieces for readability. Leading tabs are stripped from text lines, again so you can write readable HTML. For example, the text

would evaluate to a single line of text in the output, just as if you had written this as

In large, complex pages, it is very convenient to be able to define the page as a JavaScript function, and then drop in the specific server-side JavaScript as needed. For example, something like the following:

This function inserts conditional text depending on the value of the form's "accept" field, and uses another JavaScript function to insert the correct location for a gif image.

» Initialization and pre-defined classes

The normal sequence for loading template files is as follows.

  • Load the webx.tpl file, and replace all includes with their text, to any level. This defines all of the JavaScript functions/command and Web Crossing Template Language (WCTL) macros to be evaluated.

  • Evaluate all of the JavaScript functions/commands and WCTL macros, in the order defined.

  • Execute all init init functions, in the order defined. Any function name starting with "init_" is run after all of the webx.tpl functions have been compiled.

    This means that you can use an init_ function to pre-build an object class, adding functions and data constants to the constructor's prototype. For example,

    Init_ functions are evaluated in the order they are defined.

    A global propery named libraryGlobal is available to reference the global context that is copied to become the intial global object for each incoming request.

    » Variable scope

    Variables are resolved in the same manner in Web Crossing's JavaScript environment as they are in client-side JavaScript, with one significant difference: Web Crossing always resolves variables in the current global scope, instead of the global scope where the function was defined. This automatically gives each request its own private set of variables, so that multiple requests can be processed in parallel.

    In practice, this means that you can use global variables as desired, and each request will have its own set of gobals.

    The following table shows a more detailed outline of variable resolution in Web Crossing, compared to client-side usage.
    Resolution stepsWeb Crossing usage (server-side)Browser usage (client-side)
    First If the variable is defined in a var statement, it is local to the current execution of the function and is read/write.Same.
    Second Lookup the variable as a property of the current function. Same.
    Third Lookup the variable in the current request's global scope. These variables are read-write. Lookup the variable in the window in which the function was defined. These variables are read-write.

    » Grouped JavaScript functions

    In the Web Crossing Template Language, you can create nested macros, and then specify the top-level macro as the customization template for a folder or discussion. For example,

      %% macro style1 %% %% macro folder %% ... folder layout for style1 %% endmacro %% %% macro discussion %% ... discussion layout for style1 %% endmacro %% %% endmacro %%
    In effect, the top-level style1 macro just groups together some nested macros and functions that are used when this style is applied to a folder or discussion.

    With JavaScript functions, you can use the same structure:

      %% macro style1 %% %% command folder { ... folder layout for style1 } %% %% command discussion { ... discussion layout for style1 } %% %% endmacro %%
    With this format, if the "style1" macro is applied to a folder, its style1.folder() and style1.discussion() functions will be used to lay out that folder and its items.

    Functions grouped in this manner are placed into JavaScript container objects that correspond to the macro grouping. In the example above, the full names of the functions would be

      style1.folder and style1.discussion

    » Mixing JavaScript and WCTL

    You can mix JavaScript and WCTL: you can call JavaScript functions from WCTL, and you can call WCTL macros from JavaScript, per the following sections.

    JavaScript and WCTL can both set properties of stored objects, and pass data to each other this way. However, WCTL cannot reference any JavaScript types except strings. In other words, if WCTL accesses a path.var that was stored by a JavaScript "node.var = value;" statement, the WCTL program will get the correct value if it is a string, but will get the empty string as the value for any other JavaScript type.

    » Calling JavaScript from WCTL

    To call JavaScript functions from the Web Crossing Template Language, use

      string.jsEval
    to evaluate a JavaScript script. For example,

      %% "1+2".jsEval %%
    will call JavaScript and evaluate to "3". All JavaScript results are converted to strings by jsEval. If jsEval is terminated by a JavaScript error, then the evaluation will return the empty string. You can use

      %% jsError %%
    to get any error message. If you want to evaluate a JavaScript expression and get either the result or any JavaScript error message, use

      string.jsEvalOrError

    » Calling WCTL from JavaScript

    To call WCTL from JavaScript, use

      wctlEval( expression ) or wctlEvalTemplate( template )
    For example,

      wctlEval( "1+2" ) will return "3", wctlEvalTemplate( "xxxx %" + "% 1+2 %" + "%" ) will return "xxxx 3"
    Note that you cannot say

      wctlEval( "xxxx %% 1+2 %%" )
    directly because the "%%" in the string will be evaluated as switching mode between JavaScript and HTML text.

    » Debugging

    The initial parse of the webx.tpl file will append any errors to the webx.log file.

    Run-time errors will return the page to the point of the error, followed by the error message and a stack trace. You sometimes need to do a "View as source" in order to see the error messages.


    » Processing an HTTP Request

    Incoming URLs can call a JavaScript function directly, or can be processed by a JavaScript function indirectly during Web Crossing's evaluation of the URL command.

    A JavaScript function must be enabled to respond to incoming URLs.

    Each incoming request is run in its own private global context. The global properties are:

    requesttop-level object, default scope for variables. For example, "request.certificate" is the same as "certificate"
    top during initialization, top is the same as libraryGlobal. During request processing, top is the same as request.
    responseByteBuffer accumulating the response page to return to the browser
    cgiobject with a string property for each CGI variable
    formobject with a string property for each input-form field
    useruser for current session
    location the Node object specified in the location parameter of the URL, or null if none if none
    locationArray array of parents for the location object, with location as the last element.
    sitecurrent global site settings
    topLevelFoldertop-level folder for the site
    sessionobject with read/write property strings for the current user's persistent session information
    certificatecertificate string for the current user/session
    errorsome methods indicate errors by setting this error message. It is the error from last such command, or null for no error

    » Enabling JavaScript functions to serve URLs

    JavaScript functions cannot normally serve URLs. In order to have a JavaScript command serve URLs, you must either:

  • set the property urlEnable to true. For example,
      function myLookup(){ ... } function init_myLookup(){ myLookup.urlEnable = true; // Enable URL processing }
  • or use the keyword command instead of function. command is exactly the same as function, except that it also sets name.urlEnable. For example,
      command myLookup(){ ... }
    enables myLookup to serve incoming URL-based commands.

    » URL syntax

    For direct execution of a JavaScript command, the syntax of the URL is

      .../webx...?functionName@certificate@location!formName=value&...
    where

    .../webx...?directs the URL to the Web Crossing server, however this is configured.
    functionNameis the name of the JavaScript function or method
    certificateis the optional certificate for this session (WCTL automatically keeps track of user and per-session variables, see the following discussion of the "session" object.)
    locationis an optional location in the WCTL object-oriented database (OODB)
    formName=valueis an optional list of input fields. Each formName and value must be URL quoted.

    If the location has a method with the specified functionName, then that method is called. This is the same as

      var n = Node.lookup( "location" ); n.functionName();
    If there is no location, or it does not have a matching method, then the function is called.

    If there is no method or function with the right name, then an error message is displayed.

    » request

    The request object is the same as the top-level global scope. It provides a way to reference top-level variables from any function, regardless of local variables.

    For example, request.certificate is the same as certificate unless there is a local variable named "certificate".

    » response

    The response object is used to build the response Web page. The response is a ByteBuffer, which means that it is a modifiable, variable-length array of bytes.

    To add HTML text to the response page, just use

    You can also append text to the response by just inserting it into your JavaScript program inside %%...%% pairs, as

    You can also append text to the response by putting a plus sign as the first character of a JavaScript statement, as

    All of the ByteBuffer methods and properties work with the response page, so you can clear the output and start over, search or modify text already placed into response, etc.

    To embed URLs for Web Crossing functions, see the built-in command makeUrl.

    The final response value will direct Web Crossing to take appropriate action:

    response pageaction
    non-empty response, not starting with HTTP/ This is a normal HTML page, and Web Crossing will automatically generate the HTTP header for the response. (Responses to a Web browser are an HTTP header, a blank line, then the page itself. So if you provide the page, Web Crossing will provide the HTTP header and blank line.)
    response starting with HTTP/ Whenever a response page evaluates to text starting with HTTP/, that page is returned as is, without adding the standard HTTP response heading. For example, the following function forwards the incoming request to <http://mysite.com/test.html>.
      %% function forward {
        response.append( "HTTP/1.0 302 Redirect" );
        response.crlf(); 
        response.append( "Location: http://mysite.com/test.html" );
        response.crlf();
        response.crlf();
      } %%
    This is because HTTP/1.0 302 Redirect has a response code of 302, which asks the browser to temporarily forward the original URL to a new location.

    Note that the forwarding response must end with a final blank line, because this blank line marks the end of the response HTTP header. The page itself, following this blank line, is empty.

    empty response page Web Crossing assumes that the user needs to login before this function can run correctly, and will return a login page. After the user successfully logs in, the current function will be reexecuted with the same input-form values.

    » cgi

    The cgi object is a read-only list of properties from the incoming request. "cgi" stands for "Common Gateway Interface" -- this is the standard interface between a Web server (Web Crossing) and the program that is processing the request.

    You can enumerate the available properties. For example, the following function will show a list of cgi properties:

    Typical cgi properties and their use are:

    cgi propertyuse
    query_stringThe query string from the incoming URL, the portion following the first question mark in the URL.

    This string is URL-quoted, so the query string from the request "http://test.webcrossing.com/webx?showCgi@@" becomes a cgi.query_string of "showCgi%40%40".

    To remove the URL-quoting, use cgi.query_string.fromUrl().

    script_nameIncoming request, following the server domain and before any question mark and query string.

    For example, the request "http://test.webcrossing.com/webx?showCgi@@" has a cgi.script_name of "/webx".

    httpsSet to "on" if the request is via a secure SSL connection, otherwise is not defined.
    http_RefererThe URL of the page that contained the link to the current request
    http_User_AgentType of client browser, such as "Mozilla/4.05 (Macintosh; U; PPC, Nav)"
    http_ConnectionType of connection, such as "Keep-Alive"
    http_HostDomain name or IP address of the host serving this request, such as "www.webcrossing.com"
    http_AcceptThe mime-types that the browser will accept, such as "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*"
    http_Accept_LanguageLanguages that the browser will accept, such as "en" for English
    http_Accept_CharsetCharsets that the browser will accept, such as "iso-8859-1,*,utf-8"
    request_methodRequest type, "GET" or "POST"
    remote_addrIP address of the client Web browser, such as "1.2.3.4".
    server_nameDomain name or IP address of this server, such as "test.webcrossing.com".
    url_schemeIf you need to know whether a request came in over a secure SSL connection or not, use cgi.url_scheme. In direct web-service mode, this will be "https" for a secure connection, or "http" for a non-secure connection. For FastCGI mode, this will be set per the originating server, so may be missing or null; instead of url_scheme, Apache servers set https if the request was over an SSL connection. In CGI mode, no information is available.

    Note that cgi properties starting with "http_" are fields from the incoming HTTP heading. So "http_xxxx" properties are whatever the client browser has sent. Properties without an "http_" prefix are provided by the server and are known to be valid.

    » form

    The form object is a read-only list of form input fields. There is one property for each form input variable or named value in the incoming URL.

    For example, if the incoming URL is

    then You can enumerate the properties of the form to list all of the input fields.

    If the same field is input more than once, form.inputField is the last one. Using the last value allows you to set defaults using hidden fields, as in

    This usage will always provide a value for form.myCheckBox. If the checkbox is checked, then both myCheckBox=false and myCheckBox=true will be sent by the browser, which will result in a "true" value from form.myCheckBox. If the checkbox is not checked, then only myCheckBox=false is sent by the browser, which will result in a "false" value from form.myCheckBox.

    When a post is done in multipart MIME format, you can access the header component of each value through the Mime.formHeader() function.

    » user

    This is the current user for the request. It is a User object, and has all the information about the current user.

    » location

    This is the location in the Web Crossing database from the incoming request, or null. See the discussion of Node objects.

    » locationArray

    This is an array of parent Nodes for location, or null if location is null.

    locationArray[0]Same as topLevelFolder
    locationArray[...]Intermediate parents
    locationArray[locationArray.length-1]Same as location

    » site

    The site object has information about the Web Crossing site, including settings and global site variables. This is a Site object.

    » topLevelFolder

    The topLevelFolder object is a Folder object, the top-most Folder for the site.

    » session

    The session object is a read-write set of properties that are preserved across requests from the same browser. This object provides a convenient way to manange state information for an ongoing session.

    The properties of a session can only have string values. You can enumerate over these properties.

    In order for an incoming request to have the same session as an earlier request, the certificate component of the URL must be the same as for the earlier request. This means that you should dynamically generate all session-linked URLs as

    » certificate

    The certificate object is a string that is the certificate for the current session. Use this certificate in all links in order to have the current user and session preserved across requests.

    » error

    Some commands, such as new Folder( parent, title ) will return a null object if there was an error. The error message is saved in this global error string. If there is no error, then error is set to null.


    » Object-Oriented Database (OODB)

    Web Crossing includes an object-oriented database. This database is organized into a hierarchy of named Folders, each containing nested Folders, Discussions, Chat rooms, and Links. Any object that can be added to a Folder is a "Node" object.

    Discussions contain Messages, which are accessible as either a chronological conversation or a hierarchy of threaded messages.

    At the lowest level, there are primitive Stored objects. These are the same as a JavaScript Object, except that they are stored into the database.

    All objects stored in the OODB can be accessed through JavaScript objects. Setting new property values for stored objects stores the values into the OODB and saves them on disk. Fetching values from stored objects loads them from disk automatically.

    You can create your own kinds of objects derived from the built-in classes, giving you an extremely powerful tool for extending and customizing Web Crossing.

    » Defining New Classes of Objects

    You can derive your own classes from any Stored object class.

    For example, suppose you wanted to define an "auction item". You decide to derive this from the built-in Node object, because you want auction items to be listed in a folder. So, just define an AuctionItem constructor and its init logic:

      function AuctionItem( folder, title, ...){ // Constructor function for AuctionItem // AuctionItem objects inherit from Node ...init a new auction-item object as appropriate } function init_AuctionItem(){ // Initialization for the AuctionItem class // (called one time at startup because its name starts with "init") // AuctionItem objects inherit from Node, accomplished // by setting AuctionItem.prototype to be a // newUnattached Node object: AuctionItem.prototype = Node.newUnattached(); // Other inits for AuctionItem.prototype: ...attach default properties and methods to AuctionItem.prototype; }
    Now you can create new AuctionItem objects by

      var obj = new AuctionItem( folder, title, ... );

    Now new AuctionItem objects can use all of the built-in Node and Stored methods and properties, plus all of the default properties and methods that you assign to AuctionItem.prototype.

    When a previously created AuctionItem object is referenced, it is automatically loaded from the OODB as necessary, with the correct class.

    You can use the same technique to define your own object classes based on any built-in object class: Stored, Node, Folder, Discussion, Message, Chat, Link, or User.

    This is an extremely powerful technique for creating new kinds of objects and extending the Web Crossing environment.

    » Stored Object

    Stored objects are the primitive building blocks for making your own objects and classes of objects. The Stored class is the foundation for all persistent objects. Its properties and methods are inherited by all stored objects.

    A Stored object can hold any primitive JavaScript data-type: null, strings, numbers, booleans, and Dates, and can also hold other stored objects. (Storing any other kind of object will generate a run-time error.) For example,

      var s = new Stored(); s.date = new Date(); s.reminder = form.reminder; user.reminder = s;

    This code will create a new Stored object, save the current date/time and a "reminder" from the input form, and save this into the current user's record. All of this information is available later:

      if( user.reminder != null ){ // Now user.reminder.date is the date the reminder was created // And user.reminder.reminder is the reminder message text ...process reminder; }

    By default, all non-built-in property values are automatically stored into the OODB. You can specify that some properties are local (not stored at all) or transactional (stored by storedCommit).

    Properties and methodsUsage
    Stored.lookup( id ) Looks up an existing Stored object and returns it.

    id is a string which is either a pathname in the OODB folder hierarchy, or the s.storedUniqueId label for some object.

    This method will return an object with the same type that it was created with, as long as that type is available in your current JavaScript templates. (If the correct type is not available, then the type will be the underlying type of the original object, such as Folder, Node, Stored, etc.)

    If the object could not be located in the OODB, then returns null and sets error.

    Stored.newUnattached() Returns a new unattached Stored object, suitable for deriving new classes from Stored.
    storedIsAttachedReturns true if the stored object is attached to the OODB
    storedUniqueIdReturns the uniqueId string for a stored object. This can be used in a later Stored.lookup( id ).
    storedDetach()detaches a JavaScript Stored object from the OODB.
    storedConstructor(read-only) the name of the constructor for the class (from the OODB, so if this class does not exist in the current run-time, then the default base constructor was used)
    storedSetConstructor( newType )Changes the type of an object in the OODB. newType is a string that is the name of the constructor function for the new class. Detaches the old object, and returns an object of the new type.
    storedIsLocal( propName )Returns true if propName is for a local property (e.g. not stored into the OODB).
    storedIsTransact( propName )Returns true if propName is for a transaction-type property (e.g. stored into the OODB on command).
    storedIsAuto( propName )Returns true if propName is for an auto-stored property (e.g. stored into the OODB).
    storedMakeLocal( propName )Makes the specified property to be local
    storedMakeTransact( propName )Makes the specified property to be transaction-oriented
    storedMakeAuto( propName )Makes the specified property to be auto-stored
    storedCommit()Saves all modified transaction-oriented properties into the OODB
    storedRollback()Reverts all transaction-oriented properties to the old value from the OODB
    storedIsFolderReturns true if the stored object is also a Folder
    storedIsDiscussionReturns true if the stored object is also a Discussion
    storedIsMessageReturns true if the stored object is also a Message
    storedIsNodeReturns true if the stored object is also a Node
    storedIsChatReturns true if the stored object is also a Chat
    storedIsLinkReturns true if the stored object is also a Link
    storedIsUserReturns true if the stored object is also a User
    storedIsStoredArrayReturns true if the stored object is also a StoredArray
    OTHERSall other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)

    » StoredArray Object

    StoredArray objects are just like standard JavaScript Array object, except that they are stored in the Web Crossing object-oriented database. StoredArrays are based on the Stored object, so they inherit all the methods and properties of Stored objects.

    A StoredArray object is an array of any primitive JavaScript data-type: null, strings, numbers, booleans, and Dates, and can also hold other Stored objects. (Storing any other kind of object into a StoredArray will convert it to a string and store the string.) For example,

      var s = new StoredArray(); s[0] = new Date(); s[1] = form.reminder; user.tracking = s;

    This code will create a new StoredArray object, save the current date/time and a "reminder" from the input form, and save this into the current user's record.

    » Node Object

    Every location in the Web Crossing pathname hierarchy is derived from the Node class. So all of the following properties and methods are available for Folders, Discussions, Messages, Chat rooms, and Links.

    You can create Node objects and place them into Folders, and you can derive your own classes from the Node class.

    Properties and methodsUsage
        -- Static Functions --
    new Node( parentFolder, title ) creates a new node with the specified title. parentFolder can be a Folder object or a pathname string.
    Node.lookup( pathname )Returns the object located by the specified pathname. Same as Stored.lookup( id ).
    Node.lookupArray( pathname ) Returns an array of parents of the specified pathname, with the specified item the last one in the array. The first item in the returned array is always the top-level folder.
    Node.newUnattached()Returns a new unattached Node object, suitable for use as a prototype in a class definition.
        -- Properties --
    nodeAuthoruser who posted this location
    nodeBackgroundbackground for non-message items (if "", then inherited from its parent)
    nodeChildren(not implemented) Array of child nodes
    nodeDateCreateddate this location was created
    nodeDateModifieddate this location was modified
    nodeFooterfooter for non-message locations (if "", then inherited from its parent)
    nodeHeaderbanner for non-message locations (if "", then inherited from its parent)
    nodeName-- note: rarely used, see nodeTitle, nodePathname, and storedUniqueId -- unique name of an item in its parent Folder. This is the same as the nodeTitle for Folders. nodeName is read-only. Successfully setting nodeTitle for a Folder will also change the Folder's nodeName. The nodeName for a non-Folder object is a string with an integer value (e.g. 0, 1, ...) that is unique in the parent folder.
    nodeOwnerDocumentTop-level folder node
    nodeParentparent Folder or null for the top-level Folder object
    nodePathnameFull pathname for this node. Each component of the pathname is URL-quoted, separated by "/" delimiters.
    nodeShowAuthortrue to show the author of this location
    nodeTemplatetemplate envelope for this location
    nodeTitletitle of the item. The title is the same as nodeName for Folders. Because a Folder's title must be unique, setting nodeTitle for a folder may not work. For all other Node objects, setting nodeTitle will always work.
    nodeUrlURL for this location, using current session certificate, etc
    nodeValuedata for folder/discussion heading, or message body
    OTHERSall other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)
        -- Display --
    nodeDestroy()destroys an open folder, discussion, message, chat, link, or container
    nodeDisplay()constructs the display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method just calls this.nodeDisplayHeader, this.nodeDisplayContent, and this.nodeDisplayFooter
    nodeDisplayHeader()constructs the header for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method puts up the initial <HTML> tag and heading, a <BODY> tag, and the standard banner for the page, the title and backpath.
    nodeDisplayContent()constructs the content area for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method doesn't display anything.
    nodeDisplayFooter( showToolbar )constructs the footer for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method displays <p> followed by the standard footing and closing BODY and HTML tags.

    showToolbar is optional and defaults to true. If set to false, then the default toolbar is not added by nodeDisplayFooter.

    nodeIcon( extra )<img...> tag for the default icon for this location. An optional parameter can be specified which is additional stuff to add to the tag.
        -- Structure --
    nodeMoveTo( toFolder )moves any non-Message object to a new Folder. Returns null if no error, or an error message string.
    nodeInsertBefore( newChild, refSibling )(not implemented)
    nodeReplaceChild( newChild, oldChild )(not implemented)
    nodeRemoveChild( child )(not implemented)
    nodeAppendChild( newChild )(not implemented)
    nodeHasChildren()(not implemented)
    nodeFirstChild()(not implemented)
    nodeLastChild()(not implemented)
    nodePreviousSibling()(not implemented)
    nodeNextSibling()(not implemented)
    nodeAddAttachment( a ) Add an attachment to a node object. The attachment must be formatted as MIME container, using CRLF line delimiters. It starts with a partial heading that must Content-Type and Content-Transfer-Encoding, and may include other header lines.

    The heading is followed by a blank line, followed by the data.

    For example, the following is a short text file attachement:

      Content-Type: text/plain Content-Transfer-Encoding: 8bit This is a text file attachement example body.
        -- Access Control --
    nodeHasAccessList returns true if the node has its own access list. Set this property to true to create an access list if there isn't one already, or to false to remove any existing access list.
    nodeUserAccess( user ) returns the user access to a node. The returned access is "host", "participant", "moderated", "readOnly", or "none". If the node does not have its own access list, then the parent's access list is used.
    nodeSetUserAccess( user, mode ) sets the user access to a node. The access mode can be "host", "participant", "moderated", "readOnly", or "none". If the node does not have its own access list, one is added automatically.
    nodeUserCanView( user ) returns true if the user can view this location.
    nodeUserCanPost( user ) returns true if the user can post to this location (this will return true even if the user posts are moderated).
    nodeUserIsModerated( user ) returns true if the user posts are moderated at this location.
    nodeUserIsHost( user ) returns true if the user is a host for this location.

    » Folder Object

    The Folder object can use all of the properties/methods of a Node object, plus the following.

    Properties and methodsUsage
    new Folder( parentFolder, title ) creates a new folder with the specified title. parentFolder can be a Folder object or a pathname string.
    folderChild( ix ) returns folder nested objects by index (ix is [0..folderChildCount-1]). Returns null if there is no such child or ix is >= folderChildCount.
    folderChildCount the number of children in the folder (read only)
    folderNewsgroup newgroup name, also used as email username for email posts

    » Discussion

    The Discussion object can use all of the properties/methods of a Node object, plus the following.

    Properties and methodsUsage
    new Discussion( parentFolder, title ) creates a new discussion
    discussionChildCount the number of message slots in the discussion, including any deleted or moved messages (read only)
    discussionChild( ix ) returns nested messages by index (ix is [0..discussionChildCount-1]). Returns null if there is no such child or ix is >= discussionChildCount.
    messageIx always returns -1 for a discussion (read only)
    treeIx always returns -1 for a discussion (read only)
    treeChildCount the number of messages in the discussion, not counting deleted or moved messages (read only)
    treeChild( treeIx ) returns nested messages in threaded-message order by index (ix is [0..treeChildCount-1]). Returns null if there is no such child or ix is >= treeChildCount.
    treeParentIx always returns -1 for a discussion (read only)
    treeNextSibIx always returns -1 for a discussion (read only)
    treePrevSibIx always returns -1 for a discussion (read only)
    treeDepth always returns -1 for a discussion (read only)

    » Message Object

    The Message object can use all of the properties/methods of a Node object (except where noted), plus the following.

    Properties and methodsUsage
    new Message( parentDiscussion[, title] ) appends a new message to parentDiscussion
    new Message( parentMessage[, title] ) makes a new hierarchical message under parentMessage
    messageIx returns the message index in conversational order, 0 origin (read only)
    treeIx the message index in threaded-message order, 0 origin (read only)
    treeChildCount the total number of nested messages in threaded-message order, not including any deleted or moved messages (read only)
    treeChild( treeIx ) returns nested messages in threaded-message order by tree-index in the discussion (ix is [0..discussion.treeChildCount-1]). Returns null if there is no such child or ix is >= discussion.treeChildCount.
    treeParentIx the tree-index of the parent message in threaded-message order, 0 origin (read only)
    treeNextSibIx the tree-index of the next sibling in threaded-message order, 0 origin, or -1 if no next sibling (read only)
    treePrevSibIx the tree-index of the previous sibling in threaded-message order, 0 origin, or -1 if no next sibling (read only)
    treeDepth the nesting depth of this message in threaded-message order, 0 for top-level messages (read only)
    messageExists tells whether a message exists or not (deleted or moved message return false). Setting this property to false will delete a message. Once deleted, the message cannot be "undeleted".

    » Message Object

    The Message object can use all of the properties/methods of a Node object (except where noted), plus the following.

    Properties and methodsUsage
    new Message( parentDiscussion[, title] ) appends a new message to parentDiscussion
    new Message( parentMessage[, title] ) makes a new hierarchical message under parentMessage

    » Chat Object

    The Chat room object can use all of the properties/methods of a Node object, plus the following.

    Properties and methodsUsage
    new Chat( parentFolder, title ) creates a new chat room
    chatIsAnonymous true if the chat room allows anonymous users
    chatTables list of tables in a room (includes self)

    » Link Object

    The Link object can use all of the properties/methods of a Node object, plus the following.

    Properties and methodsUsage
    new Link( parentFolder, title ) creates a new link
    linkShowDescription true if the link description (nodeValue) is show in the folder listing
    linkUrl location in the current site or URL to another site

    » User Object

    The User object is derived from the Stored object, so all of the Stored methods and built-in properties are available.
    Properties and methodsUsage
    new User( name )creates a new user with the specified name.

    If there is an error, null is returned, and error is set to an error message.

    User.setUser( user ) Changes the current logged-in user as specified. Also installs a new certificate for the user, or switches to the previously assigned one if present and current. Sets error to indicate results of the switch.
    User.open( userId ) Returns the User object for the user with the specified id.

    Opens the user from either its u.userId string, which is the same as a WCTL user-id, or from its u.storedUniqueId string.

    If there is an error, null is returned, and error is set to the error message.

    Note that the WCTL/u.userId userId values are different from the u.storedUniqueId strings.

    User.lookup( username ) Returns the User object for the user with the specified name.

    If there is an error, null is returned, and error is set to the error message.

    User.loggedIn( only, exclude, sort, max, getRemoteAddr ) Get information about currently logged-in usrs. Returns an object containing a property "users". This property is an array object that is a list of logged in User objects.

    only : an optional user, or an array of users, or a string of userIds, that are the only ones to return. Default is all logged in users.
    exclude : an optional user, or an array of users, or a string of userIds, to exclude from the returned list. Default is to exclude no users.
    sort : an optional string specifying the sort sequence. This can be "user.userFirst", "user.userLast", or "none". Defaults to "user.userFirst".
    max : maxium number of users to return, default is unlimited
    getRemoteAddr : true to add remoteAddress, an array of strings, to the returned object. This is useful in deciding whether a login is a duplicate or not (if from a different IP, then it is a duplicate login)

    User.guest Returns the user ID for a guest user. You can use this ID for setting and checking user access to a particular location.
    User.other Returns the user ID for "other registered users". You can use this ID for setting and checking user access to a particular location.
    storedXxxall of the Stored properties and methods are available for User objects
    user2ndLinesecond line of info
    userApopuser APOP password (stored as clear text)
    userAuthenticate( passwd )returns true if passwd is the correct clear-text password for a user
    userBiouser bio
    userEmailemail address for user
    userEmailCodeemail code for user validation
    userForwardToemail address to foward mail to, or "" for no forwarding
    userHomepageuser's home page URL
    userIsRegistered(read-only) true if the user is registered (i.e. is not a special user ID such as User.other, and is not a guest user)
    userIsSysop(read-only) true if the user has sysop priviledges
    userNameuser's name, as First Last
    userPassworduser's password. Set in clear text, read as MD5 hash
    userIdunique WCTL user-id string to use in a WebX URL or as a parameter to User.openWctl. (This is because the original WCTL unique-id-space for users is different than the Stored.storedUniqueId. So Stored.lookup( user.storedUniqueId ) will return the user object, just as User.openWctl( user.userId ) will return the same user. But user.storedUniqueId is not the same as user.userId.)
    userDestroy()destroys the user, removing it from the member directory and all user groups. Existing messages created by this user will still reference the deleted user record.
    OTHERSall other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)

    » Site Object

    Properties and methodsUsage
    siteImagesbase URL for image graphics, such as "http://your.site/Images". Does not include a final slash (/).
    sitePictSizeButtonwidth and height for standard-sized buttons, such as "WIDTH=68 HEIGHT=30"
    siteUsePop3true if POP3 service is enabled
    siteUrlBaseURL base for Web Crossing commands
    OTHERSall other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)


    » Global Functions and Properties

    The Web Crossing JavaScript environment includes global functions for evaluating Web Crossing Template Language (WCTL) expressions.

    Global Functions and PropertiesUsage
    libraryGlobal this is the "library" object copied to become the initial global object for each request.
    top during initialization, top is the same as libraryGlobal. During request processing, top is the same as request.
    wctlVar( varname ) returns a WCTL variable value, either as a string or an integer depending on the type of the variable. For example, wctlVar( "myVar" ).
    setWctlVar( varname, value ) set a WCTL variable. If the value is an integer-valued number, then the WCTL variable is set to an integer, otherwise it is set to a string. For example, setWctlVar( "myVar", 100 ).
    makeUrl( command, parameter ) returns a Web Crossing URL for command. This command is a shorthand for
      (site.siteUrlBase+"abc@"+certificate+"@"+parameter)
    If parameter is omitted, then it defaults to the incoming location. For example,
      makeUrl( "abc" )
    is the same as
      (site.siteUrlBase+"abc@"+certificate+"@"+location)
    email( rcptList, message, return ) sends an email message to a recipients list.

    Note that the email sent does not go though the EmailHandler filters; if this email is for a local user, it will be delivered regardless of any EmailHandlers.

    rcptList is a list of <username@domain>,....

    message is a fully-composed email message with a header, body, and CR-LF linebreaks. The To header in the message is totally independent of the rcptList of destinations -- To: can be anything, it is not actually used to deliver the message.

    return is the email return address, the address that undeliverable mail is sent to (the MAIL FROM: SMTP parameter). If this is not specified, then it is taken from the message From: header field. Messages must have a return address; if you don't specify it in the email call, and there is no From: field in the message header, then the email will not be sent. Specifying the return address allows you to use Email functions to automate handing of bounced messages.

    EmailHandler Allows SSJS functions to handle incoming email. SSJS functions are email-enabled by storing them into the global EmailHandler object. For example,
      EmailHandler.support = MySupportEmailHandler;
        // Handles all email sent to "support" and "support.xxxx"
    Basically, you can attach a SSJS function to an email address prefix, so that incoming email with a matching address is handled by calling this function. For example, you could email-enable a function named "support" and have all incoming email addressed to "support" or "support.otherstuff" be processed by your email handler. Mail is delivered in the following manner:

    (1) Incoming email is first handled by checking for an email filter. The EmailHandler properties are checked for an all-lower-case property matching the incoming name. The longest match up to but not including a period in the incoming name is used. Note that you have to use

      EmailHandler["support.abc"] = function; // Due to period in mailbox name
    For example:
      incoming         matches
      ---------        -----------------
      Support@         support (but not supportx or support_abc)
    
      support.abc@     support or support.abc (but not support.abcd)
                       If both support and support.abc are present, it
                       matches support.abc

    (2)If there is an EmailHandler.All, this function is called unconditionally to handle all other email.
    (3) The user database is checked. If there is a match, then that user receives the mail.
    (4) If there is an EmailHandler.Unknown property (with upper-case "U"), then it is used to process the mail.
    (5) Otherwise, the mail is rejected as being undeliverable.

    Email handler functions

    An email handler is called as

      handler( rcptArray, message, from )
    where
    rcptArrayis an array of recipients for the message (from the SMTP RCPT commands for this message)
    messageis the actual message (from the SMTP DATA, with period-style escapes removed). The message is the full header and body. Use the Mime function to parse/manipulate the message.
    fromis the "from" address (from the SMTP MAIL FROM: command). This is the address to which returned mail is sent.
    fileAppend( filename, data ) appends data to a file. If the file does not exist it is created.
    queueWctl( macro, msecs-or-date, param0, param1, user ) queues a WCTL macro for later execution. Returns a string ID for this queued entry, that can be used to kill the queued function. For example,
      id = queueWctl( "myFunction", 1000 )
    will queue myFunction to run in 1 second.

    macro is the name of a WCTL macro.

    msecs-or-date is either a delay in milliseconds or an absolute Date() object that specifies when to run the queued macro. If ommitted, the queued macro is run as soon as possible.

    Note that the millisecond delays are not extremely accurate, so it is a good idea to delay for shorter periods, perhaps every hour, then delay one last time for the remaining period (less than 60 minutes) before an event trigger, or to use an exact Date() specification.

    param0, param1 are optional parameters. These values are converted to strings and are available as queueWctlParam( 0 ) and queueWctlParam( 1 ).

    user if specified, the queued macro will be run for this user. Otherwise, the queued function will be run with no user installed.

    You can call a JavaScript function from WCTL. For example,

      %% function testQueueStart(){ // queue testQueueWctl to run in 1 second queueWctl( "testQueueWctl", 1000, "abc" ); } %% %% macro testQueueWctl %% %% // queue WCTL macro, just calls a JS function %% %% "testQueue".jsEval %% %% endmacro %% %% function testQueue(){ // Just appends the first parameter to testFile fileAppend( "testFile", queueWctlParam( 0 ) ); } %%
    queueWctlParam( ix ) returns queued function parameter strings, 0/1 for param0/param1.
    queueWctlKill( ID ) kills the queued function, no effect if this function is no longer queued (either because it has run or has been killed previously).
    wctlEval( str ) returns result of evaluating "str" as an expression in WCTL
    wctlEvalTemplate( str ) returns result of evaluating "str" as a template in WCTL
    allowDeny( ip, allowDenySpec, maxMsecs )returns boolean, true if the ip is allowed.

    ip may be either a domain name or an absolute IP in dotted format, such as 123.4.5.6. Note that actual IP addresses are used, so if the incoming domain name cannot be resolved, this function will return false even though the input domain-name-string would appear to match the allowDeny spec.

    allowDenySpec is a list of patterns separated by commas or white space. Each entry in the list has the format

      a=allowPattern  -or-
      d=denyPattern
    where pattern is an IP address with optional "*" wildcards. For example, "a=*" will allow all IP addresses; "d=*" will deny all addresses, and "a=127.22.33.*" will allow all address with the specified first three bytes.

    The allow-deny list is processed in order, attempting to match the calling IP address. The first entry matching the calling IP is used to either accept or deny the connection. Denied connections are shut down without any notice.

    If the last entry in the allow-deny list is an allow, then there is an implicit d=* added to the end; if the last entry is a deny, then there is an implicit a=* added. If the list is empty, it is the same as "a=*"

    If any allow-deny entries include alphabetic characters, and the reverse-DNS lookup of the IP address is available, then the reverse-DNS will be checked against the patterns as well.

    maxMsecs is the maximum time to delay while doing domain-name and/or reverse-domain-name lookups, it defaults to 2 seconds.


    » Helper Objects

    The Web Crossing JavaScript environment provides a number of standard objects to help in customizing a Web Crossing site, serving dynamic pages, and processing input forms.

    There are also some extensions to standard JavaScript objects to assist with server-side operations.

    » ByteBuffer Object

    A ByteBuffer implements a modifiable array of bytes (instead of JavaScript's Unicode strings). Using a byte array means that a output page can be constructed exactly as it will be served, without any translation between Unicode and the byte stream required for Web pages.

    A ByteBuffer is used for the output response buffer, but these objects can also be created and used for other purposes.

    Properties and methodsUsage
        -- new ByteBuffers --
    new ByteBuffer()Creates a new empty ByteBuffer
    new ByteBuffer( initialValue )Creates a new ByteBuffer whose initial value is as specified.
        -- length --
    length(read/write) the current length of the ByteBuffer
        -- string compares, NOT case sensitive --
    eqNc( obj )returns true if the obj string of ByteBuffer is equal
    ltNc( obj )returns true if the obj string of ByteBuffer is less-than obj
    leNc( obj )returns true if the obj string of ByteBuffer is less-than-or-equal obj
    gtNc( obj )returns true if the obj string of ByteBuffer is greater-than obj
    geNc( obj )returns true if the obj string of ByteBuffer is greater-than-or-equal obj
    neNc( obj )returns true if the obj string of ByteBuffer is not-equal obj
        -- string compares, case sensitive --
    eq( obj )returns true if the obj string of ByteBuffer is equal
    lt( obj )returns true if the obj string of ByteBuffer is less-than obj
    le( obj )returns true if the obj string of ByteBuffer is less-than-or-equal obj
    gt( obj )returns true if the obj string of ByteBuffer is greater-than obj
    ge( obj )returns true if the obj string of ByteBuffer is greater-than-or-equal obj
    ne( obj )returns true if the obj string of ByteBuffer is not-equal obj
        -- access --
    byteAt( ix )number
    charAt( ix )string
    substring( ix [, count] )string
    subString( ix [, count] )same as substring
    subBuffer( ix [, count] )ByteBuffer
    duplicate()returns a copy of the ByteBuffer
        -- modify/parse --
    newValue( obj )sets the ByteBuffer to a new value, and returns the modified ByteBuffer
    append( obj )appends a string to the ByteBuffer, and returns the modified ByteBuffer
    appendByte( number )appends a character where "number" is the numeric value of the character, and returns the modified ByteBuffer
    set( ix, obj )sets the character at "ix", and returns the modified ByteBuffer. Uses first character of obj.toString(), or is a no-op if obj is a 0-length string
    setByte( ix, number )sets the character at "ix" where "number" is the numeric value of the character to store, and returns the modified ByteBuffer
    insert( ix, obj )inserts obj.toString() at "ix", sliding the character at "ix" and all following characters down to make room, and returns the modified ByteBuffer
    insertByte( ix, number )insterts a single character at "ix", and returns the modified ByteBuffer, slides down following bytes
    remove( ix [, count] )removes characters from ix through ix+count-1, and slides the following characters up. Returns the modified ByteBuffer
    head( [delimiter] )returns ByteBuffer to left of delim (default is space), removes the head and delimiter from the buffer
    tail( [delimiter] )returns ByteBuffer to right of delim (default is space), removes the tail and delimiter from the buffer
    toLowerCase()converts ByteBuffer to all lower-case, returns the modified buffer
    toUpperCase()converts ByteBuffeer to all upper-case, returns the modified buffer
    translate( mapByteBuffer )remaps ByteBuffer, each char in ByteBuffer is replaced by mapByteBuffer( byteAt[ix] )
    none()returns NULL (used to have a series of appends, etc evalutate to NULL
        -- URL and SGML quoting --
    toUrl()converts the ByteBuffer to be URL-quoted and returns the modified buffer
    fromUrl()converts the ByteBuffer to be URL-dequoted and returns the modified buffer
    toSgml()converts the ByteBuffer to be SGML-quoted and returns the modified buffer
    fromUrl()converts the ByteBuffer to be SGML-dequoted and returns the modified buffer
        -- hashing --
    toMD5()calculates the MD5 hash of the ByteBuffer and returns the modified buffer
        -- character appends --
    crlf()append carriage return, line-freed characters (CR/LF are the standard Internet end-of-line)
    cr()append a CR character
    lf()append a LF
        -- lookup --
    indexOfNc( obj [, ix [, count]] )not case sensitive, returns start index or -1
    indexOf( obj [, ix [, count]] )case sensitive, returns start index or -1
    lastIndexOfNc( obj[, ix [, count]] )not case sensitive, returns last start index or -1
    lastIndexOf( obj[, ix [, count]] )case sensitive, returns last start index or -1

    » Date Object

    The following methods have been added to the standard JavaScript Date object.

    Properties and methodsUsage
    format( formatSpec ) formats the JS Date per a WCTL time/date format string (as local time). See below for formatSpec syntax.
    formatUtc( formatSpec ) same as format() except as UTC/GMT

    For example,

      date.format("Www, D2 Mmm Y4 H4:I2:S2 G$MTtoutc")
    will return something like
      "Tue, 16 Feb 1999 13:06:05 GMT-0700"

    The date "formatSpec" is as follows. (Characters which are not format specifiers are copied into the output as literals.)

    » String Object

    The following methods have been added to the standard JavaScript String object.

    Properties and methodsUsage
    toSgml() returns string converted to SGML quotes
    fromSgml() returns string converted from SGML quotes
    toUrl() returns string converted to URL quotes
    fromUrl() returns string converted from URL quotes

    » MIME Processing

    The build-in Mime object provides a collection of useful routines for dealing with MIME (Multipurpose Internet Mail Extensions) envelopes.

    Mime.formHeader( "name" )returns the header for a form variable from a POST in multi-part MIME format, the same as the WCTL function formHeader. If the post was not in MIME format, or there is no form variable by this name, then returns null.
    Mime.getHeader( string )returns the header portion of a message in a MIME envelope (e.g. from a header, blank line, and body envelope)
    Mime.getBody( string )returns the body portion of a message in a MIME envelope
    Mime.unpackBody( string, boundary )unpacks a multi-part MIME body into an array of objects. The [0] element of the array is the data before the first boundary.
    Mime.getHeaderValue( string, name )Gets the value of a single header keyword
    Mime.unpackHeader( string )unpackes a MIME header, and returns an object with one property for each header keyword:value pair; the keyword is converted to lower case, and its value is the unfolded value from the header. Also, minus and underscore in the header names are exchanged, so that "Content-Type: text/html" becomes "content_type" with a value of "text/html".
    Mime.unpackValue( string )unpacks a MIME value (from a keyword:value header entry), and returns an object with one property for each value attribute. Attribute names are converted to lower case. The main value is stored into a property named "Value", with an upper-case "V". Also, minus and underscore in attribute names are exchanged, so that "x-application=abc" becomes the property name "x_application" with a value of "abc".
    Mime.packValue( obj )packs a header value-object back up.
    Mime.packHeader( obj )packs a header-object back up
    Mime.makeBoundary( obj )returns a unique boundary string for the body parts in the input array object
    Mime.packBody( obj, boundary )packs a multi-part MIME body back up from an array of part-messages and a boundary string
    Mime.packMessage( header, body )packs a header and body into a message


    » Remote Procedure Calls

    Web Crossing supports XML-based remote procedure calls, as defined by Www.XmlRpc.Com. This allows you to share resources from your Web Crossing server, and to let your Web Crossing server access shared resources from other servers.

    Note: in order to support XML-RPC, Web Crossing must be providing direct Web service. You can not pass XML-RPC calls through CGI or FastCGI interfaces.

    Remote procedure calls (RPCs) allow client programs to make calls to your Web Crossing server, with your server using the appropriate JavaScript functions to process these calls.

    You can also make remote procedure calls from Web Crossing's server-side JavaScript to any RPC-based server.

    This remote-procedure-call mechanism uses normal HTTP requests and responses, with special XML-based formatting of the body of the message to pass parameters and receive the returned value. All of the XML-RPC machinery is handled by Web Crossing, so you don't need to know the format of these calls to use it in Web Crossing.

    » Calling Remote Procedures

    To call a remote procedure, use

      rpc( url, function, p1, p2... )

    where:

    urlis the URL of the server that is going to process the procedure call. This can be a server address only (e.g. webcrossing.com), or it can be a full URL, including the remote pathname (e.g. http://webcrossing.com/RPC2).

    If the remote pathname is omitted, then /RPC2 is used, so specifying just a server address is the same as http://serveraddress/RPC2.

    To use SSL for the RCP connection, you must be running an SSL-enabled Web Crossing server, and specify https in the URL. For example, https://webcrossing.com/RPC2 would use HTTPS instead of HTTP. The default port for HTTPS is 443 and the default port for HTTP is 80.

    functionis the name of the remote function, such as mainResponder.discuss.newMessage.
    p1, p2...are optional parameters. Primitive values (strings, numbers, Dates) are passed exactly, except that null is passed as an empty string. ByteBuffers are passed as strings. Arrays are passed as arrays of values.

    All other objects are passed as primitive Objects, with all their enumerable properties passed to the remote procedure.

    returnsthe object passed back from the remote procedure. Returned values use the same rules as for sending parameters to the remote procedure. So returned values can be primitive values, or can be JavaScript Arrays or Objects.

    Any error in the call, or in the remote processing, will return a Fault object. This object has properties faultCode, a numeric error code, and faultString, a descriptive error message.

    » Processing Remote Procedure Calls

    You can process RPCs from any client by providing a JavaScript function and enabling that function for RPC handling. The parameters from the client are passed to your function, and the return value from your function is passed back to the client.

    To enable a function for RPC processing, just set

      myFunction.rpcEnable = true;

    The rpcEnable property can be either a boolean or a function. If this property is a function, then this rpcEnable function is called prior to executing the XML-RPC function, with the first parameter the function name and the following parameters the same as the XML-RPC function. The rpcEnable function can return one of the following:
    truethen the normal XML-RPC processing is done
    falsea "not enabled" fault is returned
    otherreturned to the caller instead of calling the normal XML-RPC function (e.g. "short-circuits" the normal XML-RPC call)

    You can return a Fault object if you detect some error in the request or during processing. To return a fault, just use

      return new Fault( errCode, errMsg );

    where errCode is a numeric error code (there is no standard, you just make them up for your usage), and errMsg is a descriptive error message.

    Checking the incoming request

    Sometimes you need to check that the incoming request is from a specific server, or is over a secure SSL connection. The JavaScript routine that processes the request can check the
    cgi built-in object as needed, this object is available during XML-RPC call processing just as it is for any incoming HTTP request.

    » Example

    Here is a sample RPC function that will be served from Web Crossing, and a sample test call to it. In this case, both the client making the RPC request, and the server processing it, are the same Web Crossing server -- Web Crossing is calling itself via the RPC mechanism. (This is much less efficient than just making a local call, but does illustrate how to use the machinery.)

      %% function testAdd( a, b){ // The RPC function: it just adds two numbers and returns the result return a + b; } command testRpc(){ // The test function: it makes a remote procedure call to testAdd() + "Should say 3: " + rpc( cgi.http_Host/*self*/, "testAdd", 1, 2 ); } function init_testRpc(){ // An init function: it enables testAdd to process RPC calls testAdd.rpcEnable = true; } %%

    To invoke the test function, copy this to your standard.tpl file, reset the webx.tpl cache, and use the URL

      ...webx?testRpc
    where ...webx is the access to your Web Crossing server.


    Copyright © 1996-2000 by Web Crossing, Inc., San Francisco, California.