diff --git a/README.md b/README.md index 6dea856..fd56c80 100644 --- a/README.md +++ b/README.md @@ -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 ===== @@ -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`. diff --git a/simple_server.py b/simple_server.py index a32af17..e085b90 100644 --- a/simple_server.py +++ b/simple_server.py @@ -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 @@ -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 = '' \ - '' - self.transport.write(policy) - self.transport.loseConnection() - - - if __name__ == "__main__": from twisted.internet import reactor @@ -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() - diff --git a/test_websocket.py b/test_websocket.py index cf32924..4ea4447 100644 --- a/test_websocket.py +++ b/test_websocket.py @@ -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 @@ -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 @@ -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 = "%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 = ( + '' + '') + self.assertEqual(policy, received) + + d.addCallback(asserts) + return d + + class WebSocketSiteTestCase(TestCase): """ Tests for L{WebSocketSite}. diff --git a/websocket.py b/websocket.py index df9eaeb..263baa5 100644 --- a/websocket.py +++ b/websocket.py @@ -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 @@ -344,6 +344,21 @@ def renderWebSocket(self): return +class _HttpChannel(HTTPChannel): + + def dataReceived(self, data): + if data.startswith(""): + + policy = ( + '' + '') + self.transport.write(policy) + self.transport.loseConnection() + else: + return HTTPChannel.dataReceived(self, data) + class WebSocketSite(Site): """ @@ -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):