Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ Twisted WebSocket Server

To run:

$ sudo python simple_server.py
$ python simple_server.py

In your browser go to http://localhost:8080.

N.B.: Why sudo? It's because the simple server hosts a flash socket policy file on port
843. This is optional, of course.

Notes
=====

Expand All @@ -26,7 +23,7 @@ of Chrome 6.

If using browsers that do *not* support WebSockets, consider using a fallabck
implementation to Flash, as seen in http://github.com/gimite/web-socket-js. The
bundled `test_server.py` will also start a simple Flash Socket Policy server
bundled `test_server.py` also serves a flash socket policy file
(see http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html)
and should be immediately usable with `web-socket-js`.

20 changes: 0 additions & 20 deletions simple_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

from datetime import datetime

from twisted.internet.protocol import Protocol, Factory
from twisted.web import resource
from twisted.web.static import File
from twisted.internet import task

Expand Down Expand Up @@ -50,19 +48,6 @@ def connectionLost(self, reason):
# here is a good place to deregister this handler object


class FlashSocketPolicy(Protocol):
""" A simple Flash socket policy server.
See: http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
"""
def connectionMade(self):
policy = '<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM ' \
'"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">' \
'<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>'
self.transport.write(policy)
self.transport.loseConnection()



if __name__ == "__main__":
from twisted.internet import reactor

Expand All @@ -72,9 +57,4 @@ def connectionMade(self):
site = WebSocketSite(root)
site.addHandler('/test', Testhandler)
reactor.listenTCP(8080, site)
# run policy file server
factory = Factory()
factory.protocol = FlashSocketPolicy
reactor.listenTCP(843, factory)
reactor.run()

44 changes: 43 additions & 1 deletion test_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from twisted.internet.main import CONNECTION_DONE
from twisted.internet.error import ConnectionDone
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet import reactor, defer
from twisted.python.failure import Failure

from websocket import WebSocketHandler, WebSocketFrameDecoder
Expand All @@ -17,7 +19,7 @@
from websocket import DecodingError, OPCODE_PING, OPCODE_TEXT

from twisted.web.resource import Resource
from twisted.web.server import Request, Site
from twisted.web.server import Request
from twisted.web.test.test_web import DummyChannel
from twisted.trial.unittest import TestCase

Expand Down Expand Up @@ -75,6 +77,46 @@ def connectionLost(self, reason):



class TestGettingPolicyFile(TestCase):

def setUp(self):
self.listener = reactor.listenTCP(0, WebSocketSite(Resource()))
self.addCleanup(self.listener.stopListening)

def testGetPolicyFile(self):

class PolicyRequest(Protocol):

def __init__(self, deffered):
self.done = deffered

def connectionMade(self):
request = "<policy-file-request/>%c" % (0, )
self.transport.write(request)

def dataReceived(self, data):
self.transport.loseConnection()
self.done.callback(data)

d = defer.Deferred()
factory = ClientFactory()
factory.protocol = lambda : PolicyRequest(d)

port = self.listener._realPortNumber
reactor.connectTCP('127.0.0.1', port, factory)

def asserts(received):
policy = (
'<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM '
'"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">'
'<cross-domain-policy><allow-access-from domain="*" '
'to-ports="*" /></cross-domain-policy>')
self.assertEqual(policy, received)

d.addCallback(asserts)
return d


class WebSocketSiteTestCase(TestCase):
"""
Tests for L{WebSocketSite}.
Expand Down
18 changes: 17 additions & 1 deletion websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from twisted.internet import interfaces
from twisted.python import log
from twisted.web._newclient import makeStatefulDispatcher
from twisted.web.http import datetimeToString
from twisted.web.http import datetimeToString, HTTPChannel
from twisted.web.http import _IdentityTransferDecoder
from twisted.web.server import Request, Site, version, unquote
from zope.interface import implements
Expand Down Expand Up @@ -344,6 +344,21 @@ def renderWebSocket(self):
return


class _HttpChannel(HTTPChannel):

def dataReceived(self, data):
if data.startswith("<policy-file-request/>"):

policy = (
'<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM '
'"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">'
'<cross-domain-policy><allow-access-from domain="*" '
'to-ports="*" /></cross-domain-policy>')
self.transport.write(policy)
self.transport.loseConnection()
else:
return HTTPChannel.dataReceived(self, data)


class WebSocketSite(Site):
"""
Expand All @@ -355,6 +370,7 @@ class WebSocketSite(Site):
@type supportedProtocols: C{list}
"""
requestFactory = WebSocketRequest
protocol = _HttpChannel

def __init__(self, resource, logPath=None, timeout=60*60*12,
supportedProtocols=None):
Expand Down