|
Unite API | |||||||
| PREV NEXT | FRAMES NO FRAMES | |||||||
This document is the API Specification for Unite API.
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.
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 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.
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.
The Web server supports three special requests.
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._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.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.
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.
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.
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.
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.
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.
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.
| File Summary | |
| unite.js | Opera Unite Web server APIs |
|
Unite API | |||||||
| PREV NEXT | FRAMES NO FRAMES | |||||||