⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipurl.cxx

📁 SIP(Session Initiation Protocol)是由IETF定义
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const SipUrl_cxx_Version =    "$Id: SipUrl.cxx,v 1.134 2002/12/14 01:05:12 veer Exp $";#include "global.h"#include "SipUrl.hxx"#include "symbols.hxx"#include "HostMatch.hxx"#include "cpLog.h"#include "Data.hxx"#include <cassert>#include "SipUser.hxx"#include "SipTelSubscriberUser.hxx"using namespace Vocal;//const Data DefaultSipPort(DEFAULT_SIP_PORT);stringSipUrlParserException::getName( void ) const{    return "SipUrlParserException";}void SipUrl::initializeFrom(){    transportParam.erase();    maddrParam.erase();    headers.erase();    lrParam = false;}    void SipUrl::initializeTo(){    transportParam.erase();    maddrParam.erase();    ttlParam.erase();    lrParam = false;}SipUrl::SipUrl(const SipUrl& src)    :BaseUrl(),     schemeName(src.schemeName),     passwd(src.passwd),     host(src.host),     port(src.port),     transportParam(src.transportParam),     ttlParam(src.ttlParam),     maddrParam(src.maddrParam),     userParam(src.userParam),     methodParam(src.methodParam),     otherParam(src.otherParam),     otherName(src.otherName),     headers(src.headers),     lrParam(src.lrParam),     ipv6Addr(src.ipv6Addr),     EscObj(src.EscObj){    if (src.user != 0)    {        user = src.user->duplicate(); //Sptr of BaseUser now.    }}SipUrl::SipUrl( const Data& data ) throw(SipUrlParserException&)    :BaseUrl(),     schemeName("sip"),     user(),     passwd(),     host(),     port(),     transportParam(),     ttlParam(),     maddrParam(),     userParam(),     methodParam(),     otherParam(),     otherName(),     headers(),     lrParam(false),     ipv6Addr(false),     EscObj(){    try    {        decode(data);    }    catch (SipUrlParserException&)    {        if (SipParserMode::sipParserMode())        {            throw SipUrlParserException("failed in Decode", __FILE__, __LINE__, DECODE_FAILED);        }    }}SipUrl::SipUrl(bool lr)    :BaseUrl(),     schemeName("sip"),     user(),     passwd(),     host(),     port(),     transportParam(),     ttlParam(),     maddrParam(),     userParam(),     methodParam(),     otherParam(),     otherName(),     headers(),     lrParam(lr), // !jf! - should be true when it is a looser router     ipv6Addr(false),     EscObj(){}SipUrl::~SipUrl(){}UrlTypeSipUrl::getType() const{    return SIP_URL;}    Sptr<BaseUrl> SipUrl::duplicate() const{    return new SipUrl(*this);}        bool SipUrl::areEqual(Sptr<BaseUrl> baseUrl) const{    if (baseUrl != 0)    {                return areEqual(*baseUrl);    }    else    {        return false;    }}        bool SipUrl::isLessThan(Sptr<BaseUrl> baseUrl) const{        if (baseUrl != 0 && baseUrl->getType() == SIP_URL)    {        Sptr<SipUrl> newUrl;        newUrl.dynamicCast(baseUrl);        assert(newUrl != 0);        return ( *(this) < *(newUrl) );    }    else    {	return false;    }}boolSipUrl::areEqual(const BaseUrl& baseUrl) const{    if(baseUrl.getType() == SIP_URL)    {        const SipUrl& newUrl = dynamic_cast<const SipUrl&> (baseUrl);        return ( *(this) == newUrl );    }    else    {        return false;    }}        SipUrl& SipUrl::operator =(const SipUrl& srcUrl){     if (&srcUrl != this)     {	schemeName = srcUrl.schemeName;        if(srcUrl.user != 0)	   user = srcUrl.user->duplicate();	passwd = srcUrl.passwd;	host = srcUrl.host;	port = srcUrl.port;	transportParam = srcUrl.transportParam;	ttlParam = srcUrl.ttlParam;	maddrParam = srcUrl.maddrParam;	userParam = srcUrl.userParam;	methodParam = srcUrl.methodParam;	otherParam = srcUrl.otherParam;	headers = srcUrl.headers;        lrParam = srcUrl.lrParam;        ipv6Addr = srcUrl.ipv6Addr;        if(srcUrl.EscObj != 0)            EscObj = srcUrl.EscObj;    }    return (*this);}#define IsLess(a, b) if ((a) < (b)) return true; else if ((b) < (a)) return falsebool SipUrl::operator<(const SipUrl& src) const{    IsLess(user, src.user); //this will call SipUser, or SipTelSubscriberUsr isLessThan    IsLess(passwd, src.passwd);    IsLess(ttlParam, src.ttlParam);    IsLess(maddrParam, src.maddrParam);    IsLess(userParam, src.userParam);    IsLess(methodParam, src.methodParam);    IsLess(otherParam, src.otherParam);    IsLess(port, src.port);        IsLess(headers, src.headers);        return false;}#undef IsLessbool SipUrl::operator>(const SipUrl& srcUrl) const{    //compare reverse.    return ( srcUrl < (*this) );}        bool SipUrl::operator ==(const SipUrl& srcUrl) const{    bool equal = false;    cpLog(LOG_DEBUG_STACK, "Url operator ==  function");    if (user != 0)    {	cpLog(LOG_DEBUG_STACK, "this.user= %s", user->encode().logData());    }    if (srcUrl.user != 0)    {	cpLog(LOG_DEBUG_STACK, "other.user= %s", srcUrl.user->encode().logData());    }    cpLog(LOG_DEBUG_STACK, "this.passwd= %s" , passwd.logData());    cpLog(LOG_DEBUG_STACK, "other.passwd= %s", srcUrl.passwd.logData());        cpLog(LOG_DEBUG_STACK, "this.host= %s" , host.logData());    cpLog(LOG_DEBUG_STACK, "other.host= %s", srcUrl.host.logData());        cpLog(LOG_DEBUG_STACK, "this.ttlParam= %s", ttlParam.logData() );    cpLog(LOG_DEBUG_STACK, "other.ttlParam= %s" , srcUrl.ttlParam.logData());        cpLog(LOG_DEBUG_STACK, "this.maddrParam= %s" , maddrParam.logData());    cpLog(LOG_DEBUG_STACK, "other.maddrParam= %s" , 	                                    srcUrl.maddrParam.logData());        cpLog(LOG_DEBUG_STACK, "this.userParam= %s " , userParam.logData());    cpLog(LOG_DEBUG_STACK, "other.userParam= %s" , srcUrl.userParam.logData());    cpLog(LOG_DEBUG_STACK, "this.methodParam= %s" , methodParam.logData());    cpLog(LOG_DEBUG_STACK, "other.methodParam= %s" , srcUrl.methodParam.logData());    cpLog(LOG_DEBUG_STACK, "this.otherParam= %s", otherParam.logData());    cpLog(LOG_DEBUG_STACK, "other.otherParam= %s" , 	                      srcUrl.otherParam.logData());        cpLog(LOG_DEBUG_STACK, "this.headers = %s" , headers.logData());    cpLog(LOG_DEBUG_STACK, "other.headers = %s" , srcUrl.headers.logData());        //compare user if it is defined.    if ( (user != 0) && (srcUrl.user != 0) )    {        equal = ( user->areEqual(srcUrl.user) );    }    else if ( (user.getPtr() == 0) && (srcUrl.user.getPtr() == 0) )    {	//both are empty.	equal = true;    }    else    {	equal = false;    }        //take care of some header comparsions requiring case sensitivity, and    //some requiring case-insensitivity.    equal =  (equal && 	     (isEqualNoCase(schemeName, srcUrl.schemeName)) &&	     (passwd == srcUrl.passwd) &&             (isEqualNoCase(host, srcUrl.host) ) &&             (isEqualNoCase(ttlParam,srcUrl.ttlParam)) &&             (maddrParam == srcUrl.maddrParam) &&             (isEqualNoCase(userParam,srcUrl.userParam) ) &&             (methodParam == srcUrl.methodParam) &&             (isEqualNoCase(otherParam, srcUrl.otherParam)) &&             (isEqualNoCase(headers, srcUrl.headers)) );    //compare the parameters having default values.    if ( srcUrl.port.length() && port.length() )    {        equal = (equal && (port == srcUrl.port));    }    else    {	// one or the other is a default	// the two ? : expressions evaluate to either the default	// value (in this case Data("5060") if there is nothing in the	// port) or the port (which is a Data) if there is something	// there.  Thus, when they are compared via == , you do a	// comparison which substitutes the default value if they are	// not supplied.	equal = (equal && 		 (( (srcUrl.port.length() == 0) ? Data("5060") : srcUrl.port) 		  ==		  ( (port.length() == 0) ? Data("5060") : port)));    }    if (( srcUrl.transportParam.length() && transportParam.length()) )    {	equal = (equal && (transportParam == srcUrl.transportParam));    }    else    {	// the two ? : expressions evaluate to either the default	// value (in this case Data("udp") if there is nothing in the	// port) or the port (which is a Data) if there is something	// there.  Thus, when they are compared via == , you do a	// comparison which substitutes the default value if they are	// not supplied.	equal = (equal && 		 (( (srcUrl.transportParam.length() == 0) ? 		    Data("udp") : srcUrl.transportParam)  ==		  ( (transportParam.length() == 0) ? Data("udp") : transportParam)));    }            cpLog(LOG_DEBUG_STACK, "sipUrl comparison: , returning: %s", (equal == true ? "true" : "false" ));    return equal;    }    voidSipUrl::decode( const Data& urlstr ){    if (fastDecode(urlstr) == false)     {        cpLog(LOG_ERR, "Failed in Decode (SIP_URL): %s", urlstr.logData());        throw SipUrlParserException("Failed in Decode (SIP_URL)",                                     __FILE__, __LINE__, NOT_VALID_URL_DATA);    }    //cpLog(LOG_DEBUG_STACK, "completed decoding in the SipUrl");}    // SipUrl::decodeboolSipUrl::fastDecode( Data myData ){    // new decoder, hopefully faster    bool userValid  = false;    bool hostValid = false;    bool portValid = false;    bool userParamValid = false; // used to figure if the user is     //telUser or sipUser to parse differently.    bool parseFailed;        string::size_type keyPos;    string tmpmyData;    string workstring = myData.convertString();    if((keyPos = workstring.find_first_of("?")) != string::npos){        string escData;        tmpmyData = workstring.substr(0, keyPos);        escData = workstring.substr(keyPos+1, string::npos);        EscObj = new EmbeddedObj(escData);        myData = tmpmyData;       }    Data userInfo;    Data urlType = myData.parse(":", &parseFailed);    if(parseFailed)    {	cpLog(LOG_DEBUG, "parse failed: could not find ':' separating URL type from body: %s", myData.logData());	return false;    }    if  (!isEqualNoCase(urlType, "sip") )    {	cpLog(LOG_DEBUG, "parse failed: scheme not SIP: %s", myData.logData());	return false;    }    //set it.    schemeName = urlType;        // now, either user or host, depending    char matchedChar;    Data tmpData;    bool ret;    tmpData = myData.matchChar("@", &matchedChar);    if(matchedChar == '@')    {	// this really is a user	userInfo = tmpData;	userValid = true;	// the next thing must be a host, optionally followed by a port        //Check to see if the address is a IPV6 address        host = myData.matchChar("[", &matchedChar);        if(matchedChar == '[')        {            //Ok this is a IPv6 address            ret = parseIpv6Address(myData);            if(!ret) return ret;        }        if(host.length())        {           //It was a IPV6 address           //eat away extra :;           Data eData = myData.matchChar(":;", &matchedChar); 	   hostValid = true;        }        else        {            //Take the address to be IPV4 address	    host = myData.matchChar(":;", &matchedChar);            if(host.length())	        hostValid = true;                    }	if (matchedChar == ':')	{	    // the next bit is a port	    port = myData.matchChar(";", &matchedChar);	    portValid = true;	    if(matchedChar == ';')	    {		// the rest is fine	    }	    else	    {		// no match -- the rest of myData must be a port		port = myData;		myData.erase();	    }	}	else if(matchedChar == ';')	{	}	else	{	    // maybe there is no separator, so the rest has to be a host	    host = myData;	    myData.erase();	    hostValid = true;	}    }    else    {        //No user part, so parse the host        tmpData = myData.matchChar("[", &matchedChar);        if(matchedChar == '[')        {            //Ok this is a IPv6 address            ret = parseIpv6Address(myData);            if(!ret) return ret;	    hostValid = true;        }        if(host.length())        {            //Since it was already IPV6 address            //eat away extra :;             Data eData = myData.matchChar(":;", &matchedChar);        }        else        {            host = myData.matchChar(":;", &matchedChar);            if(host.length())	         hostValid = true;        }        if (matchedChar == ':')        {        	// this is not a user -- this is a host	    port = myData.matchChar(";", &matchedChar);	    if(matchedChar == ';')	    {	        // this is a port, if there is anything	        portValid = true;	    }	    else	    {	        // myData must contain the port	        port = myData;	        myData.erase();	        portValid = true;	    }        }        else if (matchedChar == ';')        {           //No port do nothing        }        else if(!hostValid)        {           host = myData;           hostValid = true;	   myData.erase();        }    }    if (!hostValid)    {        return false;    }    if (portValid)    {        for (int i=0; i<port.length(); i++)        {            if (!isdigit(port[i]))            {                return false;            }        }    }    // now, look for options, if there are any    bool done = false;    bool matchedParam = false;    while(!done)    {	// look for an equal sign	Data key = myData.matchChar("=", &matchedChar);	Data value;	if(matchedChar == '=')	{	    matchedParam = true;    	    // find the value	    value = myData.matchChar(";?", &matchedChar);	    if((matchedChar != ';') && (matchedChar != '?'))	    {		// did not match, so this must be the last parameter		value = myData;		myData.erase();	    }            else if(matchedChar == '?')            {                //Rest of it is Headers                headers = myData;                myData.erase();	        matchedParam = false;            }	    // do something with the key-value pair            key.removeSpaces();	    if(key == "user")	    {		// do something here		userParamValid = true;		userParam = value;	    }	    else if(key == "transport")	    {		// do something here		transportParam = value;	    }	    else if(key == "ttl")	    {		ttlParam = value;	    }	    else if(key == "maddr")	    {		maddrParam = value;	    }	    else if(key == "method")	    {		methodParam = value;	    }	    else if  (matchedParam)	    {		if (userParam == "phone")		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -