From d576f8a77d3ce884711a5ac29d963fc832262d0c Mon Sep 17 00:00:00 2001 From: Marek Kowalski Date: Thu, 16 Feb 2012 11:10:01 +0100 Subject: [PATCH] WebSocketSite serves also the flash policy file. This removes the necessity of having aditional server listening on port 843, which required root priviliges. It can be done like this according to the article: http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html. --- README.md | 7 ++----- simple_server.py | 20 -------------------- test_websocket.py | 44 +++++++++++++++++++++++++++++++++++++++++++- websocket.py | 18 +++++++++++++++++- 4 files changed, 62 insertions(+), 27 deletions(-) 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):