Anjanesh

Assignment Statements, Comparisons & Observations
Font: Size: + -

Web Hosting Solutions for Web Developers

Saturday, June 29, 2013

There are tons of hosting companies for web developers.
There are many that provide VPS-like solutions.
But there are a few good ones for developers wanting more than the standard LAMP setup and a Fantastico script.
Here we'll look at a handful of the ones that have proven to be good enough.

Webfaction

This is a semi-VPS where you can install your own tools / software as long as it resides in your home directory. Supports Python, Ruby, PHP out-of-the-box.
Plan starts at $9.50 a month for 100GB disk space.

Linode

A fully-fledged unmanaged VPS that has been in the hosting space for quite some time now. Developers normally compared Linode with Slicehost, another great unmanaged VPS before it got acquired by & merged with Rackspace.
Plan starts at $20 a month for 24GB disk space.

DigitalOcean

This is one of the best places to start out for newbies who want to full root-access at a low cost. Its an unmanaged VPS where you can setup your own Linux distro with whatever software you want. Oh - and it may offer the choice of a datacenter in India.
Plan starts at $5 a month for a 20GB SSD disk space.

Amazon AWS

A proven product, if you want scalability & reliability. Some of the major websites / services like Reddit, DropBox, FourSquare, Netflix, Zynga use Amazon AWS. Amazon AWS EC2 is the virtual dedicated hosting service.
Amazon AWS provides a plethora of other services like S3, etc.
You still need to maintain the server on your own - Amazon won't do it for you. Moreover you've got to have sys-admin skills to handle an EC2 instance.

Google App Engine

Google's servers ! That's the best part. Scalability. No worrying of backups, server maintanence, server going down etc etc.
What's the worst part ? It's not the standard setup you get with other providers which provide (S)FTP, SSH etc.
Configuration is done using a file named app.yaml. Everything else is almost custom based.
This is PaaS - Platform as a Service hosting solution and hence you can't go about installing your own software. Instead it provides a wide range of options and custom solutions. Currently Python, Java, Go and PHP are the languages supported.

Others :

Uploading gzipped content to Google Storage via gsutil

Thursday, January 17, 2013

Blogging this, since it doesn't fit on twitter.

It took me sometime to figure out the proper usage of gsutil when uploading files to google storage with the -z option to stream gzipped content. Just make sure to send in the content-type header too.

gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" -h "Content-Type: text/javascript" cp -z js -a public-read script.min.js gs://[bucket]/script.js

How to upload a web-font to Google Cloud Storage and use it in your CSS

Wednesday, December 26, 2012

Replace [bucket] with your bucket name.

  1. Use fontsquirrel's @font-face Generator to download all the font formats required for various browsers.
  2. Upload the fonts to Google Storage :
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.eot gs://[bucket]/fonts/font-webfont.eot
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.woff gs://[bucket]/fonts/font-webfont.woff
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.ttf gs://[bucket]/fonts/font-webfont.ttf
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.svg gs://[bucket]/fonts/font-webfont.svg

    Now your font is accessible at http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot or http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.ttf etc.

  3. Apply the code to your CSS.

    @font-face {
        font-family: 'fontFamilyName';
        src: url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot');
        src: url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot?#iefix') format('embedded-opentype'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.woff') format('woff'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.ttf') format('truetype'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.svg#aller_displayregular') format('svg');    
        font-weight: normal;
        font-style: normal;
    }
  4. Unfortunately the last step is not enough to display the web-font on your website since the fonts need to be on the same domain as the website.

    In order to allow web-fonts to be hosted elsewhere, the location of the web-fonts must have a Access-Control-Allow-Origin header sent.

    For Google Storage, we do this :

    <?xml version="1.0" encoding="UTF-8"?>
    <CorsConfig>
      <Cors>
        <Origins>
          <Origin>http://mydomain.com</Origin>
        </Origins>
        <Methods>
          <Method>GET</Method>
          <Method>HEAD</Method>      
        </Methods>
        <ResponseHeaders>
          <ResponseHeader>x-goog-meta-foo1</ResponseHeader>
        </ResponseHeaders>
        <MaxAgeSec>1800</MaxAgeSec>
      </Cors>
    </CorsConfig>

    Save this as font.xml.
    Hmmm ... Google says :

    gsutil setcors <cors-xml-file> uri

    But using gsutil, we can set CORS to an entire bucket only and not to an object.

    gsutil setcors font.xml gs://[bucket]

    not uri as mentioned

    Similarily, for getcors :

    gsutil getcors gs://[bucket]
    and not
    gsutil getcors gs://cats/mycats.png

Solving all my permission issues on Ubuntu

Sunday, November 25, 2012

