o ¯bH”ã @sddZddlZddlZddlZddlmZddlmZmZddl m Z m Z ddl m Z ddlmZmZmZddlmZdd lmZd Zd d d dddddddœ ZiZe ¡D]\ZZeee<qT[[idd“dd“dd“dd“dd“dd “d!d"“d#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“id7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“dEdF“dGdH“dIdJ“dKdL“dMdN“dOdP“dQdR“dSdT“dUdV“dWdX“¥idYdZ“d[d\“d]d^“d_d`“dadb“dcdd“dedf“dgdh“didj“dkdl“dmdn“dodp“dqdr“dsdt“dudv“dwdx“dydz“¥d{d:d|œ¥Zd}d~dd€œZdd‚„Zdƒd„„Ze ƒZ!Gd…d†„d†ƒZ"d‡dˆ„Z#Gd‰dŠ„dŠƒZ$d¯d‹dŒ„Z%ddŽ„Z&d°dd„Z'Gd‘d’„d’e(ƒZ)Gd“d”„d”e)ƒZ*Gd•d–„d–ƒZ+Gd—d˜„d˜e+ƒZ,Gd™dš„dše+ƒZ-Gd›dœ„dœej.ƒZ/Gddž„džej0ƒZ1GdŸd „d e ƒZ2Gd¡d¢„d¢ƒZ3Gd£d¤„d¤e ƒZ4Gd¥d¦„d¦e ƒZ5Gd§d¨„d¨e1ƒZ6Gd©dª„dªe ƒZ7Gd«d¬„d¬e6ƒZ8e e4e5ƒGd­d®„d®ƒƒZ9dS)±zP Session Initialization Protocol. Documented in RFC 2543. [Superseded by 3261] éN)Ú OrderedDict)ÚDictÚList)Ú InterfaceÚ implementer)Úcred)ÚdeferÚprotocolÚreactor)Úbasic)ÚlogiÄÚiÚmÚeÚlÚcÚfÚsÚtÚv) úcall-idÚcontactzcontent-encodingúcontent-lengthz content-typeÚfromÚsubjectÚtoÚviaédÚTryingé´ÚRingingéµzCall Is Being Forwardedé¶ÚQueuedé·zSession ProgresséÈÚOKi,zMultiple Choicesi-zMoved Permanentlyi.zMoved Temporarilyi/z See Otheri1z Use Proxyi|zAlternative Serviceéz Bad Requesté‘Ú Unauthorizedi’zPayment Requiredi“Ú Forbiddené”z Not Foundi•zMethod Not Allowedi–zNot Acceptablei—zProxy Authentication Requiredi˜zRequest Timeouti™ÚConflictišÚGonei›zLength RequiredizRequest Entity Too LargeižzRequest-URI Too LargeiŸzUnsupported Media Typei zUnsupported URI Schemei¤z Bad Extensioni¥zExtension Requiredi§zInterval Too BriefiàzTemporarily UnavailableiázCall/Transaction Does Not Existiâz Loop Detectediãz Too Many HopsiäzAddress IncompleteiåÚ Ambiguousiæz Busy HereiçzRequest TerminatedièzNot Acceptable HereiëzRequest PendingiíÚUndecipherableéôzInternal Server ErroréõzNot Implementediöz Bad Gatewayi÷zService UnavailableiøzServer Time-outiùzSIP Version not supportedizMessage Too LargeiXzBusy Everywherei[ÚDeclinezDoes not exist anywhere)i\i^ÚCSeqzCall-IDzWWW-Authenticate)Úcseqrúwww-authenticatecCsd dd„| d¡Dƒ¡S)zK Capitalize a string, making sure to treat '-' as a word separator ú-cSsg|]}| ¡‘qS©)Ú capitalize)Ú.0Úxr7r7ú7/usr/lib/python3/dist-packages/twisted/protocols/sip.pyÚ psz"dashCapitalize..)ÚjoinÚsplit©rr7r7r;ÚdashCapitalizelsr@cCs2|d|dkrdkrn|S|dd…S|S)Nréÿÿÿÿú"ér7r?r7r7r;Úunqss ÿrDc@sLeZdZdZeddddeddfdd„Zedd„ƒZej d d„ƒZd d „Z dS) ÚViaa‡ A L{Via} is a SIP Via header, representing a segment of the path taken by the request. See RFC 3261, sections 8.1.1.7, 18.2.2, and 20.42. @ivar transport: Network protocol used for this leg. (Probably either "TCP" or "UDP".) @type transport: C{str} @ivar branch: Unique identifier for this request. @type branch: C{str} @ivar host: Hostname or IP for this leg. @type host: C{str} @ivar port: Port used for this leg. @type port C{int}, or None. @ivar rportRequested: Whether to request RFC 3581 client processing or not. @type rportRequested: C{bool} @ivar rportValue: Servers wishing to honor requests for RFC 3581 processing should set this parameter to the source port the request was received from. @type rportValue: C{int}, or None. @ivar ttl: Time-to-live for requests on multicast paths. @type ttl: C{int}, or None. @ivar maddr: The destination multicast address, if any. @type maddr: C{str}, or None. @ivar hidden: Obsolete in SIP 2.0. @type hidden: C{bool} @ivar otherParams: Any other parameters in the header. @type otherParams: C{dict} ÚUDPNFc Ks˜||_||_||_||_||_||_|dur%tjdtddd|_ d|_ n|dur0d|_ d|_ n|t ur;d|_ d|_ n||_ d|_ ||_ | |_ | |_dS)a( Set parameters of this Via header. All arguments correspond to attributes of the same name. To maintain compatibility with old SIP code, the 'rport' argument is used to determine the values of C{rportRequested} and C{rportValue}. If None, C{rportRequested} is set to True. (The deprecated method for doing this is to pass True.) If an integer, C{rportValue} is set to the given value. Any arguments not explicitly named here are collected into the C{otherParams} dict. Tz+rport=True is deprecated since Twisted 9.0.é)Ú stacklevelNF)Ú transportÚhostÚportÚttlÚhiddenÚreceivedÚwarningsÚwarnÚDeprecationWarningÚ rportValueÚrportRequestedÚ_absentÚbranchÚmaddrÚ otherParams) ÚselfrJrKrIrLrMrNÚrportrUrVÚkwr7r7r;Ú__init__s2ý z Via.__init__cCs"|jdkrdS|jdur|jSdS)zG Returns the rport value expected by the old SIP code. TN)rSrR©rXr7r7r;rYÓs  z Via.rportcCs||_d|_dS)z L{Base._fixupNAT} sets C{rport} directly, so this method sets C{rportValue} based on that. @param newRPort: The new rport value. @type newRPort: C{int} FN)rRrS)rXÚnewRPortr7r7r;rYßs cCsÎd|j›d|j›d|j›}|jr|d7}dD]}t||ƒ}|dur,|d|›d|›7}q|jr5|d 7}n |jdurB|d |j›7}t|j   ¡ƒ}|D]\}}|durZ|d|7}qK|d|›d|›7}qK|S) zI Serialize this header for use in a request or response. zSIP/2.0/ú ú:z;hidden)rLrUrVrNNú;ú=z;rportz;rport=) rIrJrKrMÚgetattrrSrRrYÚsortedrWÚitems)rXrÚnÚvalueÚetcÚkrr7r7r;ÚtoStringës$ €   z Via.toString) Ú__name__Ú __module__Ú __qualname__Ú__doc__ÚPORTrTr[ÚpropertyrYÚsetterrir7r7r7r;rE|s # ö6   rEcCsL| d¡}|d|dd…}}| dd¡\}}| ¡}i}| d¡\}}} |dks.|dkr5td |›ƒ‚| |d <d |vrO| d ¡\} } t| ƒ|d <| |d <n||d <|D]I} |  ¡ dd¡} t| ƒdkrm| dd} } n| \} } | dkrzd|d<qU|  dd¡}t|ƒdkrŽ|dd}}n |\}}|dvršt|ƒ}|||<qUtdi|¤ŽS)za Parse a Via header. @return: The parsed version of this header. @rtype: L{Via} r`rrCNr^ú/ÚSIPz2.0zwrong protocol or version: rIr_rKrJÚrMTra)rYrLr7)r>ÚstripÚ ValueErrorÚintÚlenrE)rfÚpartsÚsentÚparamsÚ protocolinfoÚbyÚresultÚpnameÚpversionrIrJrKÚpÚcommentÚnamer7r7r;ÚparseViaHeaders<       rƒc@sZeZdZdZ           d dd„Zdefdd„Zdefdd „Zdefd d „ZdS) ÚURLz A SIP URL. Nc Csn||_||_||_||_||_||_||_| |_||_| |_ | dkr&g|_ n| |_ | dkr2i|_ dS| |_ dS©N) ÚusernamerJÚpasswordrKrIÚusertypeÚmethodÚtagrLrVÚotherÚheaders) rXrJr†r‡rKrIrˆr‰rLrVrŠr‹rŒr7r7r;r[4s   z URL.__init__ÚreturncCsþg}|j}|dƒ|jdkr#||jƒ|jdkr|d|jƒ|dƒ||jƒ|jdkr4|d|jƒ|jdkr@|d|jƒdD]}t||ƒ}|dkrW|d|›d|›ƒqB|jD]}|d |ƒq[|jrz|d ƒ|d   d d „|j  ¡Dƒ¡ƒd  |¡S)Núsip:z:%sú@z:%dz;user=%s©rIrLrVr‰rŠr`raz;%sú?ú&cSs,g|]\}}t |¡pt|ƒ›d|›‘qS)ra)Ú specialCasesÚgetr@)r9Úhrr7r7r;r<nsÿÿz URL.toString..rs) Úappendr†r‡rJrKrˆrbr‹rŒr=rd)rXrÚwrerr7r7r;riVs<       € þÿÿ z URL.toStringcCs| ¡Sr…)rir\r7r7r;Ú__str__vsz URL.__str__cCsd |j|j|j|j|j¡S)Nz)Úformatr†r‡rJrKrIr\r7r7r;Ú__repr__ysûz URL.__repr__) NNNNNNNNNNN) rjrkrlrmr[Ústrrir˜ršr7r7r7r;r„/s" ó" r„cCsüi}| d¡std|dd…ƒ‚|dd… d¡}|d|dd…}}| dd¡}t|ƒd krU|\}} | d d¡} t| ƒdkrH| d|d <n| d|d <| d|d <n|d} |  d d¡} t| ƒdkrl| d|d <n| d|d <t| dƒ|d<|dkr‚||d <|dkrŠ||d<|D]j} | |dkr¹d| vr¹i|d<} |  dd¡\} }| d¡D] }| d¡\}}|| |<q«|  dd¡}t|ƒdkrÏ| dg¡ | ¡qŒ|\}}|dkrÜ||d<qŒ|dvrí|dkrèt|ƒ}|||<qŒ| dg¡ | ¡qŒtdi|¤ŽS)zV Return string into URL object. URIs are of form 'sip:user@example.com'. rŽzunsupported scheme: Nér`rrCrrGr_r†r‡rJrKrAr‘rŒr’rar‹ÚuserrˆrrLr7)Ú startswithrur>rwrvÚ setdefaultr–r„)ÚurlrJrKÚdrxÚ userdomainrzÚudpartsÚuserpassÚhostportÚuppartsÚhppartsr€r•rŒÚheaderrhrÚnvr‚rfr7r7r;ÚparseURLƒsV               rªcCsd|_d|_d|_i|_dS)z* Clean a URL from a Request line. N)rIrVrLrŒ)r r7r7r;ÚcleanRequestURLºs r«c Csê| ¡}| d¡rdt|||difSi}| dd¡\}}| ¡}| d¡r,|dd…}| d¡r7|dd…}| d d¡\}}t|||d}| ¡}|rb| d ¡D]}|sVqQ| d ¡\} } | || <qQ|rpd|_i|_d|_d|_|||fS) z Return (name, uri, params) for From/To/Contact header. @param clean: remove unnecessary info, usually for From and To headers. rŽrs©rJrKúr`ra) rtržrªr>ÚendswithrLrŒrIrV) ÚaddressrJrKÚcleanrzr‚r Ú paramstringrrhrr7r7r;Ú parseAddressÄs2       r³c@seZdZddd„ZdS)ÚSIPErrorNcCs4|durt|}t |d||f¡||_||_dS)NzSIP error (%d): %s)Ú statusCodesÚ Exceptionr[ÚcodeÚphrase)rXr·r¸r7r7r;r[ès  zSIPError.__init__r…©rjrkrlr[r7r7r7r;r´çsr´c@óeZdZdZdS)ÚRegistrationErrorz( Registration was not possible. N©rjrkrlrmr7r7r7r;r»ðór»c@sDeZdZdZdZdd„Zdd„Zdd„Zd d „Zd d „Z d d„Z dS)ÚMessagez A SIP message. NcCstƒ|_d|_d|_dS)Nrsr)rrŒÚbodyÚfinishedr\r7r7r;r[ýs zMessage.__init__cCs>| ¡}t ||¡}|dkrt|ƒ|_|j |g¡ |¡dS)Nr)ÚlowerÚ longHeadersr”rvÚlengthrŒrŸr–)rXr‚rfr7r7r;Ú addHeaders   zMessage.addHeadercCs|j|7_dSr…)r¿©rXÚdatar7r7r;ÚbodyDataReceived ózMessage.bodyDataReceivedcCs,|jdkr|jt|jƒkrtdƒ‚d|_dS)Nzwrong body lengthrC)rÃrwr¿rurÀr\r7r7r;ÚcreationFinished s zMessage.creationFinishedcCsbd| ¡}|j ¡D]\}}|D]}|t |¡pt|ƒ›d|›d7}qq |d7}||j7}|S)Nz%s z: z )Ú_getHeaderLinerŒrdr“r”r@r¿)rXrreÚvsrr7r7r;ris $ÿ zMessage.toStringcCót‚r…©ÚNotImplementedErrorr\r7r7r;rÊózMessage._getHeaderLine) rjrkrlrmrÃr[rÄrÇrÉrirÊr7r7r7r;r¾ös r¾c@s0eZdZdZd dd„Zdefdd„Zdd „Zd S) ÚRequestz A Request for a URI úSIP/2.0cCs<t |¡||_t|tƒr||_dSt|ƒ|_t|jƒdSr…)r¾r[r‰Ú isinstancer„Úurirªr«)rXr‰rÓÚversionr7r7r;r[#s    zRequest.__init__rcCsdt|ƒ|j|j ¡fS)Nz)Úidr‰rÓrir\r7r7r;rš,szRequest.__repr__cCs|j›d|j ¡›dS)Nr^z SIP/2.0)r‰rÓrir\r7r7r;rÊ/szRequest._getHeaderLineN)rÑ©rjrkrlrmr[r›ršrÊr7r7r7r;rÐs   rÐc@s0eZdZdZd dd„Zdefdd„Zd d „ZdS) ÚResponsez% A Response to a URI Request NrÑcCs*t |¡||_|dkrt|}||_dSr…)r¾r[r·rµr¸)rXr·r¸rÔr7r7r;r[8s  zResponse.__init__rcCsdt|ƒ|jfS)Nz)rÕr·r\r7r7r;rš?rÈzResponse.__repr__cCsd|j›d|j›S)NzSIP/2.0 r^)r·r¸r\r7r7r;rÊBszResponse._getHeaderLine)NrÑrÖr7r7r7r;r×3s   r×c@sxeZdZdZdZdZdZdZdZdd„Z dd d „Z d d „Z d d„Z dd„Z dd„Zdd„Zdd„Zddd„Zdd„ZdS)ÚMessagesParserz A SIP messages parser. Expects dataReceived, dataDone repeatedly, in that order. Shouldn't be connected to actual transport. rÑrCÚ firstlinercCs||_| ¡dSr…)ÚmessageReceivedÚreset)rXÚmessageReceivedCallbackr7r7r;r[Uó zMessagesParser.__init__rscCs,d|_d|_d|_d|_d|_| |¡dS)NrÙr)ÚstaterÃÚ bodyReceivedÚmessager¨Ú setLineMode©rXÚ remainingDatar7r7r;rÛYs zMessagesParser.resetcCsd|_| ¡dS)NÚinvalid)rÞÚ setRawModer\r7r7r;ÚinvalidMessagearÝzMessagesParser.invalidMessagecCsb| ¡|jdkr dS|jdkr| ¡dS|jdkr!| ¡dS|j|jkr-| ¡dStdƒ‚)zI Clear out any buffered data that may be hanging around. rÙNr¿zthis should never happen)ÚclearLineBufferrÞrÛrÃÚ messageDonerßÚ RuntimeErrorr\r7r7r;ÚdataDonees      zMessagesParser.dataDonecCsNzt|tƒr | d¡}tj ||¡WdSty&t ¡|  ¡YdSw)Núutf-8) rÒr›Úencoder Ú LineReceiverÚ dataReceivedr¶r ÚerrrærÅr7r7r;rîys   þzMessagesParser.dataReceivedcCrÌ)z2 Expected to create self.message. rÍ©rXÚliner7r7r;ÚhandleFirstLine‚ózMessagesParser.handleFirstLinecCs | ¡dSr…)rærðr7r7r;ÚlineLengthExceededˆó z!MessagesParser.lineLengthExceededcCs.t|tƒr | d¡}|jdkrƒ| d¡s| d¡r)|dd…}| d¡s| d¡s|s-dSz | dd¡\}}}WntyF| ¡YdSw|dkrj|jrjzt |ƒ}Wntyb| ¡YdSwt ||ƒ|_ n|dkrx|j rxt ||ƒ|_ n| ¡dSd |_dS|jd ksŠJ‚|rô| d¡s–| d ¡r¦|j\}}||| ¡f|_dS|jr³|j j|jŽd|_z | d d¡\}}WntyË| ¡YdSw|| ¡f|_| ¡d kròz t | ¡ƒ|_WdStyñ| ¡YdSwdSd |_|jr|j j|jŽd|_|jdkr| ¡dS| ¡dS)NrërÙÚ ú rCr^rGrÑrŒú r_rr¿r)rÒÚbytesÚdecoderÞržr>ruræÚacceptResponsesrvr×ràÚacceptRequestsrÐr¨ÚlstriprÄrÁrÃrèrå)rXrñÚaÚbrr·r‚rfr7r7r;Ú lineReceived‹sv    ÿ þ  þ  þ  þý   zMessagesParser.lineReceivedcCs2|jdksJ‚|j ¡| |j¡| |¡dS)Nr¿)rÞràrÉrÚrÛrâr7r7r;rèÎs  zMessagesParser.messageDonecCsÆ|jdvsJ‚t|tƒr| d¡}|jdkrdS|jdkr%|j |¡dSt|ƒ}|j|j}||krH|j |d|…¡|  ||d…¡dS|j|7_|j |¡|j|jkra|  ¡dSdS)N)r¿rärërä) rÞrÒrùrúrÃràrÇrwrßrè)rXrÆÚdataLenÚ expectedLenr7r7r;ÚrawDataReceivedÔs$        ÿzMessagesParser.rawDataReceivedN)rs)rjrkrlrmrÔrûrürÞÚdebugr[rÛrærêrîròrôrrèrr7r7r7r;rØFs"   C rØc@s`eZdZdZeZdZdd„Zdd„Zdd„Zd d „Z d d „Z d d„Z dd„Z dd„Z dd„ZdS)ÚBasez1 Base class for SIP clients and servers. FcCsg|_t|jƒ|_dSr…)ÚmessagesrØÚ addMessageÚparserr\r7r7r;r[òsz Base.__init__cCs|j |¡dSr…)rr–)rXÚmsgr7r7r;röózBase.addMessagecCs„|j |¡|j ¡|jD]*}| ||¡|jr&t d| ¡›d|›¡t |t ƒr2|  ||¡q|  ||¡qg|jdd…<dS)Nz Received z from ) rrîrêrÚ _fixupNATrr r rirÒrÐÚhandle_requestÚhandle_response)rXrÆÚaddrrr7r7r;ÚdatagramReceivedùs     zBase.datagramReceivedcCs€|\}}t|jddƒ}|j|kr(||_|j|kr||_| ¡|jdd<dS|jdkr>||_||_| ¡|jdd<dSdS)NrrT)rƒrŒrJrNrKrYri)rXràÚ sourcePeerÚsrcHostÚsrcPortÚ senderViar7r7r;r s   ýzBase._fixupNATcCóLt|jddƒ}|jp|j}|jp|jp|j}t||d}| ||¡dS©zX Deliver response. Destination is based on topmost Via header. rrr¬N© rƒrŒrNrJrYrKrnr„Ú sendMessage©rXÚresponseMessageÚdestViarJrKÚdestAddrr7r7r;ÚdeliverResponses   zBase.deliverResponsecCó2t|ƒ}dD]}|j |g¡dd…|j|<q|S©z9 Create a response to a request message. )rrrrr4N©r×rŒr”©rXr·ÚrequestÚresponser‚r7r7r;ÚresponseFromRequest!szBase.responseFromRequestcCsn|jdvr tdƒ‚|jrt d| ¡›d|›¡| ¡}t|tƒr'| d¡}|j  ||j |j p2|j f¡dS)z£ Send a message. @param destURL: C{URL}. This should be a *physical* URL, not a logical one. @param message: The message to send. )ÚudpNzonly UDP currently supportedzSending z to rëN) rIrérr r rirÒr›rìÚwriterJrKrn)rXÚdestURLràrÆr7r7r;r+s    zBase.sendMessagecCrÌ)zƒ Override to define behavior for requests received @type message: C{Message} @type addr: C{tuple} rÍ©rXràrr7r7r;r ;ózBase.handle_requestcCrÌ)z… Override to define behavior for responses received. @type message: C{Message} @type addr: C{tuple} rÍr'r7r7r;r Dr(zBase.handle_responseN)rjrkrlrmrnrr[rrr rr#rr r r7r7r7r;rês    rc@rº)ÚIContactz( A user of a registrar or proxy Nr¼r7r7r7r;r)Nr½r)c@seZdZdd„ZdS)Ú RegistrationcCs||_||_dSr…)ÚsecondsToExpiryÚ contactURL)rXr+r,r7r7r;r[Uó zRegistration.__init__Nr¹r7r7r7r;r*Ts r*c@s(eZdZdZdd„Zdd„Zdd„ZdS) Ú IRegistryz? Allows registration of logical->physical URL mapping. cCódS)z’ Register the physical address of a logical URL. @return: Deferred of C{Registration} or failure with RegistrationError. Nr7©Ú domainURLÚ logicalURLÚ physicalURLr7r7r;ÚregisterAddress_ózIRegistry.registerAddresscCr/)z” Unregister the physical address of a logical URL. @return: Deferred of C{Registration} or failure with RegistrationError. Nr7r0r7r7r;ÚunregisterAddressfr5zIRegistry.unregisterAddresscCr/)zˆ Get registration info for logical URL. @return: Deferred of C{Registration} object or failure of LookupError. Nr7©r2r7r7r;ÚgetRegistrationInfomr5zIRegistry.getRegistrationInfoN)rjrkrlrmr4r6r8r7r7r7r;r.Zs  r.c@seZdZdZdd„ZdS)ÚILocatorz< Allow looking up physical address for logical URL. cCr/)z½ Return physical URL of server for logical URL of user. @param logicalURL: a logical C{URL}. @return: Deferred which becomes URL or fails with LookupError. Nr7r7r7r7r;Ú getAddresszr5zILocator.getAddressN)rjrkrlrmr:r7r7r7r;r9us r9c@sfeZdZdZeZdZdefdd„Zdd„Zdd„Zd d „Z d d „Z d d„Z dd„Z dd„Z dd„ZdS)ÚProxyz SIP proxy. NcCs"|pt ¡|_||_t |¡dS)z˜ Create new instance. @param host: our hostname/IP as set in Via headers. @param port: our port as set in Via headers. N)ÚsocketÚgetfqdnrJrKrr[)rXrJrKr7r7r;r[ŒszProxy.__init__cCst|j|jdS)z< Return value of Via header for this proxy. r¬)rErJrKr\r7r7r;ÚgetVia—sz Proxy.getViac sºtˆdˆjdƒ}|durˆj}z|ˆ|ƒ}Wn3ty4}zˆ ˆ |jˆ¡¡WYd}~dSd}~wtyJt  ¡ˆ ˆ dˆ¡¡YdSw|dur[|  ‡‡fdd„¡dSdS)Nzhandle_%s_requestr0csˆ ˆ |jˆ¡¡Sr…)rr#r·)r©ràrXr7r;Ú­s ÿz&Proxy.handle_request..) rbr‰Úhandle_request_defaultr´rr#r·Ú BaseExceptionr rïÚ addErrback)rXràrrr¡rr7r?r;r s""€ þ ÿÿzProxy.handle_requestc sš|\}}‡fdd„}ˆ ¡}| ¡|jdvrt d¡dS|jd d| ¡¡t|jdddd \}}} ˆj |¡} |   ˆj |¡|   ˆj |¡dS) zû Default request handler. Default behaviour for OPTIONS and unknown methods for proxies is to forward message on to the client. Since at the moment we are stateless proxy, that's basically everything. cs| ¡|jdd<ˆ ||¡S)Nrr)rirŒr)rÓràr\r7r;Ú_mungContactHeader¾s z8Proxy.handle_request_default.._mungContactHeaderrzDropping looped message.NrrrC©r±) r>rirŒr r Úinsertr³Úlocatorr:Ú addCallbackrrCÚ_cantForwardRequest) rXràrrrrDÚ viaHeaderr‚rÓÚtagsr¡r7r\r;rA²s   zProxy.handle_request_defaultcCs,| t¡|jdd=| | d|¡¡dS)Nrrr+)ÚtrapÚ LookupErrorrŒrr#©rXÚerrorràr7r7r;rIÐs  zProxy._cantForwardRequestcCrrrrr7r7r;rÕs   zProxy.deliverResponsecCrrrr r7r7r;r#ãszProxy.responseFromRequestcCslt|jddƒ}|j|jf|j|jfkrt d¡dS|jdd=|jds/| ||¡dS| |¡dS)z+ Default response handler. rrz&Dropping incorrectly addressed messageN)rƒrŒrJrKr r Ú gotResponser)rXràrrr7r7r;r ìs    zProxy.handle_responsecCr/)zJ Called with responses that are addressed at this server. Nr7r'r7r7r;rPþrózProxy.gotResponse)rjrkrlrmrnrGr[r>r rArIrr#r rPr7r7r7r;r;ƒs  r;c@seZdZdd„Zdd„ZdS)Ú IAuthorizercCr/)zÇ Generate a challenge the client may respond to. @type peer: C{tuple} @param peer: The client's address @rtype: C{str} @return: The challenge string Nr7)Úpeerr7r7r;Ú getChallenger5zIAuthorizer.getChallengecCr/)zf Create a credentials object from the given response. @type response: C{str} Nr7)r"r7r7r;rúr5zIAuthorizer.decodeN)rjrkrlrSrúr7r7r7r;rQs rQc@s–eZdZUdZdZdZiZeee fe d<dd„Z dd„Z dd „Z d d „Zd d „Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS)Ú RegisterProxyzk A proxy that allows registration for a specific domain. Unregistered users won't be handled. NÚ authorizerscOs"tj|g|¢Ri|¤Ži|_dSr…)r;r[ÚliveChallenges)rXÚargsrZr7r7r;r[&s zRegisterProxy.__init__cCs |\}}dSr…r7©rXràÚ host_portrJrKr7r7r;Úhandle_ACK_request*sz RegisterProxy.handle_ACK_requestcCsJ|\}}|jdur| |||¡dSd|jvr| |||¡S| |||¡S)z` Handle a registration request. Currently registration is not proxied. NÚ authorization)ÚportalÚregisterrŒÚ unauthorizedÚloginrXr7r7r;Úhandle_REGISTER_request3s   z%RegisterProxy.handle_REGISTER_requestc CsŒ| d|¡}|j ¡D]3\}}| ||f¡}|dur&| ¡›d|j›d}n| ¡›d|›d|j›d}|j dg¡ |¡q |  |¡dS)Nr(z realm="rBr^z,realm="r5) r#rUrdrSÚtitlerJrŒrŸr–r) rXràrJrKrÚschemeÚauthÚchalrfr7r7r;r^Ds zRegisterProxy.unauthorizedc Csà|jdd dd¡}|j |d ¡¡}|rez | |d¡}Wnty(‚ty>t  ¡|  |  d|¡¡YdSw|j d|j 7_ |j |dt¡ |j|||¡ |j|||¡ tj ¡dS|  |  d|¡¡dS)Nr[rrCr0rr1)rŒr>rUr”rÁrúr´rBr rïrr#r†rJr\r_r)rHÚ_cbLoginrCÚ_ebLogin)rXràrJrKrxrþrr7r7r;r_Os"  þ ÿzRegisterProxy.logincCs|\}}}| |||¡dSr…)r])rXÚi_a_lràrJrKr rþrr7r7r;rebs zRegisterProxy._cbLogincCs | tjj¡| |||¡dSr…)rLrrOÚUnauthorizedLoginr^)rXÚfailureràrJrKr7r7r;rfgszRegisterProxy._ebLoginc Cs¼t|jdddd\}}}d}d|jvr|jdd}|j ddg¡ddkr1| |||¡dS|durIt|||d \}}}|j |j||¡} n|j |¡} | j|j |j |f|fd dS) z- Allow all users to register rrrCrENrÚexpiresÚ0r¬)Ú callbackArgsÚ errbackArgs) r³rŒr”Ú unregisterÚregistryr4rÓr8Ú addCallbacksÚ _cbRegisterÚ _ebRegister) rXràrJrKr‚ÚtoURLrzrr,r¡r7r7r;r]ks    üzRegisterProxy.registercCsT| d|¡}|jdkr| d|j ¡¡| dd|j¡| dd¡| |¡dS)Nr%rrjz%drrk)r#r,rÄrir+r)rXÚ registrationràr"r7r7r;rq…s   zRegisterProxy._cbRegistercCs| tt¡dSr…)rLr»rMrNr7r7r;rrr zRegisterProxy._ebRegisterc Cs”z t|jddƒ}Wnty| | d|¡¡YdSw|dkrH|dkr*d}nt|ƒ\}}}|j |j||¡}|  |j |¡  |j |¡dSdS)Nrjrr'Ú*) rvrŒrurr#r³ror6rÓrHÚ _cbUnregisterrCÚ _ebUnregister) rXràrsrrjr,r‚rzr¡r7r7r;rn’s ÿÿúzRegisterProxy.unregistercCs@| d|¡}|j dg¡ |j ¡¡| dd¡| |¡dS)Nr%rrjrk)r#rŒrŸr–r,rirÄr)rXrtràr r7r7r;rv¢s  zRegisterProxy._cbUnregistercCsdSr…r7)rXrtràr7r7r;rw¨rÏzRegisterProxy._ebUnregister)rjrkrlrmr\rorUrr›rQÚ__annotations__r[rZr`r^r_rerfr]rqrrrnrvrwr7r7r7r;rTs$    rTc@s@eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dS)ÚInMemoryRegistryz6 A simplistic registry for a specific domain. cCs||_i|_dSr…)ÚdomainÚusers)rXrzr7r7r;r[²r-zInMemoryRegistry.__init__cCsN|j|jkr t tdƒ¡S|j|jvr |j|j\}}t |¡St tdƒ¡S©Nzunknown domainú no such user)rJrzrÚfailrMr†r{Úsucceed©rXÚuserURIÚdcr r7r7r;r:¶s   zInMemoryRegistry.getAddresscCsd|j|jkr t tdƒ¡S|j|jvr+|j|j\}}t tt |  ¡t   ¡ƒ|ƒ¡St tdƒ¡Sr|) rJrzrr~rMr†r{rr*rvÚgetTimeÚtimer€r7r7r;r8¿s   z$InMemoryRegistry.getRegistrationInfocCsTz |j|\}}Wntyt tdƒ¡YSw| ¡|j|=t td|ƒ¡S)Nr}r)r{ÚKeyErrorrr~rMÚcancelrr*)rXr†r‚r r7r7r;Ú_expireRegistrationÈs ÿz$InMemoryRegistry._expireRegistrationcCsÐ|j|jkrt d¡t tdƒ¡S|j|jkr$t d¡t tdƒ¡S|j|jvr8|j|j\}}|  d¡n t   d|j |j¡}t d|  ¡›d|  ¡›¡||f|j|j<t tt| ¡t ¡ƒ|ƒ¡S)Nz(Registration for domain we don't handle.r+iz Registered z at )rJrzr r rr~r»r†r{rÛr Ú callLaterr‡rirr*rvrƒr„)rXr1r2r3r‚Úoldr7r7r;r4Òs       z InMemoryRegistry.registerAddresscCs | |j¡Sr…)r‡r†)rXr1r2r3r7r7r;r6ârõz"InMemoryRegistry.unregisterAddressN) rjrkrlrmr[r:r8r‡r4r6r7r7r7r;ry¬s   ry)NN)NNr):rmr<r„rOÚ collectionsrÚtypingrrÚzope.interfacerrÚtwistedrÚtwisted.internetrr r Útwisted.protocolsr Útwisted.pythonr rnÚ shortHeadersrÂrdrhrrµr“r@rDÚobjectrTrErƒr„rªr«r³r¶r´r»r¾rÐr×rírØÚDatagramProtocolrr)r*r.r9r;rQrTryr7r7r7r;ÚsJ    ÷  ÿþýüûúùø ÷ ö õ ô óòñðïîíìëêéèçæåäãâá à!ß"Þ#Ý$Ü%Û&Ú'Ù(Ø)×*Ö+Õ,Ô-Ó.Ò/Ñ0Ð1Ï2Î3Í4Ë9ý + T7 # (%d