sexta-feira, 27 de julho de 2012

Media Server is deployed!

Finished the XEP-0070 implementation, the Media Server was ready to be deployed, and yesterday the first tests with Denis' HTTP API + Media Server were excellent! Some bugs, of course, but already fixed, and we are very excited with the result of our efforts.

Although, there are some improvements needed by the Media Server for the next couple of weeks:
- Handle video media previews;
- Handle clients with bare JIDs: the XEP-0070 negotiation with those clients needs to be done via XMPP messages;
- Handle audio media: set length property;
- Documentation.

quarta-feira, 25 de julho de 2012

Media Server user authentication - XEP-0070

XEP-0070 is a known specification of how verify HTTP requests via XMPP. It has basically 8 steps.

In the Media Server, when a HTTP request arrives, the HTTP side forwards the request to a AuthVerifier class, this class has control over an XMPP component, to send and receive packets in a synchronous way, via a SyncReplySend util class. Once the AuthVerifier class receives the request, it "asks" if the client has sent it, if yes, the request is authorized, if not, the HTTP side returns a 403 error.

Here is the sequence diagram:

To send its credentials, the client has two options:
  • Via HTTP auth: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 
  • Via URL: /media/test@topics.buddycloud.org?auth=QWxhZGRpbjpvcGVuIHNlc2FtZQ==
In both ways, the client's JID and transaction id, are separated by a ; and are base 64 encoded.

This week, we hope to do the first deploy, to finally see the Media Server running in a production environment!

quinta-feira, 19 de julho de 2012

Media Server Pub-Sub based authentication

As already cited at the GSoC's proposal, the Media Server would use pubsub capabilities to give/deny access a channel's media.

Although the concept is quite simple, and the necessary packets to trade such information between a client and a pubsub server, the biggest challenge was adapt the Smack API to the particularities from the buddycloud's XEP. The work was a lot easier because in the last year GSoC, another buddycloud's student (Abmar Barros) had to implement similar functionality  into his project, also using Smack.

So, to verify if an user like "rodrigo@buddycloud.org" can POST a media into "private@topics.buddycloug.org" all that the Media Server does is retrieve the channel's affiliations, and check if "rodrigo@buddycloud.org" has post capabilities:

<iq from="mediaserver@buddycloud.org/Client" id="Eq5j2-2" to="channels.buddycloud.org" type="get"> 
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner"> 
    <affiliations node="/user/private@buddycloud.org/posts"> 
  </affiliations></pubsub> 
</iq>

RESPONSE:

<iq from="channels.buddycloud.org" id="Eq5j2-2" to="mediaserver@buddycloud.org/Client" type="result">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <affiliations xmlns="http://jabber.org/protocol/pubsub#owner">
      <...>
      <affiliation jid="rodrigo@buddycloud.org" affiliation="publisher"/>
    </affiliations>
    <set xmlns="http://jabber.org/protocol/rsm">
      <first index="0">
        user1@buddycloud.org
      </first>
      <last>
        user5@buddycloud.org
      </last>
      <count>
        5
      </count>
    </set>
  </pubsub>
</iq>

What are the next steps?
- Fist I'd like to deploy a toy client to demonstrate some of the Media Server functionality;
- After that, the next step is the implementation of the XEP-0070 and documentation.

sexta-feira, 29 de junho de 2012

Media Server XMPP component

The main module from the Media Server is its XMPP component, it has several responsibilities, including the authentication process.

The authentication process that will be used is based on the XEP-0070, to illustrate how it would work, here is a sequence diagram:



As described on XEP-0070, the Media Server will provide two types of HTTP authentication, Basic and Digest, both requests user's login and password as authentication mechanism, in this way, the Media Server has to have a mechanism where it will verify the passed password.

The authentication response and authorization request are already implemented, the next steps are implement the verify password mechanism and request confirmation process.

edit: changed the sequence diagram after discussed some points with Kev.

quinta-feira, 14 de junho de 2012

GSoC 2012 - Everything seems to be flowing well

Last week I've faced some problems due to URL confusion, but, it was easily fixed changing a little the approach that I was taking in the resources implementation.

In resume, this is what was implemented this week:
  • All Media Server API methods without any kind of authentication. In this way, the whole defined actions (upload, update, download and delete) are working (in a very naive way, but still...);
  • Simple tests just to verify if everything is working in a minimum condition;
  • Documentation improvement at buddycloud's wiki;
  • A test suite, where we can run all test cases developed so far.
I also started the implementation of the other main Media Server feature, the XMPP component. It will be responsible to communicate with the buddycloud server and ask about users permissions based on pub-sub. I'm expecting a lot of tricky coding challenges in this phase :-D

