1from twisted.trial import unittest
2import os
3from nevow import static, util, context, testutil
4
5
6def deferredRender(res, req):
7    d = util.maybeDeferred(res.renderHTTP,
8        context.PageContext(
9            tag=res, parent=context.RequestContext(
10                tag=req)))
11
12    def done(result):
13        if isinstance(result, str):
14            req.write(result)
15        return req
16    d.addCallback(done)
17    return d
18
19class Range(unittest.TestCase):
20    def setUp(self):
21        self.tmpdir = self.mktemp()
22        os.mkdir(self.tmpdir)
23        name = os.path.join(self.tmpdir, 'junk')
24        f = file(name, 'w')
25        f.write(800 * '0123456789')
26        f.close()
27        self.file = static.File(name)
28        self.request = testutil.FakeRequest()
29
30    def testBodyLength(self):
31        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-1999'])
32        return deferredRender(self.file, self.request).addCallback(
33            lambda r: self.assertEquals(len(r.v), 2000))
34
35    def testBodyContent(self):
36        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-1999'])
37        return deferredRender(self.file, self.request).addCallback(
38            lambda r: self.assertEquals(r.v, 200 * '0123456789'))
39
40    def testContentLength(self):
41        """Content-Length of a request is correct."""
42        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-1999'])
43        return deferredRender(self.file, self.request).addCallback(
44            lambda r: self.assertEquals(
45                r.responseHeaders.getRawHeaders('content-length'), ['2000']))
46
47    def testContentRange(self):
48        """Content-Range of a request is correct."""
49        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-1999'])
50        return deferredRender(self.file, self.request).addCallback(
51            lambda r: self.assertEquals(
52                r.responseHeaders.getRawHeaders('content-range'),
53                ['bytes 0-1999/8000']))
54
55    def testBodyLength_offset(self):
56        self.request.requestHeaders.setRawHeaders('range', ['bytes=3-10'])
57        return deferredRender(self.file, self.request).addCallback(
58            lambda r: self.assertEquals(len(r.v), 8))
59
60    def testBodyContent_offset(self):
61        self.request.requestHeaders.setRawHeaders('range', ['bytes=3-10'])
62        return deferredRender(self.file, self.request).addCallback(
63            lambda r: self.assertEquals(r.v, '34567890'))
64
65    def testContentLength_offset(self):
66        """Content-Length of a request is correct."""
67        self.request.requestHeaders.setRawHeaders('range', ['bytes=3-10'])
68        return deferredRender(self.file, self.request).addCallback(
69            lambda r: self.assertEquals(
70                r.responseHeaders.getRawHeaders('content-length'), ['8']))
71
72    def testContentRange_offset(self):
73        """Content-Range of a request is correct."""
74        self.request.requestHeaders.setRawHeaders('range', ['bytes=3-10'])
75        return deferredRender(self.file, self.request).addCallback(
76            lambda r: self.assertEquals(
77                r.responseHeaders.getRawHeaders('content-range'),
78                ['bytes 3-10/8000']))
79
80    def testBodyLength_end(self):
81        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-7999'])
82        return deferredRender(self.file, self.request).addCallback(
83            lambda r: self.assertEquals(len(r.v), 9))
84
85    def testBodyContent_end(self):
86        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-7999'])
87        return deferredRender(self.file, self.request).addCallback(
88            lambda r: self.assertEquals(r.v, '123456789'))
89
90    def testContentLength_end(self):
91        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-7999'])
92        return deferredRender(self.file, self.request).addCallback(
93            lambda r: self.assertEquals(
94                r.responseHeaders.getRawHeaders('content-length'), ['9']))
95
96    def testContentRange_end(self):
97        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-7999'])
98        return deferredRender(self.file, self.request).addCallback(
99            lambda r: self.assertEquals(
100                r.responseHeaders.getRawHeaders('content-range'),
101                ['bytes 7991-7999/8000']))
102
103    def testBodyLength_openEnd(self):
104        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-'])
105        return deferredRender(self.file, self.request).addCallback(
106            lambda r: self.assertEquals(len(r.v), 9))
107
108    def testBodyContent_openEnd(self):
109        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-'])
110        return deferredRender(self.file, self.request).addCallback(
111            lambda r: self.assertEquals(r.v, '123456789'))
112
113    def testContentLength_openEnd(self):
114        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-'])
115        return deferredRender(self.file, self.request).addCallback(
116            lambda r: self.assertEquals(
117                r.responseHeaders.getRawHeaders('content-length'), ['9']))
118
119    def testContentRange_openEnd(self):
120        self.request.requestHeaders.setRawHeaders('range', ['bytes=7991-'])
121        return deferredRender(self.file, self.request).addCallback(
122            lambda r: self.assertEquals(
123                r.responseHeaders.getRawHeaders('content-range'),
124                ['bytes 7991-7999/8000']))
125
126    def testBodyLength_fullRange(self):
127        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-'])
128        return deferredRender(self.file, self.request).addCallback(
129            lambda r: self.assertEquals(len(r.v), 8000))
130
131    def testBodyContent_fullRange(self):
132        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-'])
133        return deferredRender(self.file, self.request).addCallback(
134            lambda r: self.assertEquals(r.v, 800 * '0123456789'))
135
136    def testContentLength_fullRange(self):
137        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-'])
138        return deferredRender(self.file, self.request).addCallback(
139            lambda r: self.assertEquals(
140                r.responseHeaders.getRawHeaders('content-length'), ['8000']))
141
142    def testContentRange_fullRange(self):
143        self.request.requestHeaders.setRawHeaders('range', ['bytes=0-'])
144        return deferredRender(self.file, self.request).addCallback(
145            lambda r: self.assertEquals(
146                r.responseHeaders.getRawHeaders('content-range'),
147                ['bytes 0-7999/8000']))
148