我正在尝试构建一个基于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将正常播放。我真的很感谢理解/解决这个问题的任何帮助。
gameFile = Resource()
gameFile.putChild(b"", Simple())
class Simple(Resource):
isLeaf = True
def render_POST(self, request):
return File("./tmp/Game1.html")
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')
答案 0 :(得分:0)
我实际上无法运行此示例。将来,当您提出问题时,请始终创建Short, Self Contained, Correct (Compilable), Example。由于我无法运行它,我无法确定完全有什么问题,但是您的代码有几个明显错误,我至少可以指出这些。
首先介绍一些与您的主要问题相关的一般现代实践:
listenTCP
。twisted.logger
,而不是旧的和功能不足的twisted.python.log
。react
为您运行反应堆,而不是导入twisted.internet.reactor
。 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:])
正如我上面所说的,我无法运行你的例子,所以我实际上无法测试这个答案,但希望它足够接近让你开始。