Phantomjs fails to load HTTPS issue as switching to tlsv1

I had an apps to use phantomjs to generate a report by using Google Charts.

The apps will spawn a child process to execute phantomjs command, to load a web page that contains the charts, and then take a screenshots saving into JPG, which later convert into PDF for archive.

In the code, it needs to load the following JS URL from Google: https://www.google.com/jsapi, which is HTTPS based.

Suddenly it is stopped working since last month.

By checking the log and found that PhantomJS encountered JavaScript error: “ReferenceError, can’t find Google”. Hey, I tried to open the web page in my local Chrome browser, and it still working. I tried to CuRL from my server, still can download the page. So I suspected might be SSL issues on PhantomJS.

Tried googling and found a solution. As Google had already deprecated the old version of SSL (SSLv3) and use TLSv1.

In the command line, we need to add one more option: –ssl-protocol=tlsv1, to bypass the HTTPS error, and it turns out it is working now.


phantomjs --ssl-protocol=tlsv1 your-code.js

JavaScript inet_aton functions comparison

I came across this stun.js code and found one interesting implementation of inet_aton functions. I curious of its formula and equation.

function inet_aton(a) {
    var d = a.split('.');
    return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}

I written a simple Node.JS test script just to evaluate, calculate different implementations of inet_aton, and here is my findings:

function inet_aton(a) {
    var d = a.split('.');
    return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}
function inet_aton_b(ip){
    var a = new Array();
    a = ip.split('.');
    return((a[0] < < 24) >>> 0)  + ((a[1] < < 16) >>> 0) + ((a[2] < < 8) >>> 0) + (a[3] >>> 0);
}

function inet_aton_c(a) {
   var d = a.split('.');
   return d[0] * 256 * 256 * 256 + d[1] * 256 * 256 + d[2] * 256 + d[3];
}

var start;
start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));


