reSIProcate/stack  9694
Headers.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include "rutil/Data.hxx"
00006 #include "resip/stack/Headers.hxx"
00007 #include "resip/stack/Symbols.hxx"
00008 #include "resip/stack/SipMessage.hxx"
00009 
00010 // GPERF generated external routines
00011 #include "resip/stack/HeaderHash.hxx"
00012 
00013 #include <iostream>
00014 using namespace std;
00015 
00016 //int strcasecmp(const char*, const char*);
00017 //int strncasecmp(const char*, const char*, int len);
00018 
00019 using namespace resip;
00020 
00021 Data Headers::HeaderNames[MAX_HEADERS+1];
00022 bool Headers::CommaTokenizing[] = {false};
00023 bool Headers::CommaEncoding[] = {false};
00024 bool Headers::Multi[]={false};
00025 HeaderBase* HeaderBase::theHeaderInstances[] = {0};
00026 
00027 bool 
00028 Headers::isCommaTokenizing(Type type)
00029 {
00030    return CommaTokenizing[type+1];
00031 }
00032 
00033 bool 
00034 Headers::isCommaEncoding(Type type)
00035 {
00036    return CommaEncoding[type+1];
00037 }
00038 
00039 const Data&
00040 Headers::getHeaderName(int type)
00041 {
00042    return HeaderNames[type+1];
00043 }
00044 
00045 bool
00046 Headers::isMulti(Type type)
00047 {
00048    return Multi[type+1];
00049 }
00050 
00051 #define defineHeader(_enum, _name, _type, _reference)                                                                   \
00052 Headers::Type                                                                                                           \
00053 H_##_enum::getTypeNum() const {return Headers::_enum;}                                                                  \
00054                                                                                                                         \
00055 void H_##_enum::merge(SipMessage& target, const SipMessage& embedded)                                                   \
00056 {                                                                                                                       \
00057    if (embedded.exists(*this))                                                                                          \
00058    {                                                                                                                    \
00059       target.header(*this) = embedded.header(*this);                                                                    \
00060    }                                                                                                                    \
00061 }                                                                                                                       \
00062                                                                                                                         \
00063 H_##_enum::H_##_enum()                                                                                                  \
00064 {                                                                                                                       \
00065    Headers::CommaTokenizing[Headers::_enum+1] = bool(Type::commaHandling & ParserCategory::CommasAllowedOutputMulti);   \
00066    Headers::CommaEncoding[Headers::_enum+1] = bool(Type::commaHandling & 2);                                            \
00067    Headers::HeaderNames[Headers::_enum+1] = _name;                                                                      \
00068    Headers::Multi[Headers::_enum+1] = false;                                                                             \
00069    HeaderBase::theHeaderInstances[Headers::_enum+1] = this;                                                                             \
00070 }                                                                                                                       \
00071                                                                                                                         \
00072 _type&                                                                                                                  \
00073 H_##_enum::knownReturn(ParserContainerBase* container)                                                                  \
00074 {                                                                                                                       \
00075    return dynamic_cast<ParserContainer<_type>*>(container)->front();                                                    \
00076 }                                                                                                                       \
00077                                                                                                                         \
00078 ParserContainerBase*                                                                                                    \
00079 H_##_enum::makeContainer(HeaderFieldValueList* hfvs) const                                                              \
00080 {                                                                                                                       \
00081    return new ParserContainer<_type>(hfvs,Headers::_enum);                                                              \
00082 }                                                                                                                       \
00083                                                                                                                         \
00084 H_##_enum resip::h_##_enum
00085 
00086 #define defineMultiHeader(_enum, _name, _type, _reference)                                                                              \
00087    Headers::Type                                                                                                                        \
00088 H_##_enum##s::getTypeNum() const {return Headers::_enum;}                                                                               \
00089                                                                                                                                         \
00090 void H_##_enum##s::merge(SipMessage& target, const SipMessage& embedded)                                                                \
00091 {                                                                                                                                       \
00092    if (embedded.exists(*this))                                                                                                          \
00093    {                                                                                                                                    \
00094       target.header(*this).append(embedded.header(*this));                                                                              \
00095    }                                                                                                                                    \
00096 }                                                                                                                                       \
00097                                                                                                                                         \
00098 H_##_enum##s::H_##_enum##s()                                                                                                            \
00099 {                                                                                                                                       \
00100    Headers::CommaTokenizing[Headers::_enum+1] = bool(Type::value_type::commaHandling & ParserCategory::CommasAllowedOutputMulti);       \
00101    Headers::CommaEncoding[Headers::_enum+1] = bool(Type::value_type::commaHandling & 2);                                                \
00102    Headers::HeaderNames[Headers::_enum+1] = _name;                                                                                      \
00103    Headers::Multi[Headers::_enum+1] = true;                                                                             \
00104    HeaderBase::theHeaderInstances[Headers::_enum+1] = this;                                                                             \
00105 }                                                                                                                                       \
00106                                                                                                                                         \
00107 ParserContainer<_type>&                                                                                                                 \
00108 H_##_enum##s::knownReturn(ParserContainerBase* container)                                                                               \
00109 {                                                                                                                                       \
00110    return *dynamic_cast<ParserContainer<_type>*>(container);                                                                            \
00111 }                                                                                                                                       \
00112                                                                                                                                         \
00113 ParserContainerBase*                                                                                                    \
00114 H_##_enum##s::makeContainer(HeaderFieldValueList* hfvs) const                                                           \
00115 {                                                                                                                       \
00116    return new ParserContainer<_type>(hfvs,Headers::_enum);                                                              \
00117 }                                                                                                                       \
00118                                                                                                                                         \
00119 H_##_enum##s resip::h_##_enum##s
00120 
00121 //====================
00122 // Token
00123 //====================
00124 
00125 defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261");
00126 defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261");
00127 defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); // !dlb! defineMultiHeader
00128 defineHeader(MIMEVersion, "MIME-Version", Token, "RFC 3261");
00129 defineHeader(Priority, "Priority", Token, "RFC 3261");
00130 defineHeader(Event, "Event", Token, "RFC 3265");
00131 defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265");
00132 
00133 defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903");
00134 defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903");
00135 defineHeader(ContentId, "Content-ID", Token, "RFC 2045");
00136 
00137 defineHeader(Identity, "Identity", StringCategory, "RFC 4474");
00138 
00139 defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265");
00140 // explicitly declare to avoid h_AllowEventss, ugh
00141 H_AllowEventss resip::h_AllowEvents;
00142 
00143 defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261");
00144 defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261");
00145 defineMultiHeader(Allow, "Allow", Token, "RFC 3261");
00146 defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261");
00147 defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261");
00148 defineMultiHeader(Require, "Require", Token, "RFC 3261");
00149 defineMultiHeader(Supported, "Supported", Token, "RFC 3261");
00150 defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261");
00151 defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329");
00152 defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329");
00153 defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329");
00154 // explicitly declare to avoid h_SecurityVerifys, ugh
00155 H_SecurityVerifys resip::h_SecurityVerifies;
00156 
00157 defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841");
00158 defineMultiHeader(Reason, "Reason", Token, "RFC 3326");
00159 defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323");
00160 // explicitly declare to avoid h_Privacys
00161 H_Privacys resip::h_Privacies;
00162 
00163 defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313");
00164 defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488");
00165 defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01");
00166 defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01");
00167 
00168 //====================
00169 // Mime
00170 //====================
00171 typedef ParserContainer<Mime> Mimes;
00172 
00173 defineMultiHeader(Accept, "Accept", Mime, "RFC 3261");
00174 defineHeader(ContentType, "Content-Type", Mime, "RFC 3261");
00175 
00176 //====================
00177 // GenericUris:
00178 //====================
00179 defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474");
00180 
00181 typedef ParserContainer<GenericUri> GenericUris;
00182 defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261");
00183 defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261");
00184 defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261");
00185 
00186 //====================
00187 // NameAddr:
00188 //====================
00189 typedef ParserContainer<NameAddr> NameAddrs;
00190 
00191 defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261");
00192 defineMultiHeader(Route, "Route", NameAddr, "RFC 3261");
00193 defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261");
00194 defineHeader(From, "From", NameAddr, "RFC 3261");
00195 defineHeader(To, "To", NameAddr, "RFC 3261"); 
00196 defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261");
00197 defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515");
00198 defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892");
00199 
00200 defineMultiHeader(Path, "Path", NameAddr, "RFC 3327");
00201 defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841");
00202 defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841");
00203 defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325");
00204 // explicitly declare to avoid h_PPrefferedIdentitys
00205 H_PPreferredIdentitys resip::h_PPreferredIdentities;
00206 
00207 defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325");
00208 // explicitly declare to avoid h_PAssertedIdentitys
00209 H_PAssertedIdentitys resip::h_PAssertedIdentities;
00210 
00211 
00212 defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455");
00213 defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455");
00214 defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608");
00215 defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep?
00216 defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244");
00217 
00218 //====================
00219 // String:
00220 //====================
00221 typedef ParserContainer<StringCategory> StringCategories;
00222 
00223 defineHeader(Organization, "Organization", StringCategory, "RFC 3261");
00224 defineHeader(Server, "Server", StringCategory, "RFC 3261");
00225 defineHeader(Subject, "Subject", StringCategory, "RFC 3261");
00226 defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261");
00227 defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261");
00228 
00229 //====================
00230 // Integer:
00231 //====================
00232 
00233 // !dlb! not clear this needs to be exposed
00234 defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261");
00235 defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261");
00236 defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261");
00237 defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3262");
00238 
00239 // !dlb! this one is not quite right -- can have (comment) after field value
00240 // !rwm!  WHO CARES!!!! Comments are evil
00241 defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261");
00242 defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626");
00243 
00244 defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261");
00245 defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028");
00246 defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028");
00247 
00248 //====================
00249 // CallId:
00250 //====================
00251 defineHeader(CallID, "Call-ID", CallId, "RFC 3261");
00252 H_CallId resip::h_CallId; // code convention compatible
00253 defineHeader(Replaces, "Replaces", CallId, "RFC 3891");
00254 defineHeader(InReplyTo, "In-Reply-To", CallId, "RFC 3261");
00255 defineHeader(Join, "Join", CallId, "RFC 3911");
00256 defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538");
00257 
00258 
00259 //====================
00260 // Auth:
00261 //====================
00262 defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261");
00263 defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261");
00264 defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261");
00265 defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261");
00266 defineMultiHeader(WWWAuthenticate, "WWW-Authenticate", Auth, "RFC 3261");
00267 
00268 //====================
00269 // CSeqCategory:
00270 //====================
00271 defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261");
00272 
00273 //====================
00274 // DateCategory:
00275 //====================
00276 defineHeader(Date, "Date", DateCategory, "RFC 3261");
00277 
00278 //====================
00279 // WarningCategory:
00280 //====================
00281 defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261");
00282 
00283 //====================
00284 // RAckCategory
00285 //====================
00286 defineHeader(RAck, "RAck", RAckCategory, "RFC 3262");
00287 
00288 defineMultiHeader(Via, "Via", Via, "RFC 3261");
00289 
00290 //Enforces string encoding of extension headers
00291 Headers::Type                                                          
00292 H_RESIP_DO_NOT_USEs::getTypeNum() const {return Headers::RESIP_DO_NOT_USE;}                                                                               
00293                                                                                                                                         
00294 H_RESIP_DO_NOT_USEs::H_RESIP_DO_NOT_USEs()                                                                                                            
00295 {                                                                                                                                       
00296    Headers::CommaTokenizing[Headers::RESIP_DO_NOT_USE+1] = bool(Type::value_type::commaHandling & ParserCategory::CommasAllowedOutputMulti);       
00297    Headers::CommaEncoding[Headers::RESIP_DO_NOT_USE+1] = bool(Type::value_type::commaHandling & 2);                                                
00298    Headers::HeaderNames[Headers::RESIP_DO_NOT_USE+1] = "RESIP_DO_NOT_USE";                                                                                      
00299 }                                                                                                                                       
00300                                                                                                                                         
00301 ParserContainer<StringCategory>&                                                                                                                 
00302 H_RESIP_DO_NOT_USEs::knownReturn(ParserContainerBase* container)                                                                               
00303 {                                                                                                                                       
00304    return *dynamic_cast<ParserContainer<StringCategory>*>(container);                                                                            
00305 }                                                                                                                                       
00306                                                                                                                                         
00307 H_RESIP_DO_NOT_USEs resip::h_RESIP_DO_NOT_USEs;
00308 
00309 void H_RESIP_DO_NOT_USEs::merge(SipMessage& target, const SipMessage& embedded)
00310 {
00311 }
00312 
00313 ParserContainerBase*
00314 H_RESIP_DO_NOT_USEs::makeContainer(HeaderFieldValueList* hfvs) const
00315 {
00316    return new ParserContainer<StringCategory>(hfvs,Headers::RESIP_DO_NOT_USE);
00317 }
00318 
00319 RequestLineType resip::h_RequestLine;
00320 StatusLineType resip::h_StatusLine;
00321 
00322 Headers::Type
00323 Headers::getType(const char* name, int len)
00324 {
00325    const struct headers* p;
00326    p = HeaderHash::in_word_set(name, len);
00327    return p ? Headers::Type(p->type) : Headers::UNKNOWN;
00328 }
00329 
00330 /* ====================================================================
00331  * The Vovida Software License, Version 1.0 
00332  * 
00333  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00334  * 
00335  * Redistribution and use in source and binary forms, with or without
00336  * modification, are permitted provided that the following conditions
00337  * are met:
00338  * 
00339  * 1. Redistributions of source code must retain the above copyright
00340  *    notice, this list of conditions and the following disclaimer.
00341  * 
00342  * 2. Redistributions in binary form must reproduce the above copyright
00343  *    notice, this list of conditions and the following disclaimer in
00344  *    the documentation and/or other materials provided with the
00345  *    distribution.
00346  * 
00347  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00348  *    and "Vovida Open Communication Application Library (VOCAL)" must
00349  *    not be used to endorse or promote products derived from this
00350  *    software without prior written permission. For written
00351  *    permission, please contact vocal@vovida.org.
00352  *
00353  * 4. Products derived from this software may not be called "VOCAL", nor
00354  *    may "VOCAL" appear in their name, without prior written
00355  *    permission of Vovida Networks, Inc.
00356  * 
00357  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00358  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00359  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00360  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00361  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00362  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00363  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00364  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00365  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00366  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00367  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00368  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00369  * DAMAGE.
00370  * 
00371  * ====================================================================
00372  * 
00373  * This software consists of voluntary contributions made by Vovida
00374  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00375  * Inc.  For more information on Vovida Networks, Inc., please see
00376  * <http://www.vovida.org/>.
00377  *
00378  */