def test_transport(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr') self.assertEqual(r.body, 'o\n') self.assertEqual(r.status, 200) self.assertEqual(r['content-type'], 'application/javascript; charset=UTF-8') self.verify_cookie(r) self.verify_cors(r) # Xhr transports receive json-encoded array of messages. r = POST(url + '/xhr_send', body='["x"]') self.assertFalse(r.body) self.assertEqual(r.status, 204) # The content type of `xhr_send` must be set to `text/plain`, # even though the response code is `204`. This is due to # Firefox/Firebug behaviour - it assumes that the content type # is xml and shouts about it. self.assertEqual(r['content-type'], 'text/plain') self.verify_cookie(r) self.verify_cors(r) r = POST(url + '/xhr') self.assertEqual(r.body, 'a["x"]\n') self.assertEqual(r.status, 200)
def test_transport(self): url = base_url + '/000/' + str(uuid.uuid4()) r = GET_async(url + '/eventsource') self.assertEqual(r.status, 200) self.assertEqual(r['Content-Type'], 'text/event-stream; charset=UTF-8') # As EventSource is requested using GET we must be very # carefull not to allow it being cached. self.verify_not_cached(r) self.verify_cookie(r) # The transport must first send a new line prelude, due to a # bug in Opera. self.assertEqual(r.read(), '\r\n') self.assertEqual(r.read(), 'data: o\r\n\r\n') r1 = POST(url + '/xhr_send', body='["x"]') self.assertFalse(r1.body) self.assertEqual(r1.status, 204) self.assertEqual(r.read(), 'data: a["x"]\r\n\r\n') # This protocol doesn't allow binary data and we need to # specially treat leading space, new lines and things like # \x00. But, now the protocol json-encodes everything, so # there is no way to trigger this case. r1 = POST(url + '/xhr_send', body=r'[" \u0000\n\r "]') self.assertFalse(r1.body) self.assertEqual(r1.status, 204) self.assertEqual(r.read(), 'data: a[" \\u0000\\n\\r "]\r\n\r\n') r.close()
def test_jsessionid(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr') self.assertEqual(r.body, 'o\n') self.verify_cookie(r) # And must be echoed back if it's already set. url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr', headers={'Cookie': 'JSESSIONID=abcdef'}) self.assertEqual(r.body, 'o\n') self.assertEqual(r['Set-Cookie'].split(';')[0].strip(), 'JSESSIONID=abcdef') self.assertEqual(r['Set-Cookie'].split(';')[1].lower().strip(), 'path=/')
def test_closeSession(self): trans_url = close_base_url + '/000/' + str(uuid.uuid4()) r = POST(trans_url + '/xhr') self.assertEqual(r.body, 'o\n') r = POST(trans_url + '/xhr') self.assertEqual(r.body, 'c[3000,"Go away!"]\n') self.assertEqual(r.status, 200) # Until the timeout occurs, the server must constantly serve # the close message. r = POST(trans_url + '/xhr') self.assertEqual(r.body, 'c[3000,"Go away!"]\n') self.assertEqual(r.status, 200)
def test_content_types(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr') self.assertEqual(r.body, 'o\n') ctypes = ['text/plain', 'T', 'application/json', 'application/xml', ''] for ct in ctypes: r = POST(url + '/xhr_send', body='["a"]', headers={'Content-Type': ct}) self.assertFalse(r.body) self.assertEqual(r.status, 204) r = POST(url + '/xhr') self.assertEqual(r.body, 'a["a","a","a","a","a"]\n') self.assertEqual(r.status, 200)
def test_ignoringServerId(self): ''' See Protocol.test_simpleSession for explanation. ''' session_id = str(uuid.uuid4()) r = POST(base_url + '/000/' + session_id + '/xhr') self.assertEqual(r.body, 'o\n') self.assertEqual(r.status, 200) payload = '["a"]' r = POST(base_url + '/000/' + session_id + '/xhr_send', body=payload) self.assertFalse(r.body) self.assertEqual(r.status, 204) r = POST(base_url + '/999/' + session_id + '/xhr') self.assertEqual(r.body, 'a["a"]\n') self.assertEqual(r.status, 200)
def test_content_types(self): url = base_url + '/000/' + str(uuid.uuid4()) r = GET(url + '/jsonp?c=x') self.assertEqual(r.body, 'x("o");\r\n') r = POST(url + '/jsonp_send', body='d=%5B%22abc%22%5D', headers={'Content-Type': 'application/x-www-form-urlencoded'}) self.assertEqual(r.body, 'ok') r = POST(url + '/jsonp_send', body='["%61bc"]', headers={'Content-Type': 'text/plain'}) self.assertEqual(r.body, 'ok') r = GET(url + '/jsonp?c=x') self.assertEqual(r.status, 200) self.assertEqual(r.body, 'x("a[\\"abc\\",\\"%61bc\\"]");\r\n')
def test_transport(self): url = base_url + '/000/' + str(uuid.uuid4()) r = GET(url + '/jsonp?c=%63allback') self.assertEqual(r.status, 200) self.assertEqual(r['Content-Type'], 'application/javascript; charset=UTF-8') # As JsonPolling is requested using GET we must be very # carefull not to allow it being cached. self.verify_not_cached(r) self.verify_cookie(r) self.assertEqual(r.body, 'callback("o");\r\n') r = POST(url + '/jsonp_send', body='d=%5B%22x%22%5D', headers={'Content-Type': 'application/x-www-form-urlencoded'}) # Konqueror does weird things on 204. As a workaround we need # to respond with something - let it be the string `ok`. self.assertEqual(r.body, 'ok') self.assertEqual(r.status, 200) self.assertFalse(r['Content-Type']) self.verify_cookie(r) r = GET(url + '/jsonp?c=%63allback') self.assertEqual(r.status, 200) self.assertEqual(r.body, 'callback("a[\\"x\\"]");\r\n')
def test_invalid_json(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr') self.assertEqual(r.body, 'o\n') r = POST(url + '/xhr_send', body='["x') self.assertEqual(r.body.strip(), "Broken JSON encoding.") self.assertEqual(r.status, 500) r = POST(url + '/xhr_send', body='') self.assertEqual(r.body.strip(), "Payload expected.") self.assertEqual(r.status, 500) r = POST(url + '/xhr_send', body='["a"]') self.assertFalse(r.body) self.assertEqual(r.status, 204) r = POST(url + '/xhr') self.assertEqual(r.body, 'a["a"]\n') self.assertEqual(r.status, 200)
def test_simpleSession(self): trans_url = base_url + '/000/' + str(uuid.uuid4()) r = POST(trans_url + '/xhr') "New line is a frame delimiter specific for xhr-polling" self.assertEqual(r.body, 'o\n') self.assertEqual(r.status, 200) # After a session was established the server needs to accept # requests for sending messages. "Xhr-polling accepts messages as a list of JSON-encoded strings." payload = '["a"]' r = POST(trans_url + '/xhr_send', body=payload) self.assertFalse(r.body) self.assertEqual(r.status, 204) '''We're using an echo service - we'll receive our message back. The message is encoded as an array 'a'.''' r = POST(trans_url + '/xhr') self.assertEqual(r.body, 'a["a"]\n') self.assertEqual(r.status, 200) # Sending messages to not existing sessions is invalid. payload = '["a"]' r = POST(base_url + '/000/bad_session/xhr_send', body=payload) self.verify404(r, cookie=True) # The session must time out after 5 seconds of not having a # receiving connection. The server must send a heartbeat frame # every 25 seconds. The heartbeat frame contains a single `h` # character. This delays may be configurable. pass # The server must not allow two receiving connections to wait # on a single session. In such case the server must send a # close frame to the new connection. r1 = POST_async(trans_url + '/xhr', load=False) r2 = POST(trans_url + '/xhr') r1.close() self.assertEqual(r2.body, 'c[2010,"Another connection still open"]\n') self.assertEqual(r2.status, 200)
def test_invalid_json(self): url = base_url + '/000/' + str(uuid.uuid4()) r = GET(url + '/jsonp?c=x') self.assertEqual(r.body, 'x("o");\r\n') r = POST(url + '/jsonp_send', body='d=%5B%22x', headers={'Content-Type': 'application/x-www-form-urlencoded'}) self.assertEqual(r.body.strip(), "Broken JSON encoding.") self.assertEqual(r.status, 500) for data in ['', 'd=', 'p=p']: r = POST(url + '/jsonp_send', body=data, headers={'Content-Type': 'application/x-www-form-urlencoded'}) self.assertEqual(r.body.strip(), "Payload expected.") self.assertEqual(r.status, 500) r = POST(url + '/jsonp_send', body='d=%5B%22b%22%5D', headers={'Content-Type': 'application/x-www-form-urlencoded'}) self.assertEqual(r.body, 'ok') r = GET(url + '/jsonp?c=x') self.assertEqual(r.status, 200) self.assertEqual(r.body, 'x("a[\\"b\\"]");\r\n')
def test_transport(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST_async(url + '/xhr_streaming') self.assertEqual(r.status, 200) self.assertEqual(r['Content-Type'], 'application/javascript; charset=UTF-8') self.verify_cookie(r) self.verify_cors(r) # The transport must first send 2KiB of `h` bytes as prelude. self.assertEqual(r.read(), 'h' * 2048 + '\n') self.assertEqual(r.read(), 'o\n') r1 = POST(url + '/xhr_send', body='["x"]') self.assertFalse(r1.body) self.assertEqual(r1.status, 204) self.assertEqual(r.read(), 'a["x"]\n') r.close()
def test_transport(self): url = base_url + '/000/' + str(uuid.uuid4()) r = GET_async(url + '/htmlfile?c=%63allback') self.assertEqual(r.status, 200) self.assertEqual(r['Content-Type'], 'text/html; charset=UTF-8') # As HtmlFile is requested using GET we must be very careful # not to allow it being cached. self.verify_not_cached(r) self.verify_cookie(r) d = r.read() self.assertEqual(d.strip(), self.head % ('callback',)) self.assertGreater(len(d), 1024) self.assertEqual(r.read(), '<script>\np("o");\n</script>\r\n') r1 = POST(url + '/xhr_send', body='["x"]') self.assertFalse(r1.body) self.assertEqual(r1.status, 204) self.assertEqual(r.read(), '<script>\np("a[\\"x\\"]");\n</script>\r\n') r.close()
def test_invalid_session(self): url = base_url + '/000/' + str(uuid.uuid4()) r = POST(url + '/xhr_send', body='["x"]') self.verify404(r, cookie=None)
def test_invalidPaths(self): for suffix in ['//', '/a./a', '/a/a.', '/./.' ,'/', '///']: self.verify404(GET(base_url + suffix + '/xhr')) self.verify404(POST(base_url + suffix + '/xhr'))
def test_invalidMethod(self): for h in [{'Upgrade': 'WebSocket', 'Connection': 'Upgrade'}, {}]: r = POST(base_url + '/0/0/websocket', headers=h) self.assertEqual(r.status, 405) self.assertFalse(r.body)
def verify(self, session_part): r = POST(base_url + session_part + '/xhr') self.assertEqual(r.body, 'o\n') self.assertEqual(r.status, 200)