Server Protocol

This page presents the classes and functions of the BaseX Clients, and the underlying protocol, which is utilized for communicating with the database server. A detailed example demonstrates how a concrete byte exchange can look like.

Workflow

 * All clients are based on the client/server architecture. Hence, a BaseX database server must be started first.


 * Each client provides a session class or script with methods to connect to and communicate with the database server. A socket connection will be established by the constructor, which expects a host, port, user name and password as arguments.


 * The execute method is called to launch a database command. It returns the result or throws an exception with the received error message.


 * The query method creates a query instance. Variables and the context item can be bound to that instance, and the result can either be requested via execute, or in an iterative manner with the more and next functions. If an error occurs, an exception will be thrown.


 * The create, add, replace and store method pass on input streams to the corresponding database commands.


 * To speed up execution, an output stream can be specified by some clients; this way, all results will be directed to that output stream.


 * Most clients are accompanied by some example files, which demonstrate how database commands can be executed or how queries can be evaluated.

Transfer Protocol
All Clients use the following client/server protocol to communicate with the server. The description of the protocol is helpful if you want to implement your own client.

Conventions

 * : single byte.
 * : utf8 strings or raw data, suffixed with a  byte. To avoid confusion with this end-of-string byte, all transfered   and   bytes are prefixed by an additional   byte.

Digest
Digest authentication is used since Version 8.0:


 * 1) Client connects to server socket
 * 2) Server sends a realm and nonce, separated by a colon:
 * 3) Client sends the user name and a hash value. The hash is composed of the md5 hash of
 * 4) the md5 hash of the user name, realm, and password (all separated by a colon), and
 * 5) the nonce:
 * 6) Server replies with   (success) or   (error)

CRAM-MD5
CRAM-MD5 was discarded, because unsalted md5 hashes could easily be uncovered using rainbow tables. However, most client bindings still provide support for the outdated handshaking, as it only slightly differs from the new protocol:


 * 1) Client connects to server socket
 * 2) Server sends a nonce (timestamp):
 * 3) Client sends the user name and a hash value. The hash is composed of the md5 hash of
 * 4) the md5 of the password and
 * 5) the nonce:
 * 6) Server replies with   (success) or   (error)

Clients can easily be implemented to both support digest and cram-md5 authentication: If the first server response contains no colon, cram-md5 should be chosen.

Command Protocol
The following byte sequences are sent and received from the client (please note that a specific client may not support all of the presented commands):

Query Command Protocol
Queries are referenced via an id, which has been returned by the QUERY command (see above).

As can be seen in the table, all results end with a single \00 byte, which indicates that the process was successful. If an error occurs, an additional byte \01 is sent, which is then followed by the error message string.

Binding Sequences
Also sequences can be bound to variables and the context:


 * empty-sequence must be supplied as type if an empty sequence is to be bound.
 * Multiple items are supplied via the  argument and separated with \01 bytes.
 * Item types are specified by appending \02 and the type in its string representation to an item. If no item type is specified, the general type is used.

Some examples for the  argument:


 * the two integers 123 and 789 are encoded as 123, \01, 789 and \00 (xs:integer may be specified via the  argument).
 * the two items xs:integer(123) and xs:string('ABC') are encoded as 123, \02, xs:integer, \01, ABC, \02, xs:string and \00.

Example
In the following example, a client registers a new session and executes the INFO database command. Next, it creates a new query instance for the XQuery expression 1, 2+'3'. The query is then evaluated, and the server returns the result of the first subexpression 1 and an error for the second sub expression. Finally, the query instance and client session are closed.


 * Client connects to the database server socket
 * Server sends realm and timestamp "BaseX:1369578179679": ◄ 42 61 73 65 58 3A 31 33 36 39 35 37 38 31 37 39 36 37 39 00
 * Client sends user name "jack": 6A 61 63 6B 00 ►
 * Client sends hash: md5(md5("jack:BaseX:topsecret") + "1369578179679") = "ca664a31f8deda9b71ea3e79347f6666": 63 61 36 ... 00 ►
 * Server replies with success code: ◄ 00
 * Client sends the "INFO" command: 49 4E 46 4F 00 ►
 * Server responds with the result "General Information...": ◄ 47 65 6e 65 ... 00
 * Server additionally sends an (empty) info string: ◄ 00
 * Client creates a new query instance for the XQuery "1, 2+'3'": 00 31 2C 20 32 2B 27 33 27 00 ►
 * Server returns query id "1" and a success code: ◄ 31 00 00
 * Client requests the query results via the RESULTS protocol command and its query id: 04 31 00 ►
 * Server returns the first result ("1", type xs:integer): ◄ 52 31 00
 * Server sends a single \00 byte instead of a new result, which indicates that no more results can be expected: ◄ 00
 * Server sends the error code \01 and the error message ("Stopped at..."): ◄ 01 53 74 6f ... 00
 * Client closes the query instance: 02 31 00 ►
 * Server sends a response (which is equal to an empty info string) and success code: ◄ 00 00
 * Client closes the socket connection

Constructors and Functions
Most language bindings provide the following constructors and functions:

Session

 * Create and return session with host, port, user name and password:


 * Execute a command and return the result:


 * Return a query instance for the specified query:


 * Create a database from an input stream:


 * Add a document to the current database from an input stream:


 * Replace a document with the specified input stream:


 * Store raw data at the specified path:


 * Return process information:


 * Close the session:

Query

 * Create query instance with session and query:


 * Bind an external variable: The type can be an empty string.


 * Bind the context item: The type can be an empty string.


 * Execute the query and return the result:


 * Iterator: check if a query returns more items:


 * Iterator: return the next item:


 * Return query information:


 * Return serialization parameters:


 * Return if the query may perform updates:


 * Close the query:

=Changelog=


 * Version 8.2


 * Removed: WATCH and UNWATCH command


 * Version 8.0


 * Updated: cram-md5 replaced with digest authentication
 * Updated: BIND command: support more than one item


 * Version 7.2


 * Added: Query Commands CONTEXT, UPDATING and FULL
 * Added: Client function context(String value, String type)