Other interesting information is about the authentication process that I'm planning to use for the Media Server: http://xmpp.org/extensions/xep-0070.html
It is a well defined XEP about how to authenticate HTTP requests via XMPP. Denis, the other buddycloud's GSoC student, has started a very interesting discussion about how would work the HTTP Pub-Sub API and the Media Server together using the XEP cited above: https://groups.google.com/forum/?fromgroups#!topic/buddycloud-dev/5KOmqMKXEko

I'm planning to end the XMPP component in the next couple of weeks with the functionality of handling media for public buddycloud channels, this will allow a first 0.0.1 version deploy and further real tests. As usual, what I expect is to experience a lot of bugs and crashes, but not in everything (I hope so...).

sábado, 9 de junho de 2012

GSoC 2012 - Some specification changes

During the last two weeks, we decide to do some changes at the URLs definitions and the stored metadata of each media.

Now, the URLs are:

POST /media/<entityId>


PUT, DELETE, GET /media/<entityId>/<mediaId>


POST, PUT, DELETE, GET /media/<entityId>/avatar

Also we defined two query parameters, maxheight and maxwidth, in this way, if the client sends a request like

GET /media/lounge@topics.buddycloud.org/aksdh10201d?maxheigth=100&maxwidth=100

The returned media is a preview of " aksdh10201d " with dimensions that not exceed 100x100. It is assumed that the client will ask for previews of "thumbnailing" media, like images and videos.

Since /media/<entityId>/<mediaId> and /media/<entityId>/avatar can be confused by Restlet's router, I'm facing some problems due to that, I'm trying to figure out a solution that doesn't involve changing those defined URL templates.

Other significant change occurred at POST media request, now, the client should provide a multipart/form-data with 6 parameters:

  • uploadtoken: related to authentication process;
  • filename: the real name of the file (including its extension);
  • title: a title for the media (optional);
  • description: media's description;
  • author: the user that is uploading this file;
  • binaryFile: the file content.
The server response is a JSON representation of the uploaded media metadata:

{
   "id":"lETuJi8rPE4IfQrygN6rVtGx3",
   "fileName":"testimage.jpg",
   "author":"user@domain.com",
   "title":"Test Image",
   "mimeType":"application/octet-stream",
   "description":"My Test Image",
   "fileExtension":"jpg",
   "shaChecksum":"bc46e5fac2f1cbb607c8b253a5af33181f161562",
   "fileSize":60892,
   "height":312,
   "width":312,
   "entityId":"channel@topics.domain.com"
}

Next week, I'm planning to fix the URL confusion issue, and develop the first XMPP functionalities, like upload/download media from public channels.

sexta-feira, 25 de maio de 2012

GSoC 2012 - Coding has started!

Since May 21th, the Google of Summer 2012 has entered its coding period. After a lot of reading and documentation conception, we are finally doing the fun part =)

In this first week, I've implemented two methods for the Media Server HTTP API (with tests):

Once the main idea right now is prototyping, both methods doesn't have authentication yet, but is possible to publish the media server into a web server and have simple upload/download functions.

GET /channel/{channelId}/media/{mediaId}
POST /channel/{channelId}/media

Also, a JSON representation of the Media was defined:
{
  "id": string,
  "uploader": string,
  "title": string,
  "mimeType": string,
  "description": string,
  "uploadedDate": datetime,
  "lastViewedDate": datetime,
  "downloadUrl": string,
  "fileExtension": string,
  "md5Checksum": string,
  "fileSize": long,
  "length": long, // for videos
  "height": int, // for videos and images
  "width": int  // for videos and images
}

In this way, when a client tries to upload a media, it has to provide two fields at the multipart/form-data (more fields can be added later, for authentication as example). The body field, that will have the media json representation and the binaryFile field that will have the file content:

-----Aa1Bb2Cc3---
Content-Disposition: form-data; name="body"; filename=""
Content-Type: application/json; charset=UTF-8
{"fileExtension":"jpg","md5Checksum":"cd1b78e4686ae1a3cfb461a1085545f0","width":312,"uploader":"user@domain.com",
"downloadUrl":null,"id":"testFileId","fileSize":60892,"title":"testimage.jpg","height":312,"description":"a
description","length":null,"mimeType":"application/octet-stream","lastViewedDate":null,"uploadedDate":null}
-----Aa1Bb2Cc3---
Content-Disposition: form-data; name="binaryFile"; filename="testimage.jpg"
Content-Type: image/jpeg

...file content...

-----Aa1Bb2Cc3-----

When the server receives the file, it makes some verifications, like: MD5 checksum matching, file size matching, etc.

On the other side, we have the download method, it simple returns the requested file with the {mediaId} passed as argument.

The next steps are:
- Implement methods to upload/download channel's and user's avatars;
- Implement the XMPP component;
- Implement full upload/download for public channels functionality.