mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
use coffeelint
This commit is contained in:
parent
7e5e9f9f5f
commit
bc1e147ca2
7 changed files with 179 additions and 25 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,4 +9,5 @@ server/server
|
||||||
snowflake.log
|
snowflake.log
|
||||||
proxy/test
|
proxy/test
|
||||||
proxy/build
|
proxy/build
|
||||||
|
proxy/node_modules
|
||||||
ignore/
|
ignore/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fs = require 'fs'
|
fs = require 'fs'
|
||||||
{exec} = require 'child_process'
|
{spawn, exec} = require 'child_process'
|
||||||
|
|
||||||
# All coffeescript files required.
|
# All coffeescript files required.
|
||||||
FILES = [
|
FILES = [
|
||||||
|
@ -9,6 +9,10 @@ FILES = [
|
||||||
'websocket.coffee'
|
'websocket.coffee'
|
||||||
'snowflake.coffee'
|
'snowflake.coffee'
|
||||||
]
|
]
|
||||||
|
FILES_TEST = [
|
||||||
|
'snowflake_test.coffee'
|
||||||
|
]
|
||||||
|
FILES_ALL = FILES.concat FILES_TEST
|
||||||
OUTFILE = 'build/snowflake.coffee'
|
OUTFILE = 'build/snowflake.coffee'
|
||||||
STATIC = 'static'
|
STATIC = 'static'
|
||||||
|
|
||||||
|
@ -35,6 +39,12 @@ task 'build', 'build the snowflake proxy', ->
|
||||||
compileCoffee()
|
compileCoffee()
|
||||||
console.log 'Snowflake prepared.'
|
console.log 'Snowflake prepared.'
|
||||||
|
|
||||||
|
task 'lint', 'ensure idiomatic coffeescript', ->
|
||||||
|
spawn 'coffeelint', FILES_ALL, {
|
||||||
|
file: 'coffeelint.json'
|
||||||
|
stdio: 'inherit'
|
||||||
|
}
|
||||||
|
|
||||||
task 'clean', 'remove all built files', ->
|
task 'clean', 'remove all built files', ->
|
||||||
exec 'rm -r build'
|
exec 'rm -r build'
|
||||||
exec 'rm -r test'
|
exec 'rm -r test'
|
||||||
|
|
135
proxy/coffeelint.json
Normal file
135
proxy/coffeelint.json
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
{
|
||||||
|
"arrow_spacing": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"braces_spacing": {
|
||||||
|
"level": "error",
|
||||||
|
"spaces": 1,
|
||||||
|
"empty_object_spaces": 0
|
||||||
|
},
|
||||||
|
"camel_case_classes": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"coffeescript_error": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"colon_assignment_spacing": {
|
||||||
|
"level": "ignore",
|
||||||
|
"spacing": {
|
||||||
|
"left": 0,
|
||||||
|
"right": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cyclomatic_complexity": {
|
||||||
|
"level": "ignore",
|
||||||
|
"value": 10
|
||||||
|
},
|
||||||
|
"duplicate_key": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"empty_constructor_needs_parens": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"ensure_comprehensions": {
|
||||||
|
"level": "warn"
|
||||||
|
},
|
||||||
|
"eol_last": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"indentation": {
|
||||||
|
"value": 2,
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"line_endings": {
|
||||||
|
"level": "ignore",
|
||||||
|
"value": "unix"
|
||||||
|
},
|
||||||
|
"max_line_length": {
|
||||||
|
"value": 80,
|
||||||
|
"level": "error",
|
||||||
|
"limitComments": true
|
||||||
|
},
|
||||||
|
"missing_fat_arrows": {
|
||||||
|
"level": "ignore",
|
||||||
|
"is_strict": false
|
||||||
|
},
|
||||||
|
"newlines_after_classes": {
|
||||||
|
"value": 3,
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_backticks": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_debugger": {
|
||||||
|
"level": "warn",
|
||||||
|
"console": false
|
||||||
|
},
|
||||||
|
"no_empty_functions": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_empty_param_list": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_implicit_braces": {
|
||||||
|
"level": "ignore",
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"no_implicit_parens": {
|
||||||
|
"level": "ignore",
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"no_interpolation_in_single_quotes": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_nested_string_interpolation": {
|
||||||
|
"level": "warn"
|
||||||
|
},
|
||||||
|
"no_plusplus": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_private_function_fat_arrows": {
|
||||||
|
"level": "warn"
|
||||||
|
},
|
||||||
|
"no_stand_alone_at": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_tabs": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_this": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_throwing_strings": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_trailing_semicolons": {
|
||||||
|
"level": "error"
|
||||||
|
},
|
||||||
|
"no_trailing_whitespace": {
|
||||||
|
"level": "error",
|
||||||
|
"allowed_in_comments": false,
|
||||||
|
"allowed_in_empty_lines": false
|
||||||
|
},
|
||||||
|
"no_unnecessary_double_quotes": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"no_unnecessary_fat_arrows": {
|
||||||
|
"level": "warn"
|
||||||
|
},
|
||||||
|
"non_empty_constructor_needs_parens": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"prefer_english_operator": {
|
||||||
|
"level": "ignore",
|
||||||
|
"doubleNotLevel": "ignore"
|
||||||
|
},
|
||||||
|
"space_operators": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"spacing_after_comma": {
|
||||||
|
"level": "ignore"
|
||||||
|
},
|
||||||
|
"transform_messes_up_line_numbers": {
|
||||||
|
"level": "warn"
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ class ProxyPair
|
||||||
optional: [
|
optional: [
|
||||||
{ DtlsSrtpKeyAgreement: true }
|
{ DtlsSrtpKeyAgreement: true }
|
||||||
{ RtpDataChannels: false }
|
{ RtpDataChannels: false }
|
||||||
]}
|
] }
|
||||||
@pc.onicecandidate = (evt) =>
|
@pc.onicecandidate = (evt) =>
|
||||||
# Browser sends a null candidate once the ICE gathering completes.
|
# Browser sends a null candidate once the ICE gathering completes.
|
||||||
# In this case, it makes sense to send one copy-paste blob.
|
# In this case, it makes sense to send one copy-paste blob.
|
||||||
|
@ -35,7 +35,7 @@ class ProxyPair
|
||||||
Signalling.send @pc.localDescription
|
Signalling.send @pc.localDescription
|
||||||
# OnDataChannel triggered remotely from the client when connection succeeds.
|
# OnDataChannel triggered remotely from the client when connection succeeds.
|
||||||
@pc.ondatachannel = (dc) =>
|
@pc.ondatachannel = (dc) =>
|
||||||
console.log dc;
|
console.log dc
|
||||||
channel = dc.channel
|
channel = dc.channel
|
||||||
log 'Data Channel established...'
|
log 'Data Channel established...'
|
||||||
@prepareDataChannel channel
|
@prepareDataChannel channel
|
||||||
|
@ -49,11 +49,11 @@ class ProxyPair
|
||||||
# This is the point when the WebRTC datachannel is done, so the next step
|
# This is the point when the WebRTC datachannel is done, so the next step
|
||||||
# is to establish websocket to the server.
|
# is to establish websocket to the server.
|
||||||
@connectRelay()
|
@connectRelay()
|
||||||
channel.onclose = =>
|
channel.onclose = ->
|
||||||
log 'Data channel closed.'
|
log 'Data channel closed.'
|
||||||
snowflake.state = MODE.INIT;
|
snowflake.state = MODE.INIT
|
||||||
$msglog.className = ''
|
$msglog.className = ''
|
||||||
channel.onerror = =>
|
channel.onerror = ->
|
||||||
log 'Data channel error!'
|
log 'Data channel error!'
|
||||||
channel.onmessage = @onClientToRelayMessage
|
channel.onmessage = @onClientToRelayMessage
|
||||||
|
|
||||||
|
@ -124,19 +124,28 @@ class ProxyPair
|
||||||
busy = true
|
busy = true
|
||||||
checkChunks = =>
|
checkChunks = =>
|
||||||
busy = false
|
busy = false
|
||||||
|
|
||||||
# WebRTC --> websocket
|
# WebRTC --> websocket
|
||||||
if @relayIsReady() && @relay.bufferedAmount < @MAX_BUFFER && @c2rSchedule.length > 0
|
if @relayIsReady() &&
|
||||||
|
@relay.bufferedAmount < @MAX_BUFFER &&
|
||||||
|
@c2rSchedule.length > 0
|
||||||
chunk = @c2rSchedule.shift()
|
chunk = @c2rSchedule.shift()
|
||||||
@rateLimit.update chunk.length
|
@rateLimit.update chunk.length
|
||||||
@relay.send chunk
|
@relay.send chunk
|
||||||
busy = true
|
busy = true
|
||||||
|
|
||||||
# websocket --> WebRTC
|
# websocket --> WebRTC
|
||||||
if @webrtcIsReady() && @client.bufferedAmount < @MAX_BUFFER && @r2cSchedule.length > 0
|
if @webrtcIsReady() &&
|
||||||
|
@client.bufferedAmount < @MAX_BUFFER &&
|
||||||
|
@r2cSchedule.length > 0
|
||||||
chunk = @r2cSchedule.shift()
|
chunk = @r2cSchedule.shift()
|
||||||
@rateLimit.update chunk.length
|
@rateLimit.update chunk.length
|
||||||
@client.send chunk
|
@client.send chunk
|
||||||
busy = true
|
busy = true
|
||||||
|
|
||||||
checkChunks() while busy && !@rateLimit.isLimited()
|
checkChunks() while busy && !@rateLimit.isLimited()
|
||||||
|
|
||||||
if @r2cSchedule.length > 0 || @c2rSchedule.length > 0 || (@relayIsReady() && @relay.bufferedAmount > 0) || (@webrtcIsReady() && @client.bufferedAmount > 0)
|
if @r2cSchedule.length > 0 || @c2rSchedule.length > 0 ||
|
||||||
|
(@relayIsReady() && @relay.bufferedAmount > 0) ||
|
||||||
|
(@webrtcIsReady() && @client.bufferedAmount > 0)
|
||||||
@flush_timeout_id = setTimeout @flush, @rateLimit.when() * 1000
|
@flush_timeout_id = setTimeout @flush, @rateLimit.when() * 1000
|
||||||
|
|
|
@ -69,7 +69,8 @@ class Snowflake
|
||||||
|
|
||||||
rateLimitBytes = undefined
|
rateLimitBytes = undefined
|
||||||
if 'off' != query['ratelimit']
|
if 'off' != query['ratelimit']
|
||||||
rateLimitBytes = Params.getByteCount(query, 'ratelimit', DEFAULT_RATE_LIMIT)
|
rateLimitBytes = Params.getByteCount(query, 'ratelimit',
|
||||||
|
DEFAULT_RATE_LIMIT)
|
||||||
if undefined == rateLimitBytes
|
if undefined == rateLimitBytes
|
||||||
@rateLimit = new DummyRateLimit()
|
@rateLimit = new DummyRateLimit()
|
||||||
else
|
else
|
||||||
|
@ -125,7 +126,7 @@ class Snowflake
|
||||||
params.push ['transport', 'webrtc']
|
params.push ['transport', 'webrtc']
|
||||||
|
|
||||||
makeProxyPair: (relay) ->
|
makeProxyPair: (relay) ->
|
||||||
pair = new ProxyPair(null, relay, @rateLimit);
|
pair = new ProxyPair null, relay, @rateLimit
|
||||||
@proxyPairs.push pair
|
@proxyPairs.push pair
|
||||||
pair.onCleanup = (event) =>
|
pair.onCleanup = (event) =>
|
||||||
# Delete from the list of active proxy pairs.
|
# Delete from the list of active proxy pairs.
|
||||||
|
@ -224,7 +225,7 @@ init = ->
|
||||||
|
|
||||||
$input = document.getElementById('input')
|
$input = document.getElementById('input')
|
||||||
$input.focus()
|
$input.focus()
|
||||||
$input.onkeydown = (e) => $send.onclick() if 13 == e.keyCode # enter
|
$input.onkeydown = (e) -> $send.onclick() if 13 == e.keyCode # enter
|
||||||
|
|
||||||
snowflake = new Snowflake()
|
snowflake = new Snowflake()
|
||||||
window.snowflake = snowflake
|
window.snowflake = snowflake
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
window = {}
|
window = {}
|
||||||
|
|
||||||
VERBOSE = false
|
VERBOSE = false
|
||||||
if process.argv.indexOf('-v') >= 0
|
VERBOSE = true if process.argv.indexOf('-v') >= 0
|
||||||
VERBOSE = true
|
|
||||||
numTests = 0
|
numTests = 0
|
||||||
numFailed = 0
|
numFailed = 0
|
||||||
|
|
||||||
announce = (testName) ->
|
announce = (testName) ->
|
||||||
if VERBOSE
|
console.log '\n --- ' + testName + ' ---' if VERBOSE
|
||||||
console.log '\n --- ' + testName + ' ---'
|
|
||||||
|
|
||||||
pass = (test) ->
|
pass = (test) ->
|
||||||
numTests++;
|
numTests++
|
||||||
if VERBOSE
|
console.log 'PASS ' + test if VERBOSE
|
||||||
console.log 'PASS ' + test
|
|
||||||
|
|
||||||
fail = (test, expected, actual) ->
|
fail = (test, expected, actual) ->
|
||||||
numTests++
|
numTests++
|
||||||
|
@ -88,10 +86,10 @@ http://www.ietf.org/rfc/rfc2965.txt for the grammar.
|
||||||
testParseCookieString = ->
|
testParseCookieString = ->
|
||||||
TESTS = [{
|
TESTS = [{
|
||||||
cs: ''
|
cs: ''
|
||||||
expected: { }
|
expected: {}
|
||||||
},{
|
},{
|
||||||
cs: 'a=b'
|
cs: 'a=b'
|
||||||
expected: { a: 'b'}
|
expected: { a: 'b' }
|
||||||
},{
|
},{
|
||||||
cs: 'a=b=c'
|
cs: 'a=b=c'
|
||||||
expected: { a: 'b=c' }
|
expected: { a: 'b=c' }
|
||||||
|
@ -103,7 +101,7 @@ testParseCookieString = ->
|
||||||
expected: { a: 'b', c: 'd' }
|
expected: { a: 'b', c: 'd' }
|
||||||
},{
|
},{
|
||||||
cs: 'a= b',
|
cs: 'a= b',
|
||||||
expected: {a: 'b' }
|
expected: { a: 'b' }
|
||||||
},{
|
},{
|
||||||
cs: 'a='
|
cs: 'a='
|
||||||
expected: { a: '' }
|
expected: { a: '' }
|
||||||
|
@ -271,7 +269,7 @@ testParseAddress = ->
|
||||||
testGetParamAddress = ->
|
testGetParamAddress = ->
|
||||||
DEFAULT = { host: '1.1.1.1', port: 2222 }
|
DEFAULT = { host: '1.1.1.1', port: 2222 }
|
||||||
TESTS = [{
|
TESTS = [{
|
||||||
query: { }
|
query: {}
|
||||||
expected: DEFAULT
|
expected: DEFAULT
|
||||||
},{
|
},{
|
||||||
query: { addr: '3.3.3.3:4444' },
|
query: { addr: '3.3.3.3:4444' },
|
||||||
|
|
|
@ -103,8 +103,8 @@ Params =
|
||||||
return null
|
return null
|
||||||
|
|
||||||
# Get an object value and parse it as a byte count. Example byte counts are
|
# 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
|
# '100' and '1.3m'. Returns |defaultValue| if param is not a key. Return null
|
||||||
# a parsing error.
|
# on a parsing error.
|
||||||
getByteCount: (query, param, defaultValue) ->
|
getByteCount: (query, param, defaultValue) ->
|
||||||
spec = query[param]
|
spec = query[param]
|
||||||
return defaultValue if undefined == spec
|
return defaultValue if undefined == spec
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue