Skip to content
Fetching latest commit…
Cannot retrieve the latest commit at this time.
..
Failed to load latest commit information.
README.md
unite.js

README.md

Unite API

Opera Unite Web server APIs

This API document describes the JavaScript bindings for the Opera Unite Web Server, available through Opera Unite applications. Opera Unite applications supply Web services served directly from the user's computer.

Opera Unite applications are packaged like Opera Widgets with a config.xml file.

Note that no methods in this API return actual arrays. Instead they return objects whose properties can be iterated over in an array style syntax, i.e. array[i]. Methods like push(), shift(), sort(), and so on are not available.

Enabling the Web server API

In order to make the file system and its methods available, you need to add a feature element to your config.xml file like this:

<widget>
  ...
  <feature name="http://xmlns.opera.com/webserver">
    <param name="servicepath" value="chat" />
  </feature>
  ...
</widget>

The servicepath parameter is required and defines the path the service will be accessed from. See the note on service URLs for more information.

The entry point to the API becomes available as a JavaScript object opera.io.webserver.

Opera Unite applications and URLs

Opera Unite users may start a Web server on different devices running Opera, for example on a home and work computer, a living room media center and a mobile phone. The user may install a set applications on each Web server, providing several services . A service is typically a single application, for example a file sharing service or a multiplayer chess service. Services can accessed on the following general URL:

http://device.user.proxy/service/path

For example:

http://work.john.operaunite.com/wiki/add

The username is the user's My Opera username.

The device name is whatever the user has chosen when enabling the Web server. It's tied to one instance of Opera.

The proxy is a server run by Opera, proxying requests between servers and clients.

The service, or service path, is the IRI name of the service, as defined in config.xml.

The path represents a file or instruction the service will handle.

Note that only valid IRI characters can be used as part of the device name, username and service name.

Working with requests and responses

The function of a Web server is to listen to requests from clients, process them and issue a response, for example send a Web page or the result of a script. Requests occur when the user visits a particular service URL. The request may contain form data, send via GET and POST and uploaded files.

In the case of the Opera Unite Web Server you listen to requests from clients by adding event listeners to the opera.io.webserver object:

opera.io.webserver.addEventListener('path',somehandler,false);

The path corresponds to the first path component in the URL after the service name, for example:

opera.io.webserver.addEventListener('add',addHandler,false);

In this case, if the user visits the URL

http://work.john.operaunite.com/wiki/add

The application will pick it up and call the supplied addHandler function.

Handler functions are passed a WebServerRequestEvent object as an argument. This event object gives access to the incoming connection (WebServerConnection), the incoming request (WebServerRequest), and the response (WebServerResponse) the author can write data to. The addhandler could look something like this:

function addHandler(e)
{
    //Shorthands
    var req = e.connection.request;
    var res = e.connection.response;

    //Get article from POST data
    var article = req.bodyItems['article'][0];

    //...Store the article data

    //Write a response back to the client
    res.write('Article updated');
    res.close();

}

Data sent as GET are available in the queryItems property of the request. Data sent as POST are available in the bodyItems property. The body of the request is also available in the raw form in the body property. If files were attached, these are available in the files property of the request.

The response object has methods for sending different kinds of data, for example writeImage() and writeFile().

You may supply a custom protcol string, status code and headers, but these must be set before data is written to the response.

Note that requests may not begin with '_', as this is reserved for special, system generated events.

Special requests: _index, _request, _close

The Web server supports three special requests.

_index
This request occurs when a user visits the root of the service, e.g. http://work.john.operaunite.com/share. If you do not listen for this request, the file public_html/index.html will be served when the user visits the root of the server.
_request
This is a special request that catches all incoming requests, except for _close. Use this to gain fine grained control of the requests made to the server. You'll need to use WebServerRequest.uri to differentiate between different requests. This request also catches _index, but not _close.
_close
This request occurs when a connection is closed. The connection property of the resulting event is a dummy object, while the id property contains the id of the closed connection.

If the developer adds event listeners for both _request and some specific path, the event handler for the specific path will be called before the _request handler. Handlers for _index are also fired before _request.

Redispatching requests

You can redispatch a request to a new URI by changing the WebServerRequest.uri property and calling the WebServerResponse.closeAndRedispatch() method. This is useful for example for correcting commonly mistyped URLs, chaining requests and providing authentication across the entire service. For example:


if ( ! authenticated )
{
  request.uri = opera.io.webserver.currentServicePath + 'loginform';
  response.closeAndRedispatch();
}

And headers, GET or POST data in the original request are sent along with the redispatched request.

Note that uri must be set to a relative URI path, starting with '/' and the name of the service (the opera.io.webserver.currentServicePath property), potentially followed by more path components, for example '/blog/add'.

If a request is redispatched, none of the special event handlers, like _request will be fired.

Requests and files

If an incoming request URI matches a shared file or a file in public_html, the file will be served.

