Ticket #2198: Twisted_2198.2.patch

File Twisted_2198.2.patch, 4.2 KB (added by moijes12, 4 years ago)

I hadn't attached the news file.

  • twisted/topfiles/2198.feature

     
     1twisted.protocols.sip.MessageParser now handles multiline headers.
     2 No newline at end of file
  • twisted/test/test_sip.py

     
    8686
    8787""".replace("\n", "\r\n")
    8888
     89# multiline headers (example from RFC 3621).
     90response_multiline = """\
     91SIP/2.0 200 OK
     92Via: SIP/2.0/UDP server10.biloxi.com
     93    ;branch=z9hG4bKnashds8;received=192.0.2.3
     94Via: SIP/2.0/UDP bigbox3.site3.atlanta.com
     95    ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
     96Via: SIP/2.0/UDP pc33.atlanta.com
     97    ;branch=z9hG4bK776asdhds ;received=192.0.2.1
     98To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
     99From: Alice <sip:alice@atlanta.com>;tag=1928301774
     100Call-ID: a84b4c76e66710@pc33.atlanta.com
     101CSeq: 314159 INVITE
     102Contact: <sip:bob@192.0.2.4>
     103Content-Type: application/sdp
     104Content-Length: 0
     105\n""".replace("\n", "\r\n")
     106
    89107class TestRealm:
    90108    def requestAvatar(self, avatarId, mind, *interfaces):
    91109        return sip.IContact, None, lambda: None
     
    178196        self.assertEqual(m.finished, 1)
    179197
    180198
     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
    181210class MessageParsingTestCase2(MessageParsingTestCase):
    182211    """Same as base class, but feed data char by char."""
    183212
  • twisted/protocols/sip.py

     
    632632        self.length = None # body length
    633633        self.bodyReceived = 0 # how much of the body we received
    634634        self.message = None
     635        self.header = None
    635636        self.setLineMode(remainingData)
    636637
    637638    def invalidMessage(self):
     
    699700        else:
    700701            assert self.state == "headers"
    701702        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
    710712                try:
    711                     self.length = int(value.lstrip())
     713                    name, value = line.split(":", 1)
    712714                except ValueError:
    713715                    self.invalidMessage()
    714716                    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
    715725        else:
    716726            # CRLF, we now have message body until self.length bytes,
    717727            # or if no length was given, until there is no more data
    718728            # from the connection sending us data.
    719729            self.state = "body"
     730            if self.header:
     731                self.message.addHeader(*self.header)
     732                self.header = None
    720733            if self.length == 0:
    721734                self.messageDone()
    722735                return