When I load a html page I have a 5 strings written about a second apart.
<br>1</br>
...... 1 second ......
<br>2</br>
...... 1 second ......
<br>3</br>
...... 1 second ......
<br>4</br>
...... 1 second ......
<br>5</br>
...... 1 second ......
--- end request ---
Chromium and Firefox both load and display the first br then the next as received. (Firefox requires a content encoding however). But Safari refuses to display any of the tags until the request is ended.
Chromium seems to just do it.
Firefox first needs to determine the content encoding https://bugzilla.mozilla.org/show_bug.cgi?id=647203
But Safari seems to just refuse. Is a different response code or header needed? I try setting explicitly the content type to text/html. Didn't work.
I have confirmed in Wireshark that the strings are being sent a second apart, i.e they are not being cached and sent all at once.
I have also confirmed this occurs if I go through localhost or I use my public ip address.
I have tried content-length and keep alive, former just closes request automatically, latter seems to have no effect.
Headers and Responses from Wireshark
Firefox (working)
GET /pe HTTP/1.1
Host: 127.0.01:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cache-Control: max-age=0
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 17:10:20 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Server: TwistedWeb/13.2.0
1f
<html>
<title>PE</title>
<body>
2e
<br> This is the 1th time I've written. </br>
2e
<br> This is the 2th time I've written. </br>
2e
<br> This is the 3th time I've written. </br>
2e
<br> This is the 4th time I've written. </br>
2e
<br> This is the 5th time I've written. </br>
8
</body>
8
</html>
0
Safari (not working)
GET /pe HTTP/1.1
Host: 127.0.0.01:8080
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56
Accept-Language: en-us
DNT: 1
Connection: keep-alive
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 17:12:55 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Server: TwistedWeb/13.2.0
1f
<html>
<title>PE</title>
<body>
2e
<br> This is the 1th time I've written. </br>
2e
<br> This is the 2th time I've written. </br>
2e
<br> This is the 3th time I've written. </br>
2e
<br> This is the 4th time I've written. </br>
2e
<br> This is the 5th time I've written. </br>
8
</body>
8
</html>
0
Demo
import twisted
from twisted.python import log
import sys
log.startLogging(sys.stdout)
from twisted.web.server import Site, NOT_DONE_YET
from twisted.web.resource import Resource
from twisted.internet import reactor
class PersistantExample(Resource):
'''Gives an example of a persistant request'''
# does not exist on Safari until stopping browser / ending connection
isLeaf = True
def render_GET(self, request):
log.msg("Ooooh a render request")
# schedule the reoccuring thing (this could be something else like a deferred result)
reactor.callLater(1.1, self.keeps_going, request, 0) # 1.1 seconds just to show it can take floats
# firefox require the char set see https://bugzilla.mozilla.org/show_bug.cgi?id=647203
request.responseHeaders.addRawHeader("Content-Type",
"text/html; charset=utf-8") # set the MIME header (charset needed for firefox)
# this will cause the connection to keep only open for x length
# (only helpful if the length is known, also does NOT make it render right away)
# request.responseHeaders.addRawHeader("Content-Length", "150")
request.write("<html>\n<title>PE</title>\n<body>")
return NOT_DONE_YET
def keeps_going(self, request, i):
log.msg("I'm going again....")
i = i + 1
request.write("\n<br> This is the %sth time I've written. <br>" % i) ## probably not best to use <br> tag
if i < 5:
reactor.callLater(1.1, self.keeps_going, request, i) # 1.1 seconds just to show it can take floats
if i >= 5 and not request.finished:
log.msg("Done")
request.write("\n</body>")
request.write("\n</html>")
# safari will only render when finished
request.finish()
class Root(Resource):
isLeaf = False
def render_GET(self, request):
return "<html><body>Demo is <a href=\"pe\">here</a></body></html>"
class Site(Site):
pass
root = Root()
pe = PersistantExample()
site = Site(root)
root.putChild("", root)
root.putChild("index", root)
root.putChild("pe", pe)
# listen
if __name__ == "__main__":
reactor.listenTCP(8080, site)
reactor.run()
, then
– Zimm3r Nov 15 '15 at 20:17