Ticket #2198: Twisted_2198.2.patch
| File Twisted_2198.2.patch, 4.2 KB (added by moijes12, 14 months ago) |
|---|
-
twisted/topfiles/2198.feature
1 twisted.protocols.sip.MessageParser now handles multiline headers. 2 No newline at end of file -
twisted/test/test_sip.py
86 86 87 87 """.replace("\n", "\r\n") 88 88 89 # multiline headers (example from RFC 3621). 90 response_multiline = """\ 91 SIP/2.0 200 OK 92 Via: SIP/2.0/UDP server10.biloxi.com 93 ;branch=z9hG4bKnashds8;received=192.0.2.3 94 Via: SIP/2.0/UDP bigbox3.site3.atlanta.com 95 ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2 96 Via: SIP/2.0/UDP pc33.atlanta.com 97 ;branch=z9hG4bK776asdhds ;received=192.0.2.1 98 To: Bob <sip:bob@biloxi.com>;tag=a6c85cf 99 From: Alice <sip:alice@atlanta.com>;tag=1928301774 100 Call-ID: a84b4c76e66710@pc33.atlanta.com 101 CSeq: 314159 INVITE 102 Contact: <sip:bob@192.0.2.4> 103 Content-Type: application/sdp 104 Content-Length: 0 105 \n""".replace("\n", "\r\n") 106 89 107 class TestRealm: 90 108 def requestAvatar(self, avatarId, mind, *interfaces): 91 109 return sip.IContact, None, lambda: None … … 178 196 self.assertEqual(m.finished, 1) 179 197 180 198 199 def testMultiLine(self): 200 l = self.l 201 self.feedMessage(response_multiline) 202 self.assertEquals(len(l), 1) 203 m = l[0] 204 self.assertEquals(m.headers['via'][0], "SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bKnashds8;received=192.0.2.3") 205 self.assertEquals(m.headers['via'][1], "SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2") 206 self.assertEquals(m.headers['via'][2], "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1") 207 208 209 181 210 class MessageParsingTestCase2(MessageParsingTestCase): 182 211 """Same as base class, but feed data char by char.""" 183 212 -
twisted/protocols/sip.py
632 632 self.length = None # body length 633 633 self.bodyReceived = 0 # how much of the body we received 634 634 self.message = None 635 self.header = None 635 636 self.setLineMode(remainingData) 636 637 637 638 def invalidMessage(self): … … 699 700 else: 700 701 assert self.state == "headers" 701 702 if line: 702 # XXX support multi-line headers 703 try: 704 name, value = line.split(":", 1) 705 except ValueError: 706 self.invalidMessage() 707 return 708 self.message.addHeader(name, value.lstrip()) 709 if name.lower() == "content-length": 703 # multiline header 704 if line.startswith(" ") or line.startswith("\t"): 705 name, value = self.header 706 self.header = name, (value + line.lstrip()) 707 else: 708 # new header 709 if self.header: 710 self.message.addHeader(*self.header) 711 self.header = None 710 712 try: 711 self.length = int(value.lstrip())713 name, value = line.split(":", 1) 712 714 except ValueError: 713 715 self.invalidMessage() 714 716 return 717 self.header = name, value.lstrip() 718 # XXX we assume content-length won't be multiline 719 if name.lower() == "content-length": 720 try: 721 self.length = int(value.lstrip()) 722 except ValueError: 723 self.invalidMessage() 724 return 715 725 else: 716 726 # CRLF, we now have message body until self.length bytes, 717 727 # or if no length was given, until there is no more data 718 728 # from the connection sending us data. 719 729 self.state = "body" 730 if self.header: 731 self.message.addHeader(*self.header) 732 self.header = None 720 733 if self.length == 0: 721 734 self.messageDone() 722 735 return