So many permission issues when copying files / folders from an outside source like a remove drive or Dropbox to my hard-disk that I have this mini-snippet to solve them all.

chmod -R 755 directory/
cd directory/
find -type f -exec chmod 644 {} \;
cd ..

Why I bought a Dropbox Pro account ?

Sunday, August 12, 2012

Last weekend was bad. My MacBook Pro's hard-drive crashed and my Ubuntu machine's hard-drive was semi-crashing, booting once in a while and once it booted with the entire file-system as read-only !

While my Ubuntu machine was up and running, I managed to backup all my data to Dropbox. But this time I backed it up in such a way that I don't have to 're-arrange' the folders all over again when my computer crashes.

Here's an example of what I did for my localhost (http://localhost/anjanesh) which, on the physical file system points to /home/anjanesh/www (~/www).

  • I copied all my data from ~/www to ~/Dropbox/www
  • Dropbox synced all the data in ~/Dropbox/www to the server
  • I deleted ~/www and symlinked www to ~/Dropbox/www (ln -s ~/Dropbox/www www)

So now ~/www points to ~/Dropbox/www
Whatever changes I make to ~/www gets stored, indexed and synced to Dropbox's server.

And now on my MacBook, I installed Dropbox and did the same thing with www - except point ~/www to /Users/anjanesh/Dropbox/www
This way, http://localhost/~anjanesh/ physically points to my Dropbox folder.

You can do this with all data folders, like Documents, Pictures and even Desktop. Even /var/lib/mysql to point all the mysql-data to a Dropbox sub-folder itself.

Open-Source Slideshare alternative

Sunday, February 05, 2012

There were 2 reasons for me to create an alternative to slidehsare's slide-show plugin :

  1. My uncle had a 170MB PPT file which is over-the-limit of Slideshare's 100MB size limit.
  2. My previous company's CEO wanted to display 6 slideshows on the company's homepage and 6 slideshare plugins was being extremely heavy esp on the flash part.

So I created a simple slide-show using jQuery as a jQuery plugin. There are some advantages as well as disadvantages.

Advantages

  • This is completely customizable using CSS.
  • Flexible slide size
  • Unlimited slides

Disadvantages

  • The slides are all images though, not HTML on the inside. Images would consume more space than HTML sildes.
  • You need to export the slides to images, which you can do using Open Office.
  • Require basic programming knowledge in HTML, CSS & JavaScript to embed this.

An example of this :

Usage :

$(document).ready(function()
{
    $('#div-element').jscoin_slide({effect:'slideUp'});
});

The other options for effect are fade, flip and slide

This project is on github : https://github.com/anjanesh/Slide.

Linkedin's April Fool Hoaxes

Friday, April 01, 2011

Every year we want to know Google's april fools' hoaxes. This year was no different. But has anyone noticed linkedin ? This is what I found on linkedin from my People You May Know section.
Linkedin People You May Know
(Click on the image to view the full "resume")

Linkedin People You May Know Linkedin People You May Know Linkedin People You May Know

Google Agarbatti (Incense)

Monday, October 25, 2010

My friend Sudhir bought this from the local store.

google agarbatti

Read : Google Agarbatti. (Agarbatti = Incense)

Update : Thanks to Sumit Ashok Kesarkar for the clarification. its Gugal which means Guggul == made from the sap of the plant "Commiphora mukul"

Email Newsletter Subscription via GFC & GAE

Wednesday, July 28, 2010

There is one major limitation when sending out legit mass emails via SMTP ("compose") - a daily cap on the number of emails allowed to be sent from a mailbox. This applies to most e-mail service providers.
Google Apps Standard, the free edition, allows a maximum of 500 outgoing mails per day for each user id.
Even the Primier edition which costs $50 per user a year limits outgoing mails at 2000 per day for every email id.

There are two cost-effective ways to send out newsletter emails via Google's services - Google Friend Connect (GFC) and Google App Engine (GAE).

Google Friend Connect

subscribeA lot of people are not unaware of the fact that you can actually send out newsletters for free to your subscribers via Google Friend Connect (GFC).
The catch is that the users have to be susbcribed exclusively via Google's Subscribe button without which there is no way for the newsletter to reach the user.
This is really a tough catch as you got to have it's subscribe button right from launch date.
Its a major turnoff, especially when a website collects registration infomation via a form and sends the data to a database, after which emails are sent separately.
Most email marketing systems like aweber, mailchimp, emailbrain, constantcontact, madmimi etc have the option to add subscribers manually externally.
And with GFC, you would not be able to retrieve the subscribed users' email ids via the control panel - export gives only names, ids, open id urls and thumbnail images.
So, at a later point in time, if you decide to switch to another email marketing system, you would need to send one last email asking them to re-subscribe to a new system.
Another bad news is that the subscriber's email address must be an open id ! (google a/c, yahoo a/c, twitter, AIM, netlog or any other openid)
Looks like all bad news, but if you think from the users' perspective, this is a good deal.
Its secure since there is no way for emails to be leaked accidentally.
Its safe because there is no room for errors in accidentally sending out mails to users who have unsubscribed.
Regarding the sender / from email address - It would be the same as the google account username. So if you don't want it sent from myusername@gmail.com, then create a google account under your app id. (This dual account chaos would be resolved soon : Google Apps Accounts Will Also Be Personal Google Accounts)
GFC is straigtforward, only bit of major work required is getting the audience to hit the google subscribe button.

