mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-14 05:11:19 -04:00
convert rest of address spec tests, ProxyPair test, and move parse functions into Parse container
This commit is contained in:
parent
75ac969fc7
commit
487dfe697a
2 changed files with 164 additions and 32 deletions
|
@ -57,26 +57,11 @@ Query =
|
||||||
encodeURIComponent(param[1])
|
encodeURIComponent(param[1])
|
||||||
parts.join '&'
|
parts.join '&'
|
||||||
|
|
||||||
Params =
|
Parse =
|
||||||
getBool: (query, param, defaultValue) ->
|
|
||||||
val = query[param]
|
|
||||||
return defaultValue if undefined == val
|
|
||||||
return true if 'true' == val || '1' == val || '' == val
|
|
||||||
return false if 'false' == val || '0' == val
|
|
||||||
return null
|
|
||||||
|
|
||||||
# Get an object value and parse it as a byte count. Example byte counts are
|
|
||||||
# "100" and "1.3m". Returns default_val if param is not a key. Return null on
|
|
||||||
# a parsing error.
|
|
||||||
getByteCount: (query, param, defaultValue) ->
|
|
||||||
spec = query[param]
|
|
||||||
return defaultValue if undefined == spec
|
|
||||||
parseByteCount spec
|
|
||||||
|
|
||||||
# Parse a cookie data string (usually document.cookie). The return type is an
|
# Parse a cookie data string (usually document.cookie). The return type is an
|
||||||
# object mapping cookies names to values. Returns null on error.
|
# object mapping cookies names to values. Returns null on error.
|
||||||
# http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038
|
# http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038
|
||||||
parseCookie: (cookies) ->
|
cookie: (cookies) ->
|
||||||
result = {}
|
result = {}
|
||||||
strings = []
|
strings = []
|
||||||
strings = cookies.split ';' if cookies
|
strings = cookies.split ';' if cookies
|
||||||
|
@ -90,7 +75,7 @@ Params =
|
||||||
|
|
||||||
# Parse an address in the form 'host:port'. Returns an Object with keys 'host'
|
# Parse an address in the form 'host:port'. Returns an Object with keys 'host'
|
||||||
# (String) and 'port' (int). Returns null on error.
|
# (String) and 'port' (int). Returns null on error.
|
||||||
parseAddress: (spec) ->
|
address: (spec) ->
|
||||||
m = null
|
m = null
|
||||||
# IPv6 syntax.
|
# IPv6 syntax.
|
||||||
m = spec.match(/^\[([\0-9a-fA-F:.]+)\]:([0-9]+)$/) if !m
|
m = spec.match(/^\[([\0-9a-fA-F:.]+)\]:([0-9]+)$/) if !m
|
||||||
|
@ -104,9 +89,9 @@ Params =
|
||||||
return null
|
return null
|
||||||
{ host: host, port: port }
|
{ host: host, port: port }
|
||||||
|
|
||||||
# Parse a count of bytes. A suffix of "k", "m", or "g" (or uppercase)
|
# Parse a count of bytes. A suffix of 'k', 'm', or 'g' (or uppercase)
|
||||||
# does what you would think. Returns null on error.
|
# does what you would think. Returns null on error.
|
||||||
parseByteCount: (spec) ->
|
byteCount: (spec) ->
|
||||||
UNITS = {
|
UNITS = {
|
||||||
k: 1024, m: 1024 * 1024, g: 1024 * 1024 * 1024
|
k: 1024, m: 1024 * 1024, g: 1024 * 1024 * 1024
|
||||||
K: 1024, M: 1024 * 1024, G: 1024 * 1024 * 1024
|
K: 1024, M: 1024 * 1024, G: 1024 * 1024 * 1024
|
||||||
|
@ -122,6 +107,30 @@ Params =
|
||||||
return null if null == units
|
return null if null == units
|
||||||
count * Number(units)
|
count * Number(units)
|
||||||
|
|
||||||
|
Params =
|
||||||
|
getBool: (query, param, defaultValue) ->
|
||||||
|
val = query[param]
|
||||||
|
return defaultValue if undefined == val
|
||||||
|
return true if 'true' == val || '1' == val || '' == val
|
||||||
|
return false if 'false' == val || '0' == val
|
||||||
|
return null
|
||||||
|
|
||||||
|
# Get an object value and parse it as a byte count. Example byte counts are
|
||||||
|
# '100' and '1.3m'. Returns |defaultValue| if param is not a key. Return null on
|
||||||
|
# a parsing error.
|
||||||
|
getByteCount: (query, param, defaultValue) ->
|
||||||
|
spec = query[param]
|
||||||
|
return defaultValue if undefined == spec
|
||||||
|
Parse.byteCount spec
|
||||||
|
|
||||||
|
# Get an object value and parse it as an address spec. Returns |defaultValue|
|
||||||
|
# if param is not a key. Returns null on a parsing error.
|
||||||
|
getAddress: (query, param, defaultValue) ->
|
||||||
|
val = query[param]
|
||||||
|
return defaultValue if undefined == val
|
||||||
|
Parse.address val
|
||||||
|
|
||||||
|
|
||||||
safe_repr = (s) -> SAFE_LOGGING ? '[scrubbed]' : JSON.stringify(s)
|
safe_repr = (s) -> SAFE_LOGGING ? '[scrubbed]' : JSON.stringify(s)
|
||||||
|
|
||||||
# HEADLESS is true if we are running not in a browser with a DOM.
|
# HEADLESS is true if we are running not in a browser with a DOM.
|
||||||
|
@ -286,7 +295,7 @@ class Snowflake
|
||||||
|
|
||||||
# TODO: User-supplied for now, but should fetch from facilitator later.
|
# TODO: User-supplied for now, but should fetch from facilitator later.
|
||||||
setRelayAddr: (relayAddr) ->
|
setRelayAddr: (relayAddr) ->
|
||||||
addr = Params.parseAddress relayAddr
|
addr = Parse.address relayAddr
|
||||||
if !addr
|
if !addr
|
||||||
log 'Invalid address spec.'
|
log 'Invalid address spec.'
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# s = require './snowflake'
|
|
||||||
|
|
||||||
window = {}
|
window = {}
|
||||||
|
|
||||||
VERBOSE = false
|
VERBOSE = false
|
||||||
|
@ -24,6 +22,10 @@ fail = (test, expected, actual) ->
|
||||||
' expected: ' + JSON.stringify(expected) +
|
' expected: ' + JSON.stringify(expected) +
|
||||||
' actual: ' + JSON.stringify(actual)
|
' actual: ' + JSON.stringify(actual)
|
||||||
|
|
||||||
|
# Stubs for browser functionality.
|
||||||
|
class WebSocket
|
||||||
|
OPEN: 1
|
||||||
|
CLOSED: 0
|
||||||
|
|
||||||
testBuildUrl = ->
|
testBuildUrl = ->
|
||||||
TESTS = [{
|
TESTS = [{
|
||||||
|
@ -69,7 +71,6 @@ testBuildUrl = ->
|
||||||
args: ['http', 'bog:u]s']
|
args: ['http', 'bog:u]s']
|
||||||
expected: 'http://bog%3Au%5Ds'
|
expected: 'http://bog%3Au%5Ds'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
announce 'testBuildUrl'
|
announce 'testBuildUrl'
|
||||||
for test in TESTS
|
for test in TESTS
|
||||||
actual = buildUrl.apply undefined, test.args
|
actual = buildUrl.apply undefined, test.args
|
||||||
|
@ -116,10 +117,9 @@ testParseCookieString = ->
|
||||||
cs: 'a=\'\''
|
cs: 'a=\'\''
|
||||||
expected: { a: '\'\'' }
|
expected: { a: '\'\'' }
|
||||||
}]
|
}]
|
||||||
|
|
||||||
announce 'testParseCookieString'
|
announce 'testParseCookieString'
|
||||||
for test in TESTS
|
for test in TESTS
|
||||||
actual = Params.parseCookie test.cs
|
actual = Parse.cookie test.cs
|
||||||
if JSON.stringify(actual) == JSON.stringify(test.expected)
|
if JSON.stringify(actual) == JSON.stringify(test.expected)
|
||||||
pass test.cs
|
pass test.cs
|
||||||
else
|
else
|
||||||
|
@ -179,7 +179,6 @@ testParseQueryString = ->
|
||||||
qs: 'a=b&&c=d'
|
qs: 'a=b&&c=d'
|
||||||
expected: { a: 'b', '':'', c: 'd' }
|
expected: { a: 'b', '':'', c: 'd' }
|
||||||
}]
|
}]
|
||||||
|
|
||||||
announce 'testParseQueryString'
|
announce 'testParseQueryString'
|
||||||
for test in TESTS
|
for test in TESTS
|
||||||
actual = Query.parse test.qs
|
actual = Query.parse test.qs
|
||||||
|
@ -188,14 +187,138 @@ testParseQueryString = ->
|
||||||
else
|
else
|
||||||
fail test.qs, test.expected, actual
|
fail test.qs, test.expected, actual
|
||||||
|
|
||||||
|
testGetParamBoolean = ->
|
||||||
|
TESTS = [{
|
||||||
|
qs: 'param=true'
|
||||||
|
expected: true
|
||||||
|
},{
|
||||||
|
qs: 'param',
|
||||||
|
expected: true
|
||||||
|
},{
|
||||||
|
qs: 'param='
|
||||||
|
expected: true
|
||||||
|
},{
|
||||||
|
qs: 'param=1'
|
||||||
|
expected: true
|
||||||
|
},{
|
||||||
|
qs: 'param=0'
|
||||||
|
expected: false
|
||||||
|
},{
|
||||||
|
qs: 'param=false'
|
||||||
|
expected: false
|
||||||
|
},{
|
||||||
|
qs: 'param=unexpected'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
qs: 'pram=true'
|
||||||
|
expected: false
|
||||||
|
}]
|
||||||
|
announce 'testGetParamBoolean'
|
||||||
|
for test in TESTS
|
||||||
|
query = Query.parse test.qs
|
||||||
|
actual = Params.getBool(query, 'param', false)
|
||||||
|
if actual == test.expected
|
||||||
|
pass test.qs
|
||||||
|
else
|
||||||
|
fail test.qs, test.expected, actual
|
||||||
|
|
||||||
|
testParseAddress = ->
|
||||||
|
TESTS = [{
|
||||||
|
spec: ''
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '3.3.3.3:4444'
|
||||||
|
expected: { host: '3.3.3.3', port: 4444 }
|
||||||
|
},{
|
||||||
|
spec: '3.3.3.3'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '3.3.3.3:0x1111'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '3.3.3.3:-4444'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '3.3.3.3:65536'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '[1:2::a:f]:4444'
|
||||||
|
expected: { host: '1:2::a:f', port: 4444 }
|
||||||
|
},{
|
||||||
|
spec: '[1:2::a:f]'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '[1:2::a:f]:0x1111'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '[1:2::a:f]:-4444'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '[1:2::a:f]:65536'
|
||||||
|
expected: null
|
||||||
|
},{
|
||||||
|
spec: '[1:2::ffff:1.2.3.4]:4444'
|
||||||
|
expected: { host: '1:2::ffff:1.2.3.4', port: 4444 }
|
||||||
|
}]
|
||||||
|
announce 'testParseAddrSpec'
|
||||||
|
for test in TESTS
|
||||||
|
actual = Parse.address test.spec
|
||||||
|
if JSON.stringify(actual) == JSON.stringify(test.expected)
|
||||||
|
pass test.spec
|
||||||
|
else
|
||||||
|
fail test.spec, test.expected, actual
|
||||||
|
|
||||||
|
testGetParamAddress = ->
|
||||||
|
DEFAULT = { host: '1.1.1.1', port: 2222 }
|
||||||
|
TESTS = [{
|
||||||
|
query: { }
|
||||||
|
expected: DEFAULT
|
||||||
|
},{
|
||||||
|
query: { addr: '3.3.3.3:4444' },
|
||||||
|
expected: { host: '3.3.3.3', port: 4444 }
|
||||||
|
},{
|
||||||
|
query: { x: '3.3.3.3:4444' }
|
||||||
|
expected: DEFAULT
|
||||||
|
},{
|
||||||
|
query: { addr: '---' }
|
||||||
|
expected: null
|
||||||
|
}]
|
||||||
|
|
||||||
|
announce 'testGetParamAddress'
|
||||||
|
for test in TESTS
|
||||||
|
actual = Params.getAddress test.query, 'addr', DEFAULT
|
||||||
|
if JSON.stringify(actual) == JSON.stringify(test.expected)
|
||||||
|
pass test.query
|
||||||
|
else
|
||||||
|
fail test.query, test.expected, actual
|
||||||
|
|
||||||
testProxyPair = ->
|
testProxyPair = ->
|
||||||
announce 'testProxyPair'
|
announce 'testProxyPair'
|
||||||
addr = Params.parseAddress '0.0.0.0:35302'
|
fakeRelay = Parse.address '0.0.0.0:12345'
|
||||||
console.log addr
|
rateLimit = new DummyRateLimit()
|
||||||
pair = new ProxyPair(null, addr, 0)
|
destination = []
|
||||||
pair.connectRelay()
|
fakeClient =
|
||||||
|
send: (d) -> destination.push d
|
||||||
|
pp = new ProxyPair(fakeClient, fakeRelay, rateLimit)
|
||||||
|
pp.connectRelay()
|
||||||
|
if null != pp.relay.onopen then pass 'relay.onopen'
|
||||||
|
else fail 'relay onopen must not be null.'
|
||||||
|
if null != pp.relay.onclose then pass 'relay.onclose'
|
||||||
|
else fail 'relay onclose must not be null.'
|
||||||
|
if null != pp.relay.onerror then pass 'relay.onerror'
|
||||||
|
else fail 'relay onerror must not be null.'
|
||||||
|
if null != pp.relay.onmessage then pass 'relay.onmessage'
|
||||||
|
else fail 'relay onmessage must not be null.'
|
||||||
|
# TODO: Test for flush
|
||||||
|
# pp.c2rSchedule.push { data: 'omg' }
|
||||||
|
# pp.flush()
|
||||||
|
# if destination == ['omg'] then pass 'flush'
|
||||||
|
# else fail 'flush', ['omg'], destination
|
||||||
|
|
||||||
testBuildUrl()
|
testBuildUrl()
|
||||||
testParseCookieString()
|
testParseCookieString()
|
||||||
testParseQueryString()
|
testParseQueryString()
|
||||||
# testProxyPair()
|
testGetParamBoolean()
|
||||||
|
testParseAddress()
|
||||||
|
testGetParamAddress()
|
||||||
|
testProxyPair()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue