Category Archives: Web

IPv6 Day

Today both google and facebook turn on their IPv6 addresses in their DNS servers for one day.


Pinging [2001:4860:800c::93] with 32 bytes of data:
Reply from 2001:4860:800c::93: time=29ms
Reply from 2001:4860:800c::93: time=32ms
Reply from 2001:4860:800c::93: time=68ms
Reply from 2001:4860:800c::93: time=28ms

Ping statistics for 2001:4860:800c::93:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 28ms, Maximum = 68ms, Average = 39ms


Pinging [2620:0:1c00:0:face:b00c:0:2] with 32 bytes of data:
Reply from 2620:0:1c00:0:face:b00c:0:2: time=102ms
Reply from 2620:0:1c00:0:face:b00c:0:2: time=125ms
Reply from 2620:0:1c00:0:face:b00c:0:2: time=94ms
Reply from 2620:0:1c00:0:face:b00c:0:2: time=95ms

Ping statistics for 2620:0:1c00:0:face:b00c:0:2:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 94ms, Maximum = 125ms, Average = 104ms

More Information

My ISP timewarner cable does not support native ipv6 yet, so I am still using he tunnelbroker for my home connection. Nonetheless it works pretty well.

Both most recent Tomato Firmware and Openwrt trunk version have built-in 6in4 and 6to4 support.

Update 1:

Update 2:

Add QR code to Tumblr Posts

It’s super simple to add a QR code to each Tumblr post. Just add this to anywhere between {block:posts} in your custom template.

<img src="{ShortURL}"/>

Here is an Example on my tumblr.

CloudFlare free cdn service

CloudFlare is a new cloud service which provides free website security and caching. A quick test revealed that it uses anycast geodns technology with nginx reverse caching.

The setup process is very easy. You only need to change DNS server from domain registry. Setup wizard will automatically import old DNS setting. However multi tiered sub domain won’t be detected. Both CNAME and A host will be proxyed through by default.

Once DNS change finished, your website will be severed with transparent proxies. Unwanted visitor will be screened and static assets will be cached.

Here is the page loading timeline of my test page
Without CloudFlare
Without CloudFlare
With CloudFlare
With CloudFlare
The page is very simple, but still it clearly shows there’s no measurable latency with dynamic contents and notable improvement with static assets. However text assets like html, css and js have slightly bigger size. My original is compressed with gzip -9.


  • Anycast GeoDNS hosting
  • Vistor security screen
  • Slick analytics
  • Transparent caching around world
  • Basic account is free
  • Very easy to setup


  • Http only, no video streaming
  • Slow in Asia
  • Suboptimal gzip compression ratio

Overall I am very impressed with the free features and performance.

A Simple OpenID Login Example on Appengine

I wrote a simple openid login example.

I used user api to do the real login.
Login Buttons

Here is source code.

The idea is very simple. Instead of redirecting main page, I use javascript to popup a small page. Most providers have webpage optimized for popup. Then this page will detect callback and refresh main page and close itself. A hidden iframe will also try previous login url if available.

Integrate open graph with tumblr

Facebook Like button relies on Open Graph protocol to provide site information such as name, image and title.

With tumblr‘s custom HTML theme, you can integrate open graph protocol in your theme. When user click on a like button, facebook will display your real site name instead of domain itself. If it is a photo post, in activity stream a nice thumbnail will be displayed.

My test page
Facebook with open graph

Here is a tumblr theme fragment which includes required items. I also uploaded images for all post types.


If you use Disqus comments system, you probably already have a facebook app id. You can find out both your app id and user id on facebook insights page. When you click “Insights for your Domain”, you will see a list of your apps and yourself. If you select any of them, the correct meta tag will be displayed.

Flash video player to html5 fallback

There’re many javascripts [1,2] to do html5 to flash fallback.

I slightly modified this script to do the opposite. It will normally play in a flash player whenever possible, but with html5 video on devices like ipad.

Here is my modified js file. You will also need google loader and open video player.

Add this to your html head

<script src=""></script>
<script src="/static/html5-video.js"></script>

Use html5 video tag as usual.

<video width="592" height="336" preload="none" controls>
  <source src="" 
  type="video/mp4" />


Use SimpleCDN for Silverlight streaming

Microsoft’s Smooth Streaming use standard http protocol, so it is possible to use simplecdn mirror bucket for delivering.

Here is my step by step to use open source software and simplecdn for HD video delivering.

Step 1: Server
Even though the Microsoft has opened spec for a while, there is current only 1 open source smooth streaming server

It has a few server plugins including apache and nginx. I choose nginx as my backend server. You can download the nginx plugin from It has two parts, a nginx module and a small utiility mp4split which converts mp4 files to fragmented format.

Nginx doesn’t use dynamic linked library, so you have to recompile the entire binary. I compiled the smooth streaming module on nginx-0.7.62 without any problem.

Step 2: Encoding
The entire process is documented on here. It require avisynth and a few other windows utilites.

If you need to do it on linux, here is how:
You will need both ffmpeg and x264. I have tried use ffmpeg alone, but it can not accept stats file from a different bit rate setting which is required step.

Direct pipe through ffmpeg and x264 also doesn’t work, because x264 can’t recognize file type, so you need a named pipe.

mkfifo video.y4m

This file can be reused many times.

Pass 1:

ffmpeg -i -an -f yuv4mpegpipe - > video.y4m & 
x264 --threads auto --profile high --level 3.2 --preset slow --no-mbtree --b-pyramid  --min-keyint 24 --keyint 96 --pass 1 --bitrate 2524 -o /tmp/bbb_2524.mp4 video.y4m

You can also run these two commands under 2 different console windows. Setting –no-mbtree is important.

Pass 2:
If everything go ok in pass 1, you can now run pass 2 for multiple bitrate

ffmpeg -i -an -s 256x144 -f yuv4mpegpipe - > video.y4m & 
x264 --threads auto --profile high --level 3.2 --preset slow --no-mbtree --b-pyramid  --min-keyint 24 --keyint 96 --pass 2 --bitrate 260 -o /tmp/bbb_260.mp4 video.y4m

Repeat this step with your desired resolution, bitrate and filenames.

The output mp4 file from x264 cannot be streamed, you will need a small utility qt-faststart to fix them.

Problem: I can’t encode playable audio file. If I include audio, the player simply stop.

Now following the rest step described here to split your mp4 files.

Step 3: Player
Unfortunately there’s no working open source player can do smooth stream. Code-shop’s website mentioned openvideoplayer can be updated by replaced with smoothstreaming dll, but I can not find where to put the file.

So I duplicated code-shop’s demo page.

Step 4: SimpleCDN
The simplest step, make a mirror bucket and point it to your webserver.


Here is my 720p video streaming through simplecdn.

No audio yet. It looks exactly like every other demo page, but it stream through my nginx server and simplecdn. Microsoft’s player use additional query parameters to speedup playback, but simplecdn will strip them away.

Other thought:
I think it is possible to split fragmented mp4 files to real files, so you probably need not a special server module.

Google chrome frame test

Long time no update.

I have just added google frame to my blog template. I was trying to find some sites actually use chrome frame without any success. Just out of curiosity I added it to my own website.

Here are screenshots after install chrome frame in my ie8.
About box

Right Click Menu

Update 1: The display will flick when it switches rendering engine. Ie8 will also switch render engine back when I click a regular webpage.

My Varnish VCL for WordPress

On Varnish’s official website, there is a WordPress optimization guide For The Impatient: Preparing Varnish/Wordpress for a Slashdotting in 60 seconds or less….

The problem is that it removes cookie too aggressively. All non admin page will be virtually static. So I made my own vcl to remove cookies for only static files.

Here it is

backend default {
.host = "";
.port = "80";

sub vcl_recv {
# Normalize Content-Encoding
    if (req.http.Accept-Encoding) {
        if (req.url ~ ".(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(?.*|)$") {
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
# Remove cookies and query string for real static files
    if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(?.*|)$") {
       unset req.http.cookie;
       set req.url = regsub(req.url, "?.*$", "");
# Remove cookies from front page
    if (req.url ~ "^/$") {
       unset req.http.cookie;
sub vcl_fetch {
        if (req.url ~ "^/$") {
                unset obj.http.set-cookie;

So all interactive pages will be sent to php backend with correct cookies. All static files and front page will be served by varnish proxy.

Plugin Image Optimizer

This plugin will reduce uploaded image size in wordpress.
You will also need to install Optipng , Jhead and unsafe mode php.

These tools will only strip meta information of your images, therefore the result should be lossless.

You can download this plugin here.