Google App Engine

If you are not convinced with GFC then check out GAE - Google App Engine.
It has a daily free quota of sending emails to 2000 recipients. Link
After that, its billed at $0.0001 per recipient - thats just $1 for sending to an additional 10,000 recipients which can execute in about 2 minutes ! Link
But you've got to code to take advantage of GAE and your website should most probably be powered by GAE as well.
subscribe

Google Groups

Then there is always google's mailing list at google groups.
subscribe
But this cannot really be act a newsletter system.

If you want to submit ideas / suggestions to the Google team for its products, you can submit or vote at Google Product Ideas which is open to the public.

To WWW or not to

Monday, July 26, 2010

I've always been fond of naked domains. (FYI, http://mydomain.com is a naked domain, since it doesn't have www in front of it).
Lesser characters to type, see, spell out, hear and read. Much lesser overall energy.
I've always wondered why google.com always redirected to www.google.com and why Google App Engine stopped supporting mapping of an app to a naked URL. May not be the reason as mentioned here, but it does have its advantages.
So I joined the party a bit too late, but I am glad that I was not any later.
One of the advantages of using a subdomain (www is also a subdomain, it just so happens to be the default typing scheme for a website when the World Wide Web was born) is that cookies, if any, are transported to and forth - in the request and response headers - for that subdomain only.
If you have Web Developer, a FireFox addon, you can view all the cookies associated with a URL in the address bar.

Web Developer Toolbar

Here is a one liner php script to demonstrate this :

<?php setcookie("UserID", "23", time() + 3600, "/", "anjanesh.net") ?>

http://www.anjanesh.net/cookie.php

Cookies on www

http://test.anjanesh.net/cookie.jpg

Cookies on test

Lets re-iterate the above, this time without typing in www for the first URL. CTRL + SHIFT + DEL and clear all cookies.

http://anjanesh.net/cookie.php

Cookies on naked domain

http://test.anjanesh.net/cookie.jpg

Cookies on test again

Now, when requesting for a pure jpg image, the cookie information is sent across to the server which is 17 bytes (Cookie: UserID=23) of useless data.
You can use Live HTTP Headers FireFox addon to view real-time browser-request and server-response headers.

http://anjanesh.net/cookie.php

GET /cookie.php HTTP/1.1
Host: anjanesh.net
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100710 Ubuntu/9.10 (karmic) Namoroka/3.6.8pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 25 Jul 2010 01:14:18 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.11
Set-Cookie: UserID=23; expires=Fri, 25-Jul-2010 02:14:18 GMT; path=/; domain=anjanesh.net
Content-Encoding: gzip
----------------------------------------------------------
http://test.anjanesh.net/cookie.jpg

GET /cookie.jpg HTTP/1.1
Host: test.anjanesh.net
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100710 Ubuntu/9.10 (karmic) Namoroka/3.6.8pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: UserID=23
HTTP/1.1 200 OK Server: nginx Date: Fri, 25 Jul 2010 01:14:21 GMT Content-Type: image/jpeg Connection: keep-alive Last-Modified: Thu, 29 Nov 2007 03:54:05 GMT Etag: "27284bc-8291-4400943e7f140" Accept-Ranges: bytes Content-Length: 33425 ----------------------------------------------------------

From Y!'s Best Practices for Speeding Up Your Web Site :

If your domain is www.example.org, you can host your static components on static.example.org. However, if you've already set cookies on the top-level domain example.org as opposed to www.example.org, then all the requests to static.example.org will include those cookies.

But its not always possible to safe-guard this if your users don't type the www and you forget to force redirection to http://www
The best solution would be use a completely different domain name as a cookieless domain for static content.

Initially, I did not set the path & domain parameters in setcookie()

<?php setcookie("UserID", "23", time() + 3600) ?>

This does not send cookies across to the subdomain requests even when the cookie was set to the naked URL.
This does not even send cookies across to different paths.
But some browsers, or old browsers may behave differently, automatically adding cookies to *.example.org as Y! pointed out.

Related :