[tor-commits] [flashproxy/master] Add JavaScript build_url function.

dcf at torproject.org dcf at torproject.org
Sat Sep 8 09:30:20 UTC 2012


commit 143d3d99518f6e4ab970f8842e71e2133e68e44c
Author: David Fifield <david at bamsoftware.com>
Date:   Fri Sep 7 12:23:10 2012 -0700

    Add JavaScript build_url function.
---
 flashproxy-test.js |   47 ++++++++++++++++++++++++++++++++++++++++++++++
 flashproxy.js      |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/flashproxy-test.js b/flashproxy-test.js
index 1961740..3db15e0 100755
--- a/flashproxy-test.js
+++ b/flashproxy-test.js
@@ -60,6 +60,52 @@ function fail(test, expected, actual)
     print("FAIL " + repr(test) + "  expected: " + repr(expected) + "  actual: " + repr(actual));
 }
 
+function test_build_url()
+{
+    var TESTS = [
+        { args: ["http", "example.com"],
+          expected: "http://example.com" },
+        { args: ["http", "example.com", 80],
+          expected: "http://example.com" },
+        { args: ["http", "example.com", 81],
+          expected: "http://example.com:81" },
+        { args: ["https", "example.com", 443],
+          expected: "https://example.com" },
+        { args: ["https", "example.com", 444],
+          expected: "https://example.com:444" },
+        { args: ["http", "example.com", 80, "/"],
+          expected: "http://example.com/" },
+        { args: ["http", "example.com", 80, "/test?k=%#v"],
+          expected: "http://example.com/test%3Fk%3D%25%23v" },
+        { args: ["http", "example.com", 80, "/test", []],
+          expected: "http://example.com/test?" },
+        { args: ["http", "example.com", 80, "/test", [["k", "%#v"]]],
+          expected: "http://example.com/test?k=%25%23v" },
+        { args: ["http", "example.com", 80, "/test", [["a", "b"], ["c", "d"]]],
+          expected: "http://example.com/test?a=b&c=d" },
+        { args: ["http", "1.2.3.4"],
+          expected: "http://1.2.3.4" },
+        { args: ["http", "1:2::3:4"],
+          expected: "http://[1:2::3:4]" },
+        { args: ["http", "bog][us"],
+          expected: "http://bog%5D%5Bus" },
+        { args: ["http", "bog:u]s"],
+          expected: "http://bog%3Au%5Ds" },
+    ];
+
+    announce("test_build_url");
+    for (var i = 0; i < TESTS.length; i++) {
+        var test = TESTS[i];
+        var actual;
+
+        actual = build_url.apply(undefined, test.args);
+        if (objects_equal(actual, test.expected))
+            pass(test.args);
+        else
+            fail(test.args, test.expected, actual);
+    }
+}
+
 function test_parse_query_string()
 {
     var TESTS = [
@@ -170,6 +216,7 @@ function test_get_query_param_addr()
     }
 }
 
+test_build_url();
 test_parse_query_string();
 test_parse_addr_spec();
 test_get_query_param_addr();
diff --git a/flashproxy.js b/flashproxy.js
index 50526a4..d5b1c99 100644
--- a/flashproxy.js
+++ b/flashproxy.js
@@ -128,6 +128,59 @@ function parse_query_string(qs) {
     return result;
 }
 
+var DEFAULT_PORTS = {
+    http: 80,
+    https: 443
+}
+/* Build an escaped URL string from unescaped components. Only scheme and host
+   are required. See RFC 3986, section 3. */
+function build_url(scheme, host, port, path, params) {
+    var parts = []
+
+    parts.push(encodeURIComponent(scheme));
+    parts.push("://");
+
+    /* If it contains a colon but no square brackets, treat it like an IPv6
+       address. */
+    if (host.match(/:/) && !host.match(/[[\]]/)) {
+        parts.push("[");
+        parts.push(host);
+        parts.push("]");
+    } else {
+        parts.push(encodeURIComponent(host));
+    }
+    if (port !== undefined && port !== DEFAULT_PORTS[scheme]) {
+        parts.push(":");
+        parts.push(encodeURIComponent(port.toString()));
+    }
+
+    if (path !== undefined && path !== "") {
+        if (!path.match(/^\//))
+            path = "/" + path;
+        /* Slash is significant so we must protect it from encodeURIComponent,
+           while still encoding question mark and number sign. RFC 3986, section
+           3.3: "The path is terminated by the first question mark ('?') or
+           number sign ('#') character, or by the end of the URI. ... A path
+           consists of a sequence of path segments separated by a slash ('/')
+           character." */
+        path = path.replace(/[^\/]+/, function(m) {
+            return encodeURIComponent(m);
+        });
+        parts.push(path);
+    }
+
+    if (params !== undefined) {
+        parts.push("?");
+        for (var i = 0; i < params.length; i++) {
+            if (i > 0)
+                parts.push("&");
+            parts.push(encodeURIComponent(params[i][0]) + "=" + encodeURIComponent(params[i][1]));
+        }
+    }
+
+    return parts.join("");
+}
+
 /* Get a query string parameter and parse it as an address spec. Returns
    default_val if param is not defined in the query string. Returns null on a
    parsing error. */





More information about the tor-commits mailing list