0

I am trying to build a server based on twisted which will return an SWF embeded in html. However I am unable to achieve this. Following is the HTML code .

<!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>

The twisted server code is as follows. I have put an if else in render_GET because the html file is being sent properly once the GET request is sent from the browser with uri (/) . And immediately after that the server is getting another GET request from the browser with uri (/Game1.swf) . However the browser doesn't play the swf file.

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()

On the other hand, if I use a basic server to serve static content from a directory, as explained in twistedmatrix.com, and click on the html file listed on the browser, the swf plays properly. I really appreciate any help in understanding/fixing this issue.

Updates for 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')
Learner
  • 157
  • 3
  • 15

1 Answers1

0

I cannot actually run this example. In the future, when you ask questions, always create a Short, Self Contained, Correct (Compilable), Example. Since I can't run it, I can't be sure exactly what is wrong, but there are several things obviously wrong with your code, and I can at least point out those.

Starting first with some general modern practices that are tangential to your main problem:

  1. You should be using Endpoints and not calling listenTCP directly.
  2. You should be using the new, awesome twisted.logger and not the old and feature-poor twisted.python.log.
  3. You should be using react, which runs the reactor for you, and not importing twisted.internet.reactor.

Twisted already protects you against path-traversal attacks (the thing you're trying to do with the if ".." in file: line in your code). You should use that well-tested protection and not re-write it yourself. It also implements file-transfer with a high-level API, which has many advantages over calling file.read() yourself. These are both implemented in twisted.web.static.File.

Taking into account all of these corrections, your code would look something like this:

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:])

As I said above, I can't run your example, so I can't actually test this answer, but hopefully it will be close enough to get you started.

Glyph
  • 31,152
  • 11
  • 87
  • 129
  • Hi Glyph, Thanks for the quick response. Though the suggested code didn't solve the problem completely, It has given me a good direction. I will go through all your suggestions and try to figure out the problem myself before I revert back. Also I couldn't find beginLoggingTo though I could import textFileLogObserver – Learner Jan 31 '16 at 00:02
  • You're right, `beginLoggingTo` is a method on `globalLogBeginner`, not a free function. Corrected the code sample. – Glyph Jan 31 '16 at 12:11
  • Hi Glyph, Using your suggestions I am able to send the html file and embeded swf over browser for HTTP GET requests. However I am facing problem for HTTP POST. Updated my question with code for HTTP POST – Learner Feb 01 '16 at 14:38