Services Kit is Going Well

Blog post by shisui on Sun, 2010-07-11 20:02

After a hard beginning due to some academic schedule conflicts, I have been looking on a proper implementation of the Services Kit among the others kits. Thanks to my mentor (Stephan Aßmus) and his useful remarks, I've designed what the base classes of the Kit will looks like.
Several things are taken into account while designing such classes : the ease of use from the developer point of view, efficiency of the code, strength of the binary interface, ... I'm more used to take benefits from an API rather than designing it, this Summer of Code is therefore very instructive for me, and I hope it will be useful for further network development !

Let's take a quick eye on what Services Kit looks like currently (click to view in a new window):

Service Kit diagram

This diagram contains the classes currently made, which are roughly what the network part of Services Kit will look like (excluding further BUrlProtocol child classes).

URL ?

The URL acronym stands for Uniform Resource Locator, that is to say it describes where one can find an object, and how to access it.
The BUrl class is here to represents such a URL, the developer can modify each field either directly with the SetXXX members or by parsing a URL string.
Did I said URL string ? The URL string is aimed to give all the necessary informations about a specific object. Almost all of us are used to handle these strings, via their web browsers for example. According to RFC 3986, the URL format is as follows :

         foo://example.com:8042/over/there?name=ferret#nose
         \_/   \______________/\_________/ \_________/ \__/
          |           |            |            |        |
       scheme     authority       path        query   fragment
 
BUrl can parse such an URL string, and explode it into the differents corresponding fields in order to make an URL usable programatically.

Cookies ? Yum yum !

Most of us have already heard about those delicious spies which let a website to track us and save our session ID, theme preference, and so on. And no, they can't convey viruses :-}.
In my original project proposal, cookies management was an optional part, but it quickly appears obvious that if I went to develop an HTTP client through the BUrlHttpProtocol class, cookie management wouldn't be an option, even if cookies are often not used in most web services implementation.
The cookies in Services Kit are represented by the BNetworkCookie class, which (again) let the developer to either parse a cookie string received from a server and fill the corresponding fields, or fill manually these fields, as described in RFC 2965.
BNetworkCookie is also able to determine if a cookie has to be deleted based on the "Expires" and "Max-Age" fields which tracks the time to live of a cookie.

BNetworkCookies are stored in a BNetworkCookieJar, himself stored in a BUrlContext. The cookie jar keeps track of every received cookie during a session and can be saved and later restored when needed, this allow, for example, to send authentification data on a bulletin board, save received cookies, and then access threads like if we were manually authenticated. This allow an application to act transparently like if it was a web browser.

The context

The BUrlContext class is a container keeping track of the environment resulting of the request made. Currently, it contains only a cookie jar, but it will eventually also contain a cache to allow faster requests over the Internet (principally for the HTTP protocol which greatly takes advantache of caching methods).
The context is globally the environment in which requests evolves, a single application can have multiple contexts and multiple applications can share a single context.

The most important

The most important part of the network part of Services Kit is certainly the BUrlRequest class, in fact it will be the most used public class for those who want to perform an URL request. The request initialize itself with an URL and identify either if it can handle the URL scheme via the protocol roster or if it can't perform the request.
The BUrlRequest class then launch a BUrlProtocol derived class which contain all the necessary logic to handle a request (over the network or not). Currently, the only protocol available is HTTP, which will handle 90% of requests since most web services are built over HTTP in order to ease client development.
The developer don't get access to most of the BUrlProtocol child classes directly, he rather call the public SetOption member to define some protocol related parameters and tweak the url protocol internals.

Synchonous and asynchronous events

The developer can, at contruction time, specify a listener for events emitted during the request processing. The listener members will be called at specific instants, such as "connection opened", "data received", "request end", ... which allow a synchronous notification between the url protocol and the rest of the application. An oberver is also available in order to have a asynchronous way to handle these notification.
To react to these events, the developer will only have to derive a class from BUrlProtocolListener and make his own mixture.

A result, finally!

When a request is fulfilled, the developer has a direct access to the request results via the BUrlResult class. This class contains the raw data received, and other informations when applicable (e.g: HTTP headers, ...). An app can therefore build his logic over the data received : this will also be the role of the Service Kit's data layer which will let the developer to extract informations in an XML tree or a JSON response for example.

The next steps

My further development concerning the Services Kit will be focused on the enhancement of the existing code, and on the data layer of the kit. By enhancement I mean the optimization of existing classes which will require a lot of efficiency in order to be widely used (e.g: the BNetworkCookieJar class which is currently using a BList of pointer to BNetworkCookie, a relatively slow method when looking for cookies corresponding to a specific URL across a thousand cookies).
Additionally, some features are not yet implemented, such as the protocol roster and the add-on interface, and are also on my todo list for the second part of the Summer of Code.

The API interface is likely to change during further development, and many things are to be moved or modified, I'm also open to every remarks or questions ! ;-)