|
reSIProcate/stack
9694
|
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 */
1.7.5.1