var querystring = require('querystring');
var http = require('http');
var fs = require('fs');
var crypto = require('crypto');

function getResult(options, callback) {
    options = options || {};
    
    var dlkbps = options.download || 200000;
    var pingms = options.ping ||  40;;
    var ulkbps = options.upload || 200000;
    var srv = options.server || 5056;

    if (!options.noRandomize) {
        dlkbps = randomize(dlkbps);
        pingms = randomize(pingms);
        ulkbps = randomize(ulkbps);
    }
    
    function hash(parameters, algorithm, seperator) {
        seperator = seperator || "-";
        algorithm = algorithm || "md5"; 
        var str = parameters.join(seperator);
        var shasum = crypto.createHash(algorithm);
        shasum.update(encodeURIComponent(str));
        return shasum.digest('hex');
    }

    function randomize(number) {
        return Math.floor(number * (0.8 + 0.2 * Math.random()));
    }
    
    function parse(res) {
        var i, tempArr, tempArr2, id, resObj;
        res = res.toString();
        tempArr = res.split('&');
        resObj = {};
        for (i = tempArr.length - 1; i >= 0; i--) {
            tempArr2 = tempArr[i].split("=");
            resObj[decodeURIComponent(tempArr2[0])] = decodeURIComponent(tempArr2[1]);
        }
        resObj.resultURL = "http://www.speedtest.net/my-result/" + resObj.resultid;
        resObj.resultImage = "http://www.speedtest.net/result/" + resObj.resultid + ".png";
        return resObj;
    }
    
    // Build the post string from an object
    var post_data = querystring.stringify({
        "download" : dlkbps,
        'ping' : pingms,
        'upload' : ulkbps,
        'promo' : "",
        'startmode' : 'pingselect',
        'recommendedserverid' : srv,
        'accuracy' : 1,
        'serverid' : srv,
        'hash' : hash([pingms, ulkbps, dlkbps, '297aae72'], "md5", "-")
    });


    // An object of options to indicate where to post to
    var post_options = {
        host: 'www.speedtest.net',
        port: '80',
        path: '/api/api.php',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Referer' : "http://c.speedtest.net/flash/speedtest.swf",
            'Content-Length': post_data.length
        }
    };

    // Set up the request
    var post_req = http.request( post_options, function(res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            callback(parse(chunk));
        });
    });


    // post the data
    post_req.write(post_data);
    post_req.end();
}/*
getResult({}, function(ob) {
    console.log(ob);
})*/

/**
    options [object]:
        downlaod [Number]
        upload [Number]
        ping [Number]
        server [Number]
        noRandomize [boolean]
    
*/

module.exports = {
    getResult : getResult,
    test : function (options) {
        getResult(options, function(ob) {
            console.log(ob);
        });
    }
}
@@ -220,120 +220,389 @@
 kbps
- = options.download %7C%7C 200000;%0D%0A    var pingms = options.ping %7C%7C  40;;%0D%0A    var ulkbps = options.upload %7C%7C 20000
+Range = %7Bmax : 1999999, min : 1%7D;%0D%0A    var ulkbpsRange = %7Bmax : 1999999, min : 1%7D;%0D%0A    var pingmsRange = %7Bmax : 65535, min : 0%7D;%0D%0A    %0D%0A    var dlkbps = isPositive(options.download) ? Math.floor(options.download) : 200000;%0D%0A    var ulkbps = isPositive(options.upload) ? Math.floor(options.upload) : 200000;%0D%0A    var pingms = isPositive(options.ping) ? Math.floor(options.ping) : 4
 0;%0D%0A
@@ -615,16 +615,27 @@
 r srv = 
+isPositive(
 options.
@@ -644,19 +644,36 @@
 rver
- %7C%7C
+) ? options.server :
  5056;%0D%0A
 %0D%0A  
@@ -668,16 +668,20 @@
  5056;%0D%0A
+    
 %0D%0A    if
@@ -823,32 +823,507 @@
 ;%0D%0A    %7D%0D%0A    %0D%0A
+    dlkbps = fixRange(dlkbps, dlkbpsRange);%0D%0A    ulkbps = fixRange(ulkbps, ulkbpsRange);%0D%0A    pingms = fixRange(pingms, pingmsRange);%0D%0A    %0D%0A    function isPositive(val) %7B%0D%0A        return typeof val === %22number%22 && isFinite(val) && val %3E= 0;%0D%0A    %7D%0D%0A    %0D%0A    function fixRange(val, limit) %7B%0D%0A        if (val %3E limit.max) %7B%0D%0A            return limit.max;%0D%0A        %7D%0D%0A        if (val %3C limit.min) %7B%0D%0A            return limit.min;%0D%0A        %7D%0D%0A        return val;%0D%0A    %7D%0D%0A    %0D%0A
     function has

fix range and prevent invalid parameter