reSIProcate/stack  9694
Uri.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include <set>
00006 
00007 #include "resip/stack/Embedded.hxx"
00008 #include "resip/stack/Helper.hxx"
00009 #include "resip/stack/NameAddr.hxx" 
00010 #include "resip/stack/SipMessage.hxx"
00011 #include "resip/stack/Symbols.hxx"
00012 #include "resip/stack/UnknownParameter.hxx"
00013 #include "resip/stack/Uri.hxx"
00014 #include "rutil/DataStream.hxx"
00015 #include "rutil/DnsUtil.hxx"
00016 #include "rutil/Logger.hxx"
00017 #include "rutil/ParseBuffer.hxx"
00018 //#include "rutil/WinLeakCheck.hxx"  // not compatible with placement new used below
00019 
00020 using namespace resip;
00021 
00022 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00023 #define HANDLE_CHARACTER_ESCAPING //undef for old behaviour
00024 
00025 static bool initAllTables()
00026 {
00027    Uri::getUserEncodingTable();
00028    Uri::getPasswordEncodingTable();
00029    Uri::getLocalNumberTable();
00030    Uri::getGlobalNumberTable();
00031    return true;
00032 }
00033 
00034 const bool Uri::tablesMightBeInitialized(initAllTables());
00035 
00036 Uri::Uri(PoolBase* pool) 
00037    : ParserCategory(pool),
00038      mScheme(Data::Share, Symbols::DefaultSipScheme),
00039      mPort(0),
00040      mHostCanonicalized(false)
00041 {
00042 }
00043 
00044 Uri::Uri(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool) :
00045    ParserCategory(hfv, type, pool),
00046    mPort(0),
00047    mHostCanonicalized(false)
00048 {}
00049 
00050 
00051 static const Data parseContext("Uri constructor");
00052 Uri::Uri(const Data& data)
00053    : ParserCategory(), 
00054      mScheme(Symbols::DefaultSipScheme),
00055      mPort(0),
00056      mHostCanonicalized(false)
00057 {
00058    HeaderFieldValue hfv(data.data(), data.size());
00059    // must copy because parse creates overlays
00060    Uri tmp(hfv, Headers::UNKNOWN);
00061    tmp.checkParsed();
00062    *this = tmp;
00063 }
00064 
00065 Uri::Uri(const Uri& rhs,
00066          PoolBase* pool)
00067    : ParserCategory(rhs, pool),
00068      mScheme(rhs.mScheme),
00069      mHost(rhs.mHost),
00070      mUser(rhs.mUser),
00071      mUserParameters(rhs.mUserParameters),
00072      mPort(rhs.mPort),
00073      mPassword(rhs.mPassword),
00074      mHostCanonicalized(rhs.mHostCanonicalized),
00075      mEmbeddedHeadersText(rhs.mEmbeddedHeadersText.get() ? new Data(*rhs.mEmbeddedHeadersText) : 0),
00076      mEmbeddedHeaders(rhs.mEmbeddedHeaders.get() ? new SipMessage(*rhs.mEmbeddedHeaders) : 0)
00077 {}
00078 
00079 
00080 Uri::~Uri()
00081 {}
00082 
00083 // RFC 3261 19.1.6
00084 #if 0  // deprecated
00085 Uri
00086 Uri::fromTel(const Uri& tel, const Data& host)
00087 {
00088    assert(tel.scheme() == Symbols::Tel);
00089 
00090    Uri u;
00091    u.scheme() = Symbols::Sip;
00092    u.user() = tel.user();
00093    u.host() = host;
00094    u.param(p_user) = Symbols::Phone;
00095 
00096    // need to sort the user parameters
00097    if (!tel.userParameters().empty())
00098    {
00099       DebugLog(<< "Uri::fromTel: " << tel.userParameters());
00100       Data isub;
00101       Data postd;
00102 
00103       int totalSize  = 0;
00104       std::set<Data> userParameters;
00105 
00106       ParseBuffer pb(tel.userParameters().data(), tel.userParameters().size());
00107       while (true)
00108       {
00109          const char* anchor = pb.position();
00110          pb.skipToChar(Symbols::SEMI_COLON[0]);
00111          Data param = pb.data(anchor);
00112          // !dlb! not supposed to lowercase extension parameters
00113          param.lowercase();
00114          totalSize += param.size() + 1;
00115 
00116          if (param.prefix(Symbols::Isub))
00117          {
00118             isub = param;
00119          }
00120          else if (param.prefix(Symbols::Postd))
00121          {
00122             postd = param;
00123          }
00124          else
00125          {
00126             userParameters.insert(param);
00127          }
00128          if (pb.eof())
00129          {
00130             break;
00131          }
00132          else
00133          {
00134             pb.skipChar();
00135          }
00136       }
00137 
00138       u.userParameters().reserve(totalSize);
00139       if (!isub.empty())
00140       {
00141          u.userParameters() = isub;
00142       }
00143       if (!postd.empty())
00144       {
00145          if (!u.userParameters().empty())
00146          {
00147             u.userParameters() += Symbols::SEMI_COLON[0];
00148          }
00149          u.userParameters() += postd;
00150       }
00151       
00152       for(std::set<Data>::const_iterator i = userParameters.begin();
00153           i != userParameters.end(); ++i)
00154       {
00155          DebugLog(<< "Adding param: " << *i);
00156          if (!u.userParameters().empty())
00157          {
00158             u.userParameters() += Symbols::SEMI_COLON[0];
00159          }
00160          u.userParameters() += *i;
00161       }
00162    }
00163 
00164    return u;
00165 }
00166 #endif // deprecated
00167 
00168 Uri
00169 Uri::fromTel(const Uri& tel, const Uri& hostUri)
00170 {
00171    assert(tel.scheme() == Symbols::Tel);
00172 
00173    Uri u(hostUri);
00174    u.scheme() = Symbols::Sip;
00175    u.user() = tel.user();
00176    u.param(p_user) = Symbols::Phone;
00177 
00178    // need to sort the user parameters
00179    if (!tel.userParameters().empty())
00180    {
00181       DebugLog(<< "Uri::fromTel: " << tel.userParameters());
00182       Data isub;
00183       Data postd;
00184 
00185       int totalSize  = 0;
00186       std::set<Data> userParameters;
00187 
00188       ParseBuffer pb(tel.userParameters().data(), tel.userParameters().size());
00189       while (true)
00190       {
00191          const char* anchor = pb.position();
00192          pb.skipToChar(Symbols::SEMI_COLON[0]);
00193          Data param = pb.data(anchor);
00194          // !dlb! not supposed to lowercase extension parameters
00195          param.lowercase();
00196          totalSize += (int)param.size() + 1;
00197 
00198          if (param.prefix(Symbols::Isub))
00199          {
00200             isub = param;
00201          }
00202          else if (param.prefix(Symbols::Postd))
00203          {
00204             postd = param;
00205          }
00206          else
00207          {
00208             userParameters.insert(param);
00209          }
00210          if (pb.eof())
00211          {
00212             break;
00213          }
00214          else
00215          {
00216             pb.skipChar();
00217          }
00218       }
00219 
00220       u.userParameters().reserve(totalSize);
00221       if (!isub.empty())
00222       {
00223          u.userParameters() = isub;
00224       }
00225       if (!postd.empty())
00226       {
00227          if (!u.userParameters().empty())
00228          {
00229             u.userParameters() += Symbols::SEMI_COLON[0];
00230          }
00231          u.userParameters() += postd;
00232       }
00233       
00234       for(std::set<Data>::const_iterator i = userParameters.begin();
00235           i != userParameters.end(); ++i)
00236       {
00237          DebugLog(<< "Adding param: " << *i);
00238          if (!u.userParameters().empty())
00239          {
00240             u.userParameters() += Symbols::SEMI_COLON[0];
00241          }
00242          u.userParameters() += *i;
00243       }
00244    }
00245 
00246    return u;
00247 }
00248 
00249 bool
00250 Uri::isEnumSearchable() const
00251 {
00252    checkParsed();
00253    return (!mUser.empty() && mUser.size() >= 2 && mUser[0] == '+');
00254 }
00255 
00256 std::vector<Data> 
00257 Uri::getEnumLookups(const std::vector<Data>& suffixes) const
00258 {
00259    std::vector<Data> results;
00260    Data prefix;
00261    if (isEnumSearchable())
00262    {
00263       // skip the leading +
00264       for (const char* i=user().end()-1 ; i!= user().begin(); --i)
00265       {
00266          if (isdigit(*i))
00267          {
00268             prefix += *i;
00269             prefix += Symbols::DOT;
00270          }
00271       }
00272       for (std::vector<Data>::const_iterator j=suffixes.begin(); j != suffixes.end(); ++j)
00273       {
00274          results.push_back(prefix + *j);
00275       }
00276    }
00277    return results;
00278 }
00279 
00280 
00281 bool
00282 Uri::hasEmbedded() const
00283 {
00284    checkParsed(); 
00285    return (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty()) || mEmbeddedHeaders.get() != 0;
00286 }
00287 
00288 void 
00289 Uri::removeEmbedded()
00290 {
00291    checkParsed();
00292    mEmbeddedHeaders.reset();
00293    mEmbeddedHeadersText.reset();
00294 }
00295 
00296 
00297 
00298 Uri&
00299 Uri::operator=(const Uri& rhs)
00300 {
00301    if (this != &rhs)
00302    {
00303       ParserCategory::operator=(rhs);
00304       mScheme = rhs.mScheme;
00305       mHost = rhs.mHost;
00306       mHostCanonicalized=rhs.mHostCanonicalized;
00307       mUser = rhs.mUser;
00308       mUserParameters = rhs.mUserParameters;
00309       mPort = rhs.mPort;
00310       mPassword = rhs.mPassword;
00311       if (rhs.mEmbeddedHeaders.get() != 0)
00312       {
00313          mEmbeddedHeaders.reset(new SipMessage(*rhs.mEmbeddedHeaders));
00314       }
00315       else if(rhs.mEmbeddedHeadersText.get() != 0)
00316       {
00317          if(!mEmbeddedHeadersText.get())
00318          {
00319             mEmbeddedHeadersText.reset(new Data(*rhs.mEmbeddedHeadersText));
00320          }
00321          else
00322          {
00323             // !bwc! Data::operator= is smart enough to handle this safely.
00324             *mEmbeddedHeadersText = *rhs.mEmbeddedHeadersText;
00325          }
00326       }
00327    }
00328    return *this;
00329 }
00330 
00335 class OrderUnknownParameters
00336 {
00337    public:
00341       OrderUnknownParameters() { notUsed=false; };
00342 
00346       ~OrderUnknownParameters() {};
00347 
00356       bool operator()(const Parameter* p1, const Parameter* p2) const
00357       {
00358          return dynamic_cast<const UnknownParameter*>(p1)->getName() < dynamic_cast<const UnknownParameter*>(p2)->getName();
00359       }
00360 
00361    private:
00362       bool notUsed;
00363 };
00364 
00365 bool 
00366 Uri::operator==(const Uri& other) const
00367 {
00368    checkParsed();
00369    other.checkParsed();
00370 
00371    // compare hosts
00372    if (DnsUtil::isIpV6Address(mHost) &&
00373        DnsUtil::isIpV6Address(other.mHost))
00374    {
00375 
00376       // compare canonicalized IPV6 addresses
00377 
00378       // update canonicalized if host changed
00379       if (!mHostCanonicalized)
00380       {
00381          mHost = DnsUtil::canonicalizeIpV6Address(mHost);
00382          mHostCanonicalized=true;
00383       }
00384 
00385       // update canonicalized if host changed
00386       if (!other.mHostCanonicalized)
00387       {
00388          other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost);
00389          other.mHostCanonicalized=true;
00390       }
00391 
00392       if (mHost != other.mHost)
00393       {
00394          return false;
00395       }
00396    }
00397    else
00398    {
00399       if (!isEqualNoCase(mHost, other.mHost))
00400       {
00401          return false;
00402       }
00403    }
00404    
00405    if (isEqualNoCase(mScheme, other.mScheme) &&
00406        ((isEqualNoCase(mScheme, Symbols::Sip) || isEqualNoCase(mScheme, Symbols::Sips)) ? mUser == other.mUser : isEqualNoCase(mUser, other.mUser)) &&
00407        isEqualNoCase(mUserParameters,other.mUserParameters) &&
00408        mPassword == other.mPassword &&
00409        mPort == other.mPort)
00410    {
00411       for (ParameterList::const_iterator it = mParameters.begin(); it != mParameters.end(); ++it)
00412       {
00413          Parameter* otherParam = other.getParameterByEnum((*it)->getType());
00414 
00415          switch ((*it)->getType())
00416          {
00417             case ParameterTypes::user:
00418             {
00419                if (!(otherParam &&
00420                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00421                                    dynamic_cast<DataParameter*>(otherParam)->value())))
00422                {
00423                   return false;
00424                }
00425             }
00426             break;
00427             case ParameterTypes::ttl:
00428             {
00429                if (!(otherParam &&
00430                      (dynamic_cast<UInt32Parameter*>(*it)->value() ==
00431                       dynamic_cast<UInt32Parameter*>(otherParam)->value())))
00432                {
00433                   return false;
00434                }
00435                break;
00436             }
00437             case ParameterTypes::method:
00438             {
00439                // this should possibly be case sensitive, but is allowed to be
00440                // case insensitive for robustness.  
00441                
00442                if (otherParam)
00443                {
00444                   DataParameter* dp1 = dynamic_cast<DataParameter*>(*it);
00445                   DataParameter* dp2 = dynamic_cast<DataParameter*>(otherParam);
00446                   (void)dp1;
00447                   (void)dp2;
00448                   // ?bwc? It looks like we're just assuming the dynamic_cast 
00449                   // will succeed everywhere else; why are we bothering to 
00450                   // assert()?
00451                   assert(dp1);
00452                   assert(dp2);
00453                }
00454                if (!(otherParam &&
00455                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00456                                    dynamic_cast<DataParameter*>(otherParam)->value())))
00457                {
00458                   return false;
00459                }
00460                break;
00461             }
00462             case ParameterTypes::maddr:
00463             {               
00464                if (!(otherParam &&
00465                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00466                                    dynamic_cast<DataParameter*>(otherParam)->value())))
00467                {
00468                   return false;
00469                }
00470             }
00471             break;
00472             case ParameterTypes::transport:
00473             {
00474                if (!(otherParam &&
00475                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00476                                    dynamic_cast<DataParameter*>(otherParam)->value())))
00477                {
00478                   return false;
00479                }
00480             }
00481             break;
00482             // the parameters that follow don't affect comparison if only present
00483             // in one of the URI's
00484             case ParameterTypes::lr:
00485                break;
00486             default:
00487                break;
00488                //treat as unknown parameter?
00489          }
00490       }         
00491 
00492       // now check the other way, sigh
00493       for (ParameterList::const_iterator it = other.mParameters.begin(); it != other.mParameters.end(); ++it)
00494       {
00495          Parameter* param = getParameterByEnum((*it)->getType());
00496          switch ((*it)->getType())
00497          {
00498             case ParameterTypes::user:
00499             {
00500                if (!(param &&
00501                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00502                                    dynamic_cast<DataParameter*>(param)->value())))
00503                {
00504                   return false;
00505                }
00506             }
00507             break;
00508             case ParameterTypes::ttl:
00509             {
00510                if (!(param &&
00511                      (dynamic_cast<UInt32Parameter*>(*it)->value() == 
00512                       dynamic_cast<UInt32Parameter*>(param)->value())))
00513                {
00514                   return false;
00515                }
00516                break;
00517             }
00518             case ParameterTypes::method:
00519             {
00520                // this should possilby be case sensitive, but is allowed to be
00521                // case insensitive for robustness.  
00522                if (!(param &&
00523                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00524                                    dynamic_cast<DataParameter*>(param)->value())))
00525                {
00526                   return false;
00527                }
00528             }
00529             break;
00530             case ParameterTypes::maddr:
00531             {               
00532                if (!(param &&
00533                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00534                                    dynamic_cast<DataParameter*>(param)->value())))
00535                {
00536                   return false;
00537                }
00538             }
00539             break;
00540             case ParameterTypes::transport:
00541             {
00542                if (!(param &&
00543                      isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
00544                                    dynamic_cast<DataParameter*>(param)->value())))
00545                {
00546                   return false;
00547                }
00548             }
00549             break;
00550             // the parameters that follow don't affect comparison if only present
00551             // in one of the URI's
00552             case ParameterTypes::lr:
00553                break;
00554             default:
00555                break;
00556                //treat as unknown parameter?
00557          }
00558       }
00559    }
00560    else
00561    {
00562       return false;
00563    }
00564 
00565    OrderUnknownParameters orderUnknown;
00566 
00567 #if defined(__SUNPRO_CC) || defined(WIN32) || defined(__sun__)
00568    // The Solaris Forte STL implementation does not support the
00569    // notion of a list.sort() function taking a BinaryPredicate.
00570    // The hacky workaround is to load the Parameter pointers into
00571    // an STL set which does support an ordering function.
00572 
00573    typedef std::set<Parameter*, OrderUnknownParameters> ParameterSet;
00574    ParameterSet unA, unB;
00575 
00576    for (ParameterList::const_iterator i = mUnknownParameters.begin();
00577         i != mUnknownParameters.end(); ++i)
00578    {
00579       unA.insert(*i);
00580    }
00581    for (ParameterList::const_iterator i = other.mUnknownParameters.begin();
00582         i != other.mUnknownParameters.end(); ++i)
00583    {
00584       unB.insert(*i);
00585    }
00586 
00587    ParameterSet::iterator a = unA.begin();
00588    ParameterSet::iterator b = unB.begin();
00589 #else
00590    // .dlb. more efficient to copy to vector for sorting?
00591    // Uri comparison is expensive; consider caching? ugh
00592    ParameterList unA = mUnknownParameters;
00593    ParameterList unB = other.mUnknownParameters;
00594 
00595    sort(unA.begin(), unA.end(), orderUnknown);
00596    sort(unB.begin(), unB.end(), orderUnknown);
00597  
00598    ParameterList::iterator a = unA.begin();
00599    ParameterList::iterator b = unB.begin();
00600 #endif
00601 
00602    while(a != unA.end() && b != unB.end())
00603    {
00604       if (orderUnknown(*a, *b))
00605       {
00606          ++a;
00607       }
00608       else if (orderUnknown(*b, *a))
00609       {
00610          ++b;
00611       }
00612       else
00613       {
00614          if (!isEqualNoCase(dynamic_cast<UnknownParameter*>(*a)->value(),
00615                             dynamic_cast<UnknownParameter*>(*b)->value()))
00616          {
00617             return false;
00618          }
00619          ++a;
00620          ++b;
00621       }
00622    }
00623    return true;
00624 }
00625 
00626 bool 
00627 Uri::operator!=(const Uri& other) const
00628 {
00629    return !(*this == other);
00630 }
00631 
00632 bool
00633 Uri::operator<(const Uri& other) const
00634 {
00635    other.checkParsed();
00636    checkParsed();
00637    if (mUser < other.mUser)
00638    {
00639       return true;
00640    }
00641 
00642    if (mUser > other.mUser)
00643    {
00644       return false;
00645    }
00646 
00647    if (mUserParameters < other.mUserParameters)
00648    {
00649       return true;
00650    }
00651 
00652    if (mUserParameters > other.mUserParameters)
00653    {
00654       return false;
00655    }
00656 
00657    // !bwc! Canonicalize before we compare! Jeez...
00658    if (!mHostCanonicalized)
00659    {
00660       if(DnsUtil::isIpV6Address(mHost))
00661       {
00662          mHost = DnsUtil::canonicalizeIpV6Address(mHost);
00663       }
00664       else
00665       {
00666          mHost.lowercase();
00667       }
00668       mHostCanonicalized=true;
00669    }
00670    
00671    if (!other.mHostCanonicalized)
00672    {
00673       if(DnsUtil::isIpV6Address(other.mHost))
00674       {
00675          other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost);
00676       }
00677       else
00678       {
00679          other.mHost.lowercase();
00680       }
00681       other.mHostCanonicalized=true;
00682    }
00683 
00684    if (mHost < other.mHost)
00685    {
00686       return true;
00687    }
00688 
00689    if (mHost > other.mHost)
00690    {
00691       return false;
00692    }
00693 
00694    return mPort < other.mPort;
00695 }
00696 
00697 bool
00698 Uri::aorEqual(const resip::Uri& rhs) const
00699 {
00700    checkParsed();
00701    rhs.checkParsed();
00702 
00703    if (!mHostCanonicalized)
00704    {
00705       if(DnsUtil::isIpV6Address(mHost))
00706       {
00707          mHost = DnsUtil::canonicalizeIpV6Address(mHost);
00708       }
00709       else
00710       {
00711          mHost.lowercase();
00712       }
00713       mHostCanonicalized=true;
00714    }
00715    
00716    if (!rhs.mHostCanonicalized)
00717    {
00718       if(DnsUtil::isIpV6Address(rhs.mHost))
00719       {
00720          rhs.mHost = DnsUtil::canonicalizeIpV6Address(rhs.mHost);
00721       }
00722       else
00723       {
00724          rhs.mHost.lowercase();
00725       }
00726       rhs.mHostCanonicalized=true;
00727    }
00728    
00729    return (mUser==rhs.mUser) && (mHost==rhs.mHost) && (mPort==rhs.mPort) && 
00730             (isEqualNoCase(mScheme,rhs.mScheme));
00731 }
00732 
00733 void 
00734 Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const
00735 {
00736    checkParsed();
00737    // canonicalize host
00738 
00739    addPort = addPort && mPort!=0;
00740 
00741    bool hostIsIpV6Address = false;
00742    if(!mHostCanonicalized)
00743    {
00744       if (DnsUtil::isIpV6Address(mHost))
00745       {
00746          mHost = DnsUtil::canonicalizeIpV6Address(mHost);
00747          hostIsIpV6Address = true;
00748       }
00749       else
00750       {
00751          mHost.lowercase();
00752       }
00753    }
00754 
00755    // !bwc! Maybe reintroduce caching of aor. (Would use a bool instead of the
00756    // mOldX cruft)
00757    //                                                  @:10000
00758    aor.clear();
00759    aor.reserve((dropScheme ? 0 : mScheme.size()+1)
00760                + mUser.size() + mHost.size() + 7);
00761    if(!dropScheme)
00762    {
00763       aor += mScheme;
00764       aor += ':';
00765    }
00766 
00767    if (!mUser.empty())
00768    {
00769 #ifdef HANDLE_CHARACTER_ESCAPING
00770       {
00771          oDataStream str(aor);
00772          mUser.escapeToStream(str, getUserEncodingTable()); 
00773       }
00774 #else
00775       aor += mUser;
00776 #endif
00777       if(!mHost.empty())
00778       {
00779          aor += Symbols::AT_SIGN;
00780       }
00781    }
00782 
00783    if(hostIsIpV6Address && addPort)
00784    {
00785       aor += Symbols::LS_BRACKET;
00786       aor += mHost;
00787       aor += Symbols::RS_BRACKET;
00788    }
00789    else
00790    {
00791       aor += mHost;
00792    }
00793 
00794    if(addPort)
00795    {
00796       aor += Symbols::COLON;
00797       aor += Data(mPort);
00798    }
00799 }
00800 
00801 Data 
00802 Uri::getAOR(bool addPort) const
00803 {
00804    Data result;
00805    getAorInternal(false, addPort, result);
00806    return result;
00807 }
00808 
00809 bool 
00810 Uri::userIsTelephoneSubscriber() const
00811 {
00812    try
00813    {
00814       ParseBuffer pb(mUser);
00815       pb.assertNotEof();
00816       const char* anchor=pb.position();
00817       bool local=false;
00818       if(*pb.position()=='+')
00819       {
00820          // Might be a global phone number
00821          pb.skipChar();
00822          pb.skipChars(getGlobalNumberTable());
00823       }
00824       else
00825       {
00826          pb.skipChars(getLocalNumberTable());
00827          local=true;
00828       }
00829 
00830       Data dialString(pb.data(anchor));
00831       if(dialString.empty())
00832       {
00833          pb.fail(__FILE__, __LINE__, "Dial string is empty.");
00834       }
00835 
00836       // ?bwc? More dial-string checking? For instance, +/ (or simply /) is not 
00837       // a valid dial-string according to the BNF; the string must contain at 
00838       // least one actual digit (or in the local number case, one hex digit or 
00839       // '*' or '#'. Interestingly, this means that stuff like ///*/// is 
00840       // valid)
00841 
00842       // Dial string looks ok so far; now look for params (there must be a 
00843       // phone-context param if this is a local number, otherwise there might 
00844       // or might not be one)
00845       if(local || !pb.eof())
00846       {
00847          // The only thing that can be here is a ';'. If it does, we're going 
00848          // to say it is good enough for us. If something in the parameter 
00849          // string is malformed, it'll get caught when/if 
00850          // getUserAsTelephoneSubscriber() is called.
00851          pb.skipChar(';');
00852       }
00853 
00854       return true;
00855    }
00856    catch(ParseException& /*e*/)
00857    {
00858       return false;
00859    }
00860 }
00861 
00862 Token 
00863 Uri::getUserAsTelephoneSubscriber() const
00864 {
00865    // !bwc! Ugly. Someday, refactor all this lazy-parser stuff and make it 
00866    // possible to control ownership explicitly.
00867    // Set this up as lazy-parsed, to prevent exceptions from being thrown.
00868    HeaderFieldValue temp(mUser.data(), mUser.size());
00869    Token tempToken(temp, Headers::NONE);
00870    // tempToken does not own the HeaderFieldValue temp, and temp does not own 
00871    // its buffer.
00872 
00873    // Here's the voodoo; invoking operator= makes a deep copy of the stuff in
00874    // tempToken, with result owning the memory, and result is in the unparsed 
00875    // state.
00876    Token result = tempToken;
00877    return result;
00878 }
00879 
00880 void 
00881 Uri::setUserAsTelephoneSubscriber(const Token& telephoneSubscriber)
00882 {
00883    mUser.clear();
00884    oDataStream str(mUser);
00885    str << telephoneSubscriber;
00886 }
00887 
00888 Data
00889 Uri::getAorNoPort() const
00890 {
00891    Data result;
00892    getAorInternal(true, false, result);
00893    return result;
00894 }
00895 
00896 Data
00897 Uri::getAor() const
00898 {
00899    Data result;
00900    getAorInternal(true, true, result);
00901    return result;
00902 }
00903 
00904 Uri 
00905 Uri::getAorAsUri(TransportType transportTypeToRemoveDefaultPort) const
00906 {   
00907    //.dcm. -- tel conversion?
00908    checkParsed();
00909    Uri ret;
00910    ret.scheme() = mScheme;   
00911    ret.user() = mUser;
00912    ret.host() = mHost;
00913 
00914    // Remove any default ports (if required)
00915    if(transportTypeToRemoveDefaultPort == UDP || 
00916        transportTypeToRemoveDefaultPort == TCP)
00917    {
00918       if(mPort != Symbols::DefaultSipPort)
00919       {
00920          ret.port() = mPort;
00921       }
00922    }
00923    else if (transportTypeToRemoveDefaultPort == TLS || 
00924             transportTypeToRemoveDefaultPort == DTLS)
00925    {
00926       if(mPort != Symbols::DefaultSipsPort)
00927       {
00928          ret.port() = mPort;
00929       }
00930    }
00931    else
00932    {
00933       ret.port() = mPort;
00934    }
00935 
00936    return ret;
00937 }
00938 
00939 void
00940 Uri::parse(ParseBuffer& pb)
00941 {
00942    pb.skipWhitespace();
00943    const char* start = pb.position();
00944    pb.skipToOneOf(":@");
00945 
00946    pb.assertNotEof();
00947 
00948    pb.data(mScheme, start);
00949    pb.skipChar(Symbols::COLON[0]);
00950    mScheme.schemeLowercase();
00951 
00952    if (mScheme==Symbols::Tel)
00953    {
00954       const char* anchor = pb.position();
00955       static std::bitset<256> delimiter=Data::toBitset("\r\n\t ;>");
00956       pb.skipToOneOf(delimiter);
00957       pb.data(mUser, anchor);
00958       if (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0])
00959       {
00960          anchor = pb.skipChar();
00961          pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::RA_QUOTE);
00962          pb.data(mUserParameters, anchor);
00963       }
00964       return;
00965    }
00966    
00967    start = pb.position();
00968    static std::bitset<256> userPortOrPasswordDelim(Data::toBitset("@:\""));
00969    // stop at double-quote to prevent matching an '@' in a quoted string param. 
00970    pb.skipToOneOf(userPortOrPasswordDelim);
00971    if (!pb.eof())
00972    {
00973       const char* atSign=0;
00974       if (*pb.position() == Symbols::COLON[0])
00975       {
00976          // Either a password, or a port
00977          const char* afterColon = pb.skipChar();
00978          pb.skipToOneOf("@\"");
00979          if(!pb.eof() && *pb.position() == Symbols::AT_SIGN[0])
00980          {
00981             atSign=pb.position();
00982             // password
00983 #ifdef HANDLE_CHARACTER_ESCAPING
00984             pb.dataUnescaped(mPassword, afterColon);
00985 #else
00986             pb.data(mPassword, afterColon);
00987 #endif
00988             pb.reset(afterColon-1);
00989          }
00990          else
00991          {
00992             // port. No user part.
00993             pb.reset(start);
00994          }
00995       }
00996       else if(*pb.position() == Symbols::AT_SIGN[0])
00997       {
00998          atSign=pb.position();
00999       }
01000       else
01001       {
01002          // Only a hostpart
01003          pb.reset(start);
01004       }
01005 
01006       if(atSign)
01007       {
01008 #ifdef HANDLE_CHARACTER_ESCAPING
01009          pb.dataUnescaped(mUser, start);
01010 #else
01011          pb.data(mUser, start);
01012 #endif
01013          pb.reset(atSign);
01014          start = pb.skipChar();
01015       }
01016    }
01017    else
01018    {
01019       pb.reset(start);
01020    }
01021 
01022    mHostCanonicalized=false;
01023    static std::bitset<256> hostDelimiter(Data::toBitset("\r\n\t :;?>"));
01024    if (*start == '[')
01025    {
01026       start = pb.skipChar();
01027       pb.skipToChar(']');
01028       pb.data(mHost, start);
01029       // .bwc. We do not save this canonicalization, since we weren't doing so
01030       // before. This may change soon.
01031       Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mHost);
01032       if(canonicalizedHost.empty())
01033       {
01034          // .bwc. So the V6 addy is garbage.
01035          throw ParseException("Unparsable V6 address (note, this might"
01036                                     " be unparsable because IPV6 support is not"
01037                                     " enabled)","Uri",__FILE__,
01038                                        __LINE__);
01039       }
01040       pb.skipChar();
01041       pb.skipToOneOf(hostDelimiter);
01042    }
01043    else
01044    {
01045       pb.skipToOneOf(hostDelimiter);
01046       pb.data(mHost, start);
01047    }
01048 
01049    if (!pb.eof() && *pb.position() == ':')
01050    {
01051       start = pb.skipChar();
01052       mPort = pb.uInt32();
01053    }
01054    else
01055    {
01056       mPort = 0;
01057    }
01058 
01059    parseParameters(pb);
01060 
01061    if (!pb.eof() && *pb.position() == Symbols::QUESTION[0])
01062    {
01063       const char* anchor = pb.position();
01064       pb.skipToOneOf(">;", ParseBuffer::Whitespace);
01065       if(!mEmbeddedHeadersText.get()) mEmbeddedHeadersText.reset(new Data);
01066       pb.data(*mEmbeddedHeadersText, anchor);
01067    }
01068 }
01069 
01070 ParserCategory*
01071 Uri::clone() const
01072 {
01073    return new Uri(*this);
01074 }
01075 
01076 ParserCategory*
01077 Uri::clone(void* location) const
01078 {
01079    return new (location) Uri(*this);
01080 }
01081 
01082 ParserCategory*
01083 Uri::clone(PoolBase* pool) const
01084 {
01085    return new (pool) Uri(*this);
01086 }
01087 
01088 void Uri::setUriUserEncoding(unsigned char c, bool encode) 
01089 {
01090    getUserEncodingTable()[c] = encode; 
01091 }
01092 
01093 void Uri::setUriPasswordEncoding(unsigned char c, bool encode)
01094 {
01095    getPasswordEncodingTable()[c] = encode;
01096 }
01097 
01098 // should not encode user parameters unless its a tel?
01099 EncodeStream& 
01100 Uri::encodeParsed(EncodeStream& str) const
01101 {
01102    str << mScheme << Symbols::COLON; 
01103    if (!mUser.empty())
01104    {
01105 #ifdef HANDLE_CHARACTER_ESCAPING
01106       mUser.escapeToStream(str, getUserEncodingTable()); 
01107 #else
01108       str << mUser;
01109 #endif
01110       if (!mUserParameters.empty())
01111       {
01112          str << Symbols::SEMI_COLON[0] << mUserParameters;
01113       }
01114       if (!mPassword.empty())
01115       {
01116          str << Symbols::COLON;
01117 #ifdef HANDLE_CHARACTER_ESCAPING
01118          mPassword.escapeToStream(str, getPasswordEncodingTable());
01119 #else
01120          str << mPassword;
01121 #endif
01122       }
01123    }
01124    if (!mHost.empty())
01125    {
01126      if (!mUser.empty())
01127      {
01128        str << Symbols::AT_SIGN;
01129      }
01130      if (DnsUtil::isIpV6Address(mHost))
01131      {
01132         str << '[' << mHost << ']';
01133      }
01134      else
01135      {
01136         str << mHost;
01137      }
01138    }
01139    if (mPort != 0)
01140    {
01141       str << Symbols::COLON << mPort;
01142    }
01143    encodeParameters(str);
01144    encodeEmbeddedHeaders(str);
01145 
01146    return str;
01147 }
01148 
01149 SipMessage&
01150 Uri::embedded()
01151 {
01152    checkParsed();
01153    if (mEmbeddedHeaders.get() == 0)
01154    {
01155       this->mEmbeddedHeaders.reset(new SipMessage());
01156       if (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty())
01157       {
01158          ParseBuffer pb(mEmbeddedHeadersText->data(), mEmbeddedHeadersText->size());
01159          this->parseEmbeddedHeaders(pb);
01160       }
01161    }
01162 
01163    return *mEmbeddedHeaders;
01164 }
01165 
01166 const SipMessage&
01167 Uri::embedded() const
01168 {
01169    Uri* ncthis = const_cast<Uri*>(this);
01170    return ncthis->embedded();
01171 }
01172 
01173 static const Data bodyData("Body");
01174 void
01175 Uri::parseEmbeddedHeaders(ParseBuffer& pb)
01176 {
01177    DebugLog(<< "Uri::parseEmbeddedHeaders");
01178    if (!pb.eof() && *pb.position() == Symbols::QUESTION[0])
01179    {
01180       pb.skipChar();
01181    }
01182 
01183    const char* anchor;
01184    Data headerName;
01185    Data headerContents;
01186 
01187    bool first = true;
01188    while (!pb.eof())
01189    {
01190       if (first)
01191       {
01192          first = false;
01193       }
01194       else
01195       {
01196          pb.skipChar(Symbols::AMPERSAND[0]);
01197       }
01198 
01199       anchor = pb.position();
01200       pb.skipToChar(Symbols::EQUALS[0]);
01201       pb.data(headerName, anchor);
01202       // .dlb. in theory, need to decode header name
01203 
01204       anchor = pb.skipChar(Symbols::EQUALS[0]);
01205       pb.skipToChar(Symbols::AMPERSAND[0]);
01206       pb.data(headerContents, anchor);
01207 
01208       unsigned int len;
01209       char* decodedContents = Embedded::decode(headerContents, len);
01210       mEmbeddedHeaders->addBuffer(decodedContents);
01211 
01212       if (isEqualNoCase(bodyData, headerName))
01213       {
01214          mEmbeddedHeaders->setBody(decodedContents, len); 
01215       }
01216       else
01217       {
01218          DebugLog(<< "Uri::parseEmbeddedHeaders(" << headerName << ", " << Data(decodedContents, len) << ")");
01219          mEmbeddedHeaders->addHeader(Headers::getType(headerName.data(), (int)headerName.size()),
01220                                      headerName.data(), (int)headerName.size(),
01221                                      decodedContents, len);
01222       }
01223    }
01224 }
01225 
01226 EncodeStream& 
01227 Uri::encodeEmbeddedHeaders(EncodeStream& str) const
01228 {
01229    if (mEmbeddedHeaders.get())
01230    {
01231       mEmbeddedHeaders->encodeEmbedded(str);
01232    }
01233    else if(mEmbeddedHeadersText.get())
01234    {
01235       // never decoded
01236       str << *mEmbeddedHeadersText;
01237    }
01238    return str;
01239 }
01240 
01241 Data 
01242 Uri::toString() const
01243 {
01244    Data out;
01245    {
01246       oDataStream dataStream(out);
01247       this->encodeParsed(dataStream);
01248    }
01249    return out;
01250 }
01251 
01252 ParameterTypes::Factory Uri::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0};
01253 
01254 Parameter* 
01255 Uri::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool)
01256 {
01257    if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type])
01258    {
01259       return ParameterFactories[type](type, pb, terminators, pool);
01260    }
01261    return 0;
01262 }
01263 
01264 bool 
01265 Uri::exists(const Param<Uri>& paramType) const
01266 {
01267     checkParsed();
01268     bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL;
01269     return ret;
01270 }
01271 
01272 void 
01273 Uri::remove(const Param<Uri>& paramType)
01274 {
01275     checkParsed();
01276     removeParameterByEnum(paramType.getTypeNum());
01277 }
01278 
01279 #define defineParam(_enum, _name, _type, _RFC_ref_ignored)                                                      \
01280 _enum##_Param::DType&                                                                                           \
01281 Uri::param(const _enum##_Param& paramType)                                                           \
01282 {                                                                                                               \
01283    checkParsed();                                                                                               \
01284    _enum##_Param::Type* p =                                                                                     \
01285       static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
01286    if (!p)                                                                                                      \
01287    {                                                                                                            \
01288       p = new _enum##_Param::Type(paramType.getTypeNum());                                                      \
01289       mParameters.push_back(p);                                                                                 \
01290    }                                                                                                            \
01291    return p->value();                                                                                           \
01292 }                                                                                                               \
01293                                                                                                                 \
01294 const _enum##_Param::DType&                                                                                     \
01295 Uri::param(const _enum##_Param& paramType) const                                                     \
01296 {                                                                                                               \
01297    checkParsed();                                                                                               \
01298    _enum##_Param::Type* p =                                                                                     \
01299       static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
01300    if (!p)                                                                                                      \
01301    {                                                                                                            \
01302       InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]);     \
01303       DebugLog(<< *this);                                                                                       \
01304       throw Exception("Missing parameter " _name, __FILE__, __LINE__);                                          \
01305    }                                                                                                            \
01306    return p->value();                                                                                           \
01307 }
01308 
01309 defineParam(ob,"ob",ExistsParameter,"RFC 5626");
01310 defineParam(gr, "gr", ExistsOrDataParameter, "RFC 5627");
01311 defineParam(comp, "comp", DataParameter, "RFC 3486");
01312 defineParam(duration, "duration", UInt32Parameter, "RFC 4240");
01313 defineParam(lr, "lr", ExistsParameter, "RFC 3261");
01314 defineParam(maddr, "maddr", DataParameter, "RFC 3261");
01315 defineParam(method, "method", DataParameter, "RFC 3261");
01316 defineParam(transport, "transport", DataParameter, "RFC 3261");
01317 defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261");
01318 defineParam(user, "user", DataParameter, "RFC 3261, 4967");
01319 defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when ext is a user-parameter
01320 defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049");
01321 defineParam(rinstance, "rinstance", DataParameter, "proprietary (resip)");
01322 defineParam(addTransport, "addTransport", ExistsParameter, "RESIP INTERNAL");
01323 
01324 #undef defineParam
01325 
01326 HashValueImp(resip::Uri, resip::Data::from(data).hash());
01327 
01328 /* ====================================================================
01329  * The Vovida Software License, Version 1.0 
01330  * 
01331  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
01332  * 
01333  * Redistribution and use in source and binary forms, with or without
01334  * modification, are permitted provided that the following conditions
01335  * are met:
01336  * 
01337  * 1. Redistributions of source code must retain the above copyright
01338  *    notice, this list of conditions and the following disclaimer.
01339  * 
01340  * 2. Redistributions in binary form must reproduce the above copyright
01341  *    notice, this list of conditions and the following disclaimer in
01342  *    the documentation and/or other materials provided with the
01343  *    distribution.
01344  * 
01345  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01346  *    and "Vovida Open Communication Application Library (VOCAL)" must
01347  *    not be used to endorse or promote products derived from this
01348  *    software without prior written permission. For written
01349  *    permission, please contact vocal@vovida.org.
01350  *
01351  * 4. Products derived from this software may not be called "VOCAL", nor
01352  *    may "VOCAL" appear in their name, without prior written
01353  *    permission of Vovida Networks, Inc.
01354  * 
01355  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01356  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01357  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01358  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01359  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01360  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01361  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01362  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01363  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01364  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01365  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01366  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01367  * DAMAGE.
01368  * 
01369  * ====================================================================
01370  * 
01371  * This software consists of voluntary contributions made by Vovida
01372  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01373  * Inc.  For more information on Vovida Networks, Inc., please see
01374  * <http://www.vovida.org/>.
01375  *
01376  */