Skip to content

Commit

Permalink
Implement parts of OONI Backend.
Browse files Browse the repository at this point in the history
* Write an HTTP server that replies with the headers sent by the browser
* Write a Proxy DNS server that proxies requests and writes to log
  • Loading branch information
Arturo Filastò committed May 28, 2012
1 parent 7a60f4c commit c042338
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 12 deletions.
Empty file added backend/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions backend/dnsbackend.py
@@ -0,0 +1,16 @@
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
from twisted.names import dns
from twisted.names import client, server

class ProxyDNSServer(server.DNSServerFactory):
def __init__(self, authorities = None,
caches = None, clients = None,
verbose = 0):
resolver = client.Resolver(servers=[('8.8.8.8', 53)])
server.DNSServerFactory.__init__(self, authorities = authorities,
caches = caches, clients = [resolver],
verbose = verbose)
def handleQuery(self, message, protocol, address):
print message, protocol, address
server.DNSServerFactory.handleQuery(self, message, protocol, address)
74 changes: 74 additions & 0 deletions backend/httpbackend.py
@@ -0,0 +1,74 @@
import json
import random
import string

from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
from twisted.web import resource, server, static
from twisted.web.microdom import escape

server.version = "Apache"

class HTTPRandomPage(resource.Resource):
"""
This generates a random page of arbitrary length and containing the string
selected by the user.
The format is the following:
/random/<length>/<keyword>
"""
isLeaf = True
def _gen_random_string(self, length):
return ''.join(random.choice(string.letters) for x in range(length))

def genRandomPage(self, length=100, keyword=None):
data = self._gen_random_string(length/2)
if keyword:
data += keyword
data += self._gen_random_string(length - length/2)
data += '\n'
return data

def render(self, request):
length = 100
keyword = None
path_parts = request.path.split('/')
if len(path_parts) > 2:
length = int(path_parts[2])
if length > 100000:
length = 100000

if len(path_parts) > 3:
keyword = escape(path_parts[3])

return self.genRandomPage(length, keyword)

class HTTPReturnHeaders(resource.Resource):
"""
This returns the headers being sent by the client in JSON format.
"""
isLeaf = True
def render(self, request):
req_headers = request.getAllHeaders()
return json.dumps(req_headers)

class HTTPSendHeaders(resource.Resource):
"""
This sends to the client the headers that they send inside of the POST
request encoded in json.
"""
isLeaf = True
def render_POST(self, request):
headers = json.loads(request.content.read())
for header, value in headers.items():
request.setHeader(str(header), str(value))
return ''

class HTTPBackend(resource.Resource):
def __init__(self):
resource.Resource.__init__(self)
self.putChild('random', HTTPRandomPage())
self.putChild('returnheaders', HTTPReturnHeaders())
self.putChild('sendheaders', HTTPSendHeaders())


34 changes: 34 additions & 0 deletions backend/oonibackend.py
@@ -0,0 +1,34 @@
"""
ooni backend
************
This is the backend system responsible for running certain services that
are useful for censorship detection.
"""
import json
import random
import string

from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
from twisted.web import resource, server, static
from twisted.web.microdom import escape
from twisted.names import dns

from backend.httpbackend import HTTPBackend
from backend.dnsbackend import ProxyDNSServer

# This tells twisted to set the
server.version = "Apache"

application = service.Application('oonibackend')
serviceCollection = service.IServiceCollection(application)
internet.TCPServer(8000, server.Site(HTTPBackend())).setServiceParent(serviceCollection)

# Start the DNS Server related services
TCPDNSServer = ProxyDNSServer()
internet.TCPServer(8002, TCPDNSServer).setServiceParent(serviceCollection)
UDPFactory = dns.DNSDatagramProtocol(TCPDNSServer)
internet.UDPServer(5353, UDPFactory).setServiceParent(serviceCollection)

16 changes: 4 additions & 12 deletions plugoo/tests.py
Expand Up @@ -186,31 +186,23 @@ def finished(self, result):
result['start_time'] = self.start_time
result['end_time'] = self.end_time
result['run_time'] = self.end_time - self.start_time
return self.d.callback(result)

def _do_experiment(self):
self.d_experiment = defer.Deferred()
self.d_experiment.addCallback(self._do_control)
self.experiment()
self.d = defer.maybeDeferred(self.experiment)
self.d.addCallback(self.control)
self.d.addCallback(self.finished)
return self.d

def _do_control(self, exp):
self.control(exp)
self.finished(dict())

def control(self, exp):
print "Doing control..."
self.d.callback(result)

def experiment(self):
print "Doing experiment"
self.d_experiment.callback(None)

def startTest(self):
print "Starting test %s" % repr(self)
self.d = defer.Deferred()
result = {}
#reactor.callLater(2.0, self.finished, result)
# Start experiment
return self._do_experiment()

class TwistedTestFactory(object):
Expand Down

0 comments on commit c042338

Please sign in to comment.