从Twisted WebServer将SWF嵌入式HTML页面返回到浏览器

时间:2016-01-30 18:47:54

标签: twisted twisted.web

我正在尝试构建一个基于twisted的服务器,它将返回嵌入在html中的SWF。但是我无法做到这一点。以下是HTML代码。

<!DOCTYPE html>
 <html>
   <head>
    <meta charset="UTF-8">
    <title>Faro</title>
    <style type="text/css" media="screen">
    html, body { height:100%; background-color: #ffffff;}
    body { margin:0; padding:0; overflow:hidden; }
    #flashContent { width:100%; height:100%; }
    </style>
  </head>
  <body>
    <div id="flashContent">
        <object type="application/x-shockwave-flash" data="Game1.swf" width="860" height="640" id="Game1" style="float: none; vertical-align:middle">
            <param name="movie" value="Game1.swf" />
            <param name="quality" value="high" />
            <param name="bgcolor" value="#ffffff" />
            <param name="play" value="true" />
            <param name="loop" value="true" />
            <param name="wmode" value="window" />
            <param name="scale" value="showall" />
            <param name="menu" value="true" />
            <param name="devicefont" value="false" />
            <param name="salign" value="" />
            <param name="allowScriptAccess" value="sameDomain" />
            <a href="http://www.adobe.com/go/getflash">
                <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
            </a>
        </object>
    </div>
  </body>
 </html>

扭曲的服务器代码如下。我在render_GET中放了一个if else,因为一旦从浏览器用uri(/)发送GET请求,就会正确发送html文件。之后,服务器立即通过uri(/Game1.swf)从浏览器获取另一个GET请求。但是浏览器不播放swf文件。

from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.resource import Resource
import time
from pprint import pprint



import os.path
from twisted.python import log
import sys
log.startLogging(sys.stdout)
from swf.movie import SWF

class GameFile(Resource):
    content_type = "html"
    directory = None
    extension = None
    isLeaf = True

    def render_GET(self, request):
        pprint(request.uri)        
        if(request.uri=='/'):
            file = "./tmp/Game1.html"
            self.content_type = 'html'
        else :
            file = "E:/Dev/Server/Local/tmp/Game1.swf"
            self.content_type = 'application/x-shockwave-flash'
        x = None

        request.responseHeaders.setRawHeaders("content-type", [self.content_type])

        if ".." in file:
           request.setResponseCode(400)
           return ""

       if not os.path.isfile(file):
           request.setResponseCode(404)
           print "File not found"
           return ""
        if(request.uri=='/'):
           x = open(file).read()
        else:
           x = open(file).read()
        print x
        return x

resource = GameFile()
factory = Site(resource)
reactor.listenTCP(8880, factory)
reactor.run()

另一方面,如果我使用基本服务器从目录提供静态内容,如twistedmatrix.com中所述,并单击浏览器上列出的html文件,swf将正常播放。我真的很感谢理解/解决这个问题的任何帮助。

HTTP POST的更新

gameFile = Resource()
gameFile.putChild(b"", Simple())

class Simple(Resource):
    isLeaf = True
    def render_POST(self, request):
        return File("./tmp/Game1.html")

RESULT

Request did not return bytes
Request:
<Request at 0x14f89948 method=POST uri=/ clientproto=HTTP/1.1>

Resource:<__main__.Simple instance at 0x0000000014F89388>

Value:FilePath('E:\\Dev\\Server\\Local\\tmp\\Game1.html')

1 个答案:

答案 0 :(得分:0)

我实际上无法运行此示例。将来,当您提出问题时,请始终创建Short, Self Contained, Correct (Compilable), Example。由于我无法运行它,我无法确定完全有什么问题,但是您的代码有几个明显错误,我至少可以指出这些。

首先介绍一些与您的主要问题相关的一般现代实践:

  1. 您应该使用Endpoints而不是直接致电listenTCP
  2. 你应该使用新的,令人敬畏的twisted.logger,而不是旧的和功能不足的twisted.python.log
  3. 您应该使用react为您运行反应堆,而不是导入twisted.internet.reactor
  4. Twisted已经保护您免受路径遍历攻击(您尝试使用代码中的if ".." in file:行)。您应该使用经过良好测试的保护,而不是自己重新编写。它还使用高级API实现文件传输,与自己调用file.read()相比,它具有许多优势。这些都在twisted.web.static.File中实现。

    考虑到所有这些更正,您的代码将如下所示:

    import sys
    
    from twisted.web.server import Site
    from twisted.web.resource import Resource
    from twisted.web.static import File
    from twisted.logger import globalLogBeginner, textFileLogObserver
    from twisted.internet.endpoints import serverFromString
    from twisted.internet.task import react
    from twisted.internet.defer import Deferred
    
    globalLogBeginner.beginLoggingTo(textFileLogObserver(sys.stdout))
    
    gameFile = Resource()
    gameFile.putChild(b"", File("./tmp/Game1.html", defaultType="text/html"))
    gameFile.putChild(b"Game1.swf",
                      File("E:/Dev/Server/Local/tmp/Game1.swf",
                           defaultType='application/x-shockwave-flash'))
    
    factory = Site(gameFile)
    
    forever = Deferred() # never fires
    def main(reactor, endpointDescription="tcp:8880"):
        endpoint = serverFromString(reactor, endpointDescription)
        endpoint.listen(factory)
        return forever
    
    react(main, sys.argv[1:])
    

    正如我上面所说的,我无法运行你的例子,所以我实际上无法测试这个答案,但希望它足够接近让你开始。