Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

SyncTab architecture. Part 1. Server.

This post is a continuation for my previous post with introduction to SyncTab. I'm going to describe SyncTab server application in this post.

Well, I had a desire to write a server application on python, but in result I wrote it on Grails. Why Grails? Because I was actively using it for more than a year to creating different web applications, including web API. And I knew that would be simple and fast to create such app with Grails and publish some sort of web service.

So server side is running on a single Amazon EC2 instance. Application is running under Tomcat. Nginx plays a role of proxy. MongoDB is used as a database, and mongodb grails plugin used to add MongoDB.

API is very simple. It's based on GET/POST requests and JSON result with a status flag and other values, like auth token, list of tags and links.

Some code sample:


/**
* Returns the list of last available tabs.
* Client can pass a "tabId" parameter with an id of the tab to get tags for.
*
* Returns:
*  - status: "true" if was removed, otherwise "false".
*  - tabs: an array of found tabs.
*/
def getLastTabs = {
if (request.method != 'GET') {
response.sendError 405
return
}

User user = session.user
Tag tag = getTagFromRequest()
RecentTabConditions conditions = new RecentTabConditions(user, tag, LAST_TABS_NUM)
List tabs = sharedTabService.getRecentSharedTabs(conditions)

render([status: true, tabs: prepareTabs(tabs)] as JSON)
}

An authentication token system is used in SyncTab. Each time user enters his username/password to login, a new authentication token is created and assigned to user. Auth token is invalidated after two weeks.

As both Android application and Chrome extension should support not only login but also registration, it is a part of API too. Actually, user related API contains only 4 functions: register, authenticate, logout and resetPassword.

There are more API functions related to sending/receiving links and view/edit the list of tags.

A short about tags. Tags is just a way to name the device. For example, user can create a tag for his home computer and another tag for work computer, and tags for phone and tablet. Each device/browser is subscribed only to one tag, and will receive and open only links sent with specified tag.

Server not only responsible for storing and fetching links by client applications, but also for preparing links for user. Usually, when user sends a link, information about it contains only name of the device, tag id and the link URL. Server is responsible to fetch the link title, description, favicon link and the final URL. The final URL may differ from sent URL. For example, user could send a link like http://bit.ly/xNPUeo, but user should see this link as http://blog.khmelyuk.com.

Well, looks like there is nothing interesting left that I would like to tell about SyncTab server application.

Ah, source code is not public, and I'm not planning to open source it soon. As VCS I'm using Git and BitBucket as hosting service.

SyncTab architecture. Part 0.

A few months ago I was willing to write my own android application. And I also had a need - a way to send easily links from my phone to my browser and vice versa. Well, my phone is under Android, and my favourite browser is Chrome. So I decided to create the app to satisfy my desire to create and release Android app and make my life easier.

And as result of this, I have made a set of applications that forms a SyncTab. Obviously, those applications are Android application, server-side application and Chrome extension.

This post is like a preface, and next few posts will include a short technical description of each application.

Well, the work of application is very simple: android app and chrome extensions are both clients for the server. There is no web interface for application. User can get the list of all sent links and manage them using Android application.

In most functionality, Android app and Chrome extension are similar. But the only way to see the list of sent links is using Android application.


Some links:

Facebook was failing to parse OG meta tags

Last week was having awful time fighting with strange work of Facebook. We had a page with OG meta tags and a Facebook Like button on the page. And Facebook was discarding to parse the page and extract data from OG meta tags. Using URL linter didn't help to find the problem but show the same information - page isn't parsed, OG meta tags are not used.

So I tried to check next things to find the issue:

  • whether property attribute in used <meta/> tags

  • whether correct fb:app_id meta tag value is set

  • whether nginx returns correct page when facebook requests the page

  • whether correct namespaces added to the <html/> tag

  • whether we are using UTF-8 encoding

  • and something other, don't remember all my tests

And was checking web page through URL Linter each time. With no success. Facebook discarded parsing the page and fetching page title with other data from meta tags.

So I reviewed response/request data through firebug to find suspicious things. I found one scanty detail: Content-Type header had value "text/html;charset=utf-8;charset=UTF-8".
I must say, this one web page is generated by application using user-defined template. Grails controller is responsible for handling request and renders output like:

render text: context.out, contentType: "text/html;charset=$AppConstant.RENDER_CHARSET"

where AppConstant.RENDER_CHARSET equals to "UTF-8". But the rendered page had Content-Type equal to "text/html;charset=utf-8;charset=UTF-8". And my thought was to fix header value to have something like "text/thml;charset=UTF-8" and hoped this may help. So I changed code to be like:

render text: context.out, contentType: "text/html"

Content-Type header value now is "text/html;charset=utf-8". So I tried URL Lint again. I wasn't expecting much from Facebook this time either, but miracle happened! Everything works fine now. I know, that is my fault, but, nevertheless, thank you Facebook for "nice" time spending :).