[tor-commits] [snowflake/master] broker successfully passing client offers to snowflake proxy (#1)
arlo at torproject.org
arlo at torproject.org
Thu Jan 21 22:15:14 UTC 2016
commit 7081e6328c34db31fec437aabaac829a9280e0f9
Author: Serene Han <keroserene+git at gmail.com>
Date: Thu Jan 21 11:40:42 2016 -0800
broker successfully passing client offers to snowflake proxy (#1)
---
broker/snowflake-broker.go | 11 ++++----
proxy/broker.coffee | 64 +++++++++++++++++++++++++-------------------
proxy/snowflake.coffee | 48 +++++++++++++++++++++++----------
3 files changed, 76 insertions(+), 47 deletions(-)
diff --git a/broker/snowflake-broker.go b/broker/snowflake-broker.go
index 279b2b6..1d26eb1 100644
--- a/broker/snowflake-broker.go
+++ b/broker/snowflake-broker.go
@@ -2,7 +2,7 @@ package snowflake_broker
import (
"container/heap"
- "fmt"
+ // "fmt"
"io/ioutil"
"log"
"net"
@@ -104,8 +104,8 @@ func clientHandler(w http.ResponseWriter, r *http.Request) {
// TODO: Make this much better.
snowflake := heap.Pop(snowflakes).(*Snowflake)
if nil == snowflake {
+ // w.Header().Set("Status", http.StatusServiceUnavailable)
w.Write([]byte("no snowflake proxies available"))
- // w.WriteHeader(http.StatusServiceUnavailable)
return
}
// snowflakes = snowflakes[1:]
@@ -135,10 +135,11 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Passing client offer to snowflake.")
w.Write(offer)
case <-time.After(time.Second * 10):
- s := fmt.Sprintf("%d snowflakes left.", snowflakes.Len())
- w.Write([]byte("timed out. " + s))
+ // s := fmt.Sprintf("%d snowflakes left.", snowflakes.Len())
+ // w.Write([]byte("timed out. " + s))
+ // w.Header().Set("Status", http.StatusRequestTimeout)
+ w.WriteHeader(http.StatusGatewayTimeout)
heap.Remove(snowflakes, snowflake.index)
- // w.WriteHeader(http.StatusRequestTimeout)
}
}
diff --git a/proxy/broker.coffee b/proxy/broker.coffee
index 9432e5c..688d45d 100644
--- a/proxy/broker.coffee
+++ b/proxy/broker.coffee
@@ -5,43 +5,51 @@ Browser snowflakes must register with the broker in order
to get assigned to clients.
###
+STATUS_OK = 200
+STATUS_GATEWAY_TIMEOUT = 504
+
# Represents a broker running remotely.
class Broker
+
+ clients: 0
+
# When interacting with the Broker, snowflake must generate a unique session
# ID so the Broker can keep track of which signalling channel it's speaking
# to.
constructor: (@url) ->
log 'Using Broker at ' + @url
+ clients = 0
# Snowflake registers with the broker using an HTTP POST request, and expects
- # a response from the broker containing some client offer
- register: ->
- # base_url = this.fac_url.replace(/\?.*/, "");
- # url = base_url + "?" + build_query_string(params);
- xhr = new XMLHttpRequest()
- try
- xhr.open 'POST', @url
- catch err
- ###
- An exception happens here when, for example, NoScript allows the domain on
- which the proxy badge runs, but not the domain to which it's trying to
- make the HTTP request. The exception message is like "Component returned
- failure code: 0x805e0006 [nsIXMLHttpRequest.open]" on Firefox.
- ###
- log 'Broker: exception while connecting: ' + err.message
- return
-
- # xhr.responseType = 'text'
- xhr.onreadystatechange = ->
- if xhr.DONE == xhr.readyState
- log 'Broker: ' + xhr.status
- if 200 == xhr.status
- log 'Response: ' + xhr.responseText
- log xhr
- else
- log 'Broker error ' + xhr.status + ' - ' + xhr.statusText
- xhr.send 'snowflake-testing'
- log "Broker: sent a registration message, waiting for reply..."
+ # a response from the broker containing some client offer.
+ # TODO: Actually support multiple clients.
+ getClientOffer: ->
+ new Promise (fulfill, reject) =>
+ xhr = new XMLHttpRequest()
+ try
+ xhr.open 'POST', @url
+ catch err
+ ###
+ An exception happens here when, for example, NoScript allows the domain
+ on which the proxy badge runs, but not the domain to which it's trying
+ to make the HTTP request. The exception message is like "Component
+ returned failure code: 0x805e0006 [nsIXMLHttpRequest.open]" on Firefox.
+ ###
+ log 'Broker: exception while connecting: ' + err.message
+ return
+ xhr.onreadystatechange = ->
+ return if xhr.DONE != xhr.readyState
+ switch xhr.status
+ when STATUS_OK
+ fulfill xhr.responseText # Should contain offer.
+ when STATUS_GATEWAY_TIMEOUT
+ reject 'Timed out waiting for a client to serve. Retrying...'
+ else
+ log 'Broker ERROR: Unexpected ' + xhr.status +
+ ' - ' + xhr.statusText
+
+ xhr.send 'snowflake-testing'
+ log "Broker: polling for client offer..."
sendAnswer: (answer) ->
log 'Sending answer to broker.'
diff --git a/proxy/snowflake.coffee b/proxy/snowflake.coffee
index 1b837d5..646b9b4 100644
--- a/proxy/snowflake.coffee
+++ b/proxy/snowflake.coffee
@@ -9,6 +9,7 @@ this must always act as the answerer.
###
DEFAULT_WEBSOCKET = '192.81.135.242:9901'
DEFAULT_BROKER = 'https://snowflake-reg.appspot.com/proxy'
+COPY_PASTE_ENABLED = false
DEFAULT_PORTS =
http: 80
https: 443
@@ -58,7 +59,7 @@ class Snowflake
$badge: null
state: MODE.INIT
- constructor: ->
+ constructor: (@broker) ->
if HEADLESS
# No badge
else if DEBUG
@@ -98,6 +99,27 @@ class Snowflake
@makeProxyPair @relayAddr
@proxyPair = @proxyPairs[0]
+ # Poll broker for clients.
+ findClients: ->
+ poll = =>
+ recv = broker.getClientOffer()
+ recv.then((desc) =>
+ log 'Received:\n\n' + desc + '\n'
+ offer = JSON.parse desc
+ @receiveOffer offer
+ , (err) ->
+ log err
+ setTimeout(poll, 1000)
+ )
+ poll()
+
+ # if @proxyPairs.length >= MAX_NUM_CLIENTS * CONNECTIONS_PER_CLIENT
+ # setTimeout(@proxyMain, @broker_poll_interval * 1000)
+ # return
+ # params = [['r', '1']]
+ # params.push ['transport', 'websocket']
+ # params.push ['transport', 'webrtc']
+
# Receive an SDP offer from client plugin.
receiveOffer: (desc) =>
sdp = new RTCSessionDescription desc
@@ -117,14 +139,6 @@ class Snowflake
promise = @proxyPair.pc.createAnswer next
promise.then next if promise
- # Poll broker when this snowflake can support more clients.
- proxyMain: ->
- if @proxyPairs.length >= MAX_NUM_CLIENTS * CONNECTIONS_PER_CLIENT
- setTimeout(@proxyMain, @broker_poll_interval * 1000)
- return
- params = [['r', '1']]
- params.push ['transport', 'websocket']
- params.push ['transport', 'webrtc']
makeProxyPair: (relay) ->
pair = new ProxyPair null, relay, @rateLimit
@@ -156,6 +170,7 @@ class Snowflake
@badge.die() if @badge
snowflake = null
+broker = null
#
## -- DOM & Inputs -- #
@@ -170,7 +185,9 @@ Interface =
# Local input from keyboard into message window.
acceptInput: ->
msg = $input.value
- switch snowflake.state
+ if !COPY_PASTE_ENABLED
+ log 'No input expected - Copy Paste Signalling disabled.'
+ else switch snowflake.state
when MODE.INIT
# Set target relay.
if !(snowflake.setRelayAddr msg)
@@ -224,10 +241,13 @@ init = ->
$input.onkeydown = (e) -> $send.onclick() if 13 == e.keyCode # enter
log '== snowflake browser proxy =='
- snowflake = new Snowflake()
- window.snowflake = snowflake
broker = new Broker DEFAULT_BROKER
- broker.register()
- log 'Input desired relay address:'
+ snowflake = new Snowflake(broker)
+ window.snowflake = snowflake
+ if COPY_PASTE_ENABLED
+ log 'Input desired relay address:'
+ else
+ snowflake.setRelayAddr DEFAULT_WEBSOCKET
+ snowflake.findClients()
window.onload = init if window
More information about the tor-commits
mailing list