start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton_b('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));

start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton_c('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));

See the first implementation run faster. The key point is lesser multiplication is performed, by factoring using simple math.

I run the same code on Java but I found different things, I can't tell which one run faster than other one. If I run the first code first, second code followed, always the second block faster than first block. If I exchange, run second code first, first code followed, always the second block faster than first block. They both run in same speed. I even use javap to view its bytecode and found second code have more instruction than first one, but might be JVM can do its optimization so that end result both code run same speed.

Java/JavaScript Tips on Append to File

This is Java/JavaScript Tips on Append content to file. I will introduce append file via command line, Java, and Node.JS (JavaScript).

To append file via command line, in Windows or Unix, you can do:

echo "test" >> a.txt

The file a.txt will be created if not exist at the first time. And the subsequence calls of >> will append the content to next line of the end of file.

To append file via Java, you can do:

PrintWriter pw = new PrintWriter(new FileWriter(new File("a.txt"), true)); 
pw.println("test");
pw.close();

The file a.txt will be created if not exist at the first time. And the subsequence calls of PrintWriter.println will append the content to next line of the end of file.

The interesting thing is I like to use PrintWriter, to call println, which I not need to append \n myself.

Notice the true variable at new FileWriter, this let Java know you want to append file, if you not provide this variable, Java will always overwrite the file but not appending.

To append file via JavaScript, you can do:

in asynchronous calls:

var fs = require('fs');
fs.appendFile('a.txt', 'content\n', function(err) {
 // some callback after append file
});

OR

in synchronize calls:

var fs = require('fs');
fs.appendFileSync('a.txt', 'content\n');

The file a.txt will be created if not exist at the first time. And the subsequence calls of appendFile or appendFileSync will append the content to next line of the end of file.

Node.JS provides asynchronous and synchronize versions for each File IO Calls. Refer the link here. Other than appendFile, for example, readFile/readFileSync, writeFile/writeFileSync.

Node.JS itself is a single threaded and asynchronous. It is always recommended to use asynchronous version of method instead of synchronize version, as synchronize version is a blocking calls. If the content need append to file is very very big, the calls will just hang there, Node.JS cannot handle other requests anymore. To learn how Node.JS back end works, refer here.

JavaScript Tips on Objects and Array and their For loop

This is JavaScript Tips on Objects and Array and their For loop.

In JavaScript, there is an Object and represented as:


var someObj = {name:"YongHao", age:25}

There is an Array and represented as:


var someArr = [1,2,3,4]

Use normal for loop only for Array, and use for…in only for Object.

For example, for Object

var someObj = {name:"YongHao", age:25}
for(var i in someObj) {
  console.log(i + ' - ' + someObj[i]);
}

We get:
name – YongHao
age – 25

For Array

var someArr = [1,2,3,4]
for(var i = 0; i < someArr.length; i++) {
  console.log(i + ' - ' + someArr[i]);
}

We get:
0 - 1
1 - 2
2 - 3
3 - 4

Do not use for...in to Array, if you do:

var someArr = [1,2,3,4]
for(var i in someArr) {
  console.log(i + ' - ' + someArr[i]);
}

It may return good result, but not recommended, as i now is a string but not an integer.

Java/JavaScript tips for removing list elements when iterating list

This is Java and JavaScript tips for same topic, removing list elements when iterating list.

In Java, we will use List as an example, as it is uncommon to remove element from an Array. In Javascript we will use Array as an example, as only Array is supported in JavaScript.

Introduction

To remove an element from a Java List, you will do

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");
someList.remove(1); // to remove by index
someList.remove("one); // to remove by element value
System.out.println(someList);

To remove an element from a JavaScript Array, you will do

var someArray = ["two", "one", "three"];
someArray.splice(1, 1); // to remove by index
console.log(someArray);

What if you want to remove an element from a List or Array when you iterating the List, you want to remove it based on some conditions?

In Java, you may do

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");

for(String item : someList) {
  if(item.equals("one")) {
    someList.remove(item); // #1
  }
  else if(item.equals("three")) {
    someList.remove(item); // #2
  }
}

Unfortunately, by doing this, you will get exception thrown.

By executing line #1, “one” is removed from someList, and next if you still continue the for loop, you will get exception as someList is modified, affecting the for loop execution.

The best way to remove item from a Java list is to use Iterator

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");

Iterator it = someList.iterator();
while(it.hasNext()) {
  String item = it.next();
  if(item.equals("one")) {
    it.remove();
  }
  else if(item.equals("three")) {
    it.remove();
  }
}

System.out.println("Latest someList: " + someList);

This is the safe way to remove items from List when you will still continue iterating over the someList.

In JavaScript, you may do

var someArray = ["two", "one", "three"];
for(var i = 0; i < someArray.length; i++) {
  if(someArray[i] == "one") {
    someArray.splice(i, 1); // #1
  }
  else if(someArray[i] == "three") {
    someArray.splice(i, 1); // #2
  }
}

Unfortunately, by doing this, you will get exception thrown.

By executing line #1, "one" is removed from someArray, and next if you still continue the for loop, you will get exception as someArray is modified, affecting the for loop execution.

The best way to remove item from a JavaScript array is to iterate the Array from last.

var someArray = ["two", "one", "three"];
for(var i = someArray.length - 1; i >= 0; i--) {
  if(someArray[i] == "one") {
    someArray.splice(i, 1); // #1
  }
  else if(someArray[i] == "three") {
    someArray.splice(i, 1); // #2
  }
}

This is the safe way to remove items from JavaScript Array.

Why this works? You may think same thing also applies to Java right? Yes you are right. How this works? Leave it for your back home reading.

JavaScript universal http request method – frequest

I wrote some universal JavaScript method for my apps, across Node.JS and Titanium Mobile, Freeswitch, jQuery. Here introduces a very simple but useful method, http request.

We all doing HTTP request on our apps. Make a request via HTTP and get back the response. I designed an API that I can use the same method signature when I am developing apps for Node.JS and Titanium Mobile. Node.JS is a server side program, and Titanium Mobile is a framework compile to Native iOS code. Freeswitch is an open source SIP Media Server, supports JavaScripts to create IVR apps. jQuery is a web based client framework. These platforms had different underlying native libraries to do HTTP request. I just want to design a very simple API that can wrap up these platforms, then I can share code easily across these platform.

The client code I can do:

frequest({
    url : 'http://somewebsite.com',
    callback : function(data) {
        console.log(data);
    }
});

The code for Node.JS:

frequest : function(args) {
		var http = require('http');
		
		try {
			var options = {};
		
			if(args.options) {
				
				options = args.options;
				
			}
			 
			if(args.url) {
				if(args.url.indexOf('http') == -1) return;
				var b = require('url').parse(args.url);
				
				// resolve host name
				if(b.hostname) {
					options.host = b.hostname;
				}
				
				// resolve port
				if(!b.port) {
					b.port = 80;
				}
				
				if(b.port) {
					options.port = b.port;
				}
				
				// resolve web path
				if(b.pathname) {
					options.path = b.pathname;
					
					if(b.search) {
						options.path += b.search;
					}
				}
					
			}
			
			if(args.headers) {
				options.headers = args.headers;
			}
		    
		    var request = http.get(options);
		
			if(args.callback || args.callbackJSON) {
				request.addListener('response', function(response){
				    var data = '';
				
				    response.addListener('data', function(chunk){ 
				        data += chunk; 
				    });
				    response.addListener('end', function(){
				        
				        // prepare data for callback
				        
				        if(data != '') {
				        	if(args.callback) {
					        	args.callback(data);
					        }
					        
					        if(args.callbackJSON) {
					        	try {
					        		var json = JSON.parse(data);
					        		args.callbackJSON(json);	
					        	
					        	} catch (e) {
					        		console.log(e);
					        	}
					        }
				        }
				        
				    });
				});
			}
		} catch (e) {
			console.log(e);
		}
		
		
	
	}

The code for Titanium Mobile:

var frequest = function(args) {
	
	
	var xhr = Ti.Network.createHTTPClient();
	xhr.onload = function() {
		var res = this.responseText;
		
		if(args.callback) {
			args.callback(res);
		}
		
		if(args.callbackJSON) {
			args.callbackJSON(JSON.parse(res));
		}
	};
	
	xhr.onerror = function(e) {
		// detect message
		var errortitle = 'Connection Failure Error';
		var errormsg = ''; // define some suggested network failure message
		if(e.error && e.error.indexOf('A connection failure occurred')) {
			errormsg = 'A connection failure occurred';
		}
		if(args.errorCallback) {
			args.errorCallback({
				e : e,
				errormsg : errormsg
			});
		} else {
			Ti.UI.createAlertDialog({
				title : errortitle,
				message : errormsg
			}).show();
		}
	}
	if(args.timeout) {
		xhr.timeout = args.timeout;
	}
	if(args.progressCallback) {
		xhr.onsendstream = function(e) {
			args.progressCallback(e.progress);
		}
	}
	
	var method = args.method || 'GET';
	xhr.open(method, args.url);
	if(args.headers) {
		for(var k in args.headers) {
			var v = args.headers[k];
			xhr.setRequestHeader(k,v);
		}
	}
	var params = args.params || null;
	if(params != null) 
		xhr.send(params);
	else
		xhr.send();
};

The code for Freeswitch:

frequest : function(args) {
		var result = fetchUrl(args.url);
		if(args.callback) {
			args.callback(result);
		}
	}

The code for jQuery:

var frequest = function(args) {
    $.ajax({
      url : args.url,
      success : args.callback
    });
};

Feel free to share your code for related frequest implementation.

Video for using Node.js for Everything

This is another talks video by Charlie Key, the CEO at Modulus, he share with us how Node.JS succeed for development nearly every aspects for a startup where load balance, performance, usability, enterprise class are considered.

He introduced and demo some new tools like Node-inspector, which is a web based inspector to inspect/debug Node code. The debugger interface is nearly same as the native Google Chrome/Safari Developer tools which developed for inspect client web JavaScript and this web based inspector is a completely rewrite mimic the look and feel and features of the native inspector just using JavaScript, and quite powerful, and quite interesting.

Meanwhile he introduced Modulus, an enterprise class Node.JS + MongoDB cloud platform, have a look.

Video for JavaScript & Our Obsession with Speed

This is a talks by Brian Lonsdorf, the CTO of Loop/Recur, who at least last 5 years stuck in JavaScript development, give a talks why we should not always comes to performance in an early stage, and he talks about the benefits of declarative over imperative way.

I spent my time to watch this video and I found useful so I share here to you. Now is Singapore Time 1:15am and I watched this video when I reached home from works just now, but unfortunately I slept in front of computer after this video nearly finished… But I should blog this video before sleep.