However, if you listen for the _request event, even requests to files will be intercepted. In order to serve the file, you'll need to call WebServerResponse.closeAndRedispatch() without changing the URI.

Sharing files

You can share files from a local disk through your Web server. Use the opera.io.webserver.sharePath() and opera.io.webserver.unsharePath() methods. The first takes two arguments - a URL path and a File object retrieved using the File I/O API. The path denotes which sub-path of your service the file will be accessible on.

Here's an example:

//mount a directory using File I/O, get a reference to it called 'dir'
opera.io.webserver.sharePath('myShare', dir);

Assuming the device is called 'work', the user is called 'john' and the service is called 'fileSharing', the directory will now be available on the URL http://work.john.operaunite.com/fileSharing/myShare.

To unshare a path, call the opera.io.webserver.unsharePath() method with the path you've previously shared something on:

opera.io.webserver.unsharePath('myShare');

Note that for security reasons the contents of a shared directory is not listed automatically. If you visit the URL of a shared directory, you will get a 404 error code. You may still access files under the shared directory, for example:

http://work.john.operaunite.com/fileSharing/myShare/notes.txt

You'll need to listen for the name of the share as a request, and serve a listing to the client yourself.

If you do listen for the _request event to serve directory listings, you will also need to check for requests to files under a shared path. If you catch such references, you need to call WebServerResponse.closeAndRedispatch() without changing the WebServerRequest.uri property of the request to send the request back to the Web server. On the second pass, the Web server will serve the shared file directly.

Uploading files

You can upload files using a normal file upload form. Once uploaded, the file will be available in the WebServerRequest.files property. This is a special File object that functions like a directory. You can iterate through it to locate your uploaded file.

The File object and its children will be deleted when the request object goes out of scope. You must make sure to read it or copy it before this happens.

for ( var i = 0, file; file = request.files[i]; i++ )
{
    file.copyTo('/storage/' + file.name);
}

The value of the name property of the File object will be the same as the file name the uploaded file had on the user's disk.

Each uploaded file has a metaData property, which contains a dictionary of headers for that uploaded file.

Working with cookies

You can set cookies using the Set-Cookie header as you would for a normal Web page using the WebServerResponse.setResponseHeader() method:

response.setResponseHeader('Set-Cookie', 'session=' + seesionId );

The cookie will not be valid for any other domains, nor the admin subdomain. Setting the domain attribute does not override this. This means that if the current request is made out to the admin subdomain, setting a cookie in the response will set it for the admin subdomain.

If you do not specify a path, the Web server will set it to the path of the current service. Cookies are not shared among services.

Generating administration pages: The admin subdomain and WebServerRequest.isOwner

In order to allow administration of the service, the developer will need to be able to positively identify a user as the owner of the service. Administration pages can be accessed through the admin subdomain of the service.

The following URL pattern will be interpreted as an administration page:

http://admin.device.user.operaunite.com/path

For example:

http://admin.work.john.operaunite.com/fileSharing/

URLs on this form can only be accessed successfully from the same instance of Opera running the application. If it is accessed in any other way, for example through another browser, the user will be redirected to the non-admin version of the page.

In cases where a service page is successfully accessed through http://admin., the corresponding WebServerConnection object will have its isOwner property set to true. Developers can check this property and provide an administration interface:

if ( e.connection.isOwner )
{
    showAdminPage();
}

The admin page for the root service is special and may be used to provide admin-links to other installed applications. This service is integrated into Opera. It's available on the URL:

http://admin.work.john.operaunite.com/

When accessing service pages in the same instance, Opera will sometimes either ask the user to confirm the action or block the access. The reason for asking for a confirmation is to protect the user from malicious links which may result in cross-posting and destructive operations on the application. The table below summarized the different cases:

From page \ To Page Admin root, start URL Admin root, other URL Admin same service, start URL Admin same service, other URL Admin other service, any URL Non-admin, any URL
From panel, bookmarks or UI open open open open open open
From root admin, any URL open open open open open open
From service admin, any URL open block open open block open
From non-admin, locally hosted root (isLocal = true) open warning open warning warning open
From non-admin, locally hosted service (isLocal = true) warning warning open warning warning open
From regular page warning warning warning warning warning open

The start URL of a service or the root, is the minimal URL, ending in a slash, without path, filename, query arguments or hash.

If a warning is shown, and the user chooses to continue, any POST request is changed to a GET request.

In order to maintain security, the services will by default ignore requests for administration access from other instances or browsers. There is no native way of doing remote administration of applications. Developers can relax this model by implementing additional administration using authentication and nonces. It is not possible to access the admin subdomain through an IP address or through localhost, so the same applies in this case.

Author: Hans S. Toemmerholt, Web Applications, Opera Software ASA

JSDoc

Documentation can be generated with JSDoc (either version 2 or 3).

Something went wrong with that request. Please try again.