public static SIPHeader ParseSIPHeaders(string[] headersCollection)
{
try
{
SIPHeader sipHeader = new SIPHeader();
sipHeader.MaxForwards = -1; // This allows detection of whether this header is present or not.
string lastHeader = null;
for (int lineIndex = 0; lineIndex < headersCollection.Length; lineIndex++)
{
string headerLine = headersCollection[lineIndex];
if (headerLine.IsNullOrBlank())
{
// No point processing blank headers.
continue;
}
string headerName = null;
string headerValue = null;
// If the first character of a line is whitespace it's a contiuation of the previous line.
if (headerLine.StartsWith(" "))
{
headerName = lastHeader;
headerValue = headerLine.Trim();
}
else
{
headerLine = headerLine.Trim();
int delimiterIndex = headerLine.IndexOf(SIPConstants.HEADER_DELIMITER_CHAR);
if (delimiterIndex == -1)
{
logger.Warn("Invalid SIP header, ignoring, " + headerLine + ".");
continue;
}
headerName = headerLine.Substring(0, delimiterIndex).Trim();
headerValue = headerLine.Substring(delimiterIndex + 1).Trim();
}
try
{
string headerNameLower = headerName.ToLower();
#region Via
if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_VIA.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_VIA.ToLower())
{
//sipHeader.RawVia += headerValue;
SIPViaHeader[] viaHeaders = SIPViaHeader.ParseSIPViaHeader(headerValue);
if (viaHeaders != null && viaHeaders.Length > 0)
{
foreach (SIPViaHeader viaHeader in viaHeaders)
{
sipHeader.Vias.AddBottomViaHeader(viaHeader);
}
}
}
#endregion
#region CallId
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_CALLID.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_CALLID.ToLower())
{
sipHeader.CallId = headerValue;
}
#endregion
#region CSeq
else if (headerNameLower == SIPHeaders.SIP_HEADER_CSEQ.ToLower())
{
//sipHeader.RawCSeq += headerValue;
string[] cseqFields = headerValue.Split(' ');
if (cseqFields == null || cseqFields.Length == 0)
{
logger.Warn("The " + SIPHeaders.SIP_HEADER_CSEQ + " was empty.");
}
else
{
if (!Int32.TryParse(cseqFields[0], out sipHeader.CSeq))
{
logger.Warn(SIPHeaders.SIP_HEADER_CSEQ + " did not contain a valid integer, " + headerLine + ".");
}
if (cseqFields != null && cseqFields.Length > 1)
{
sipHeader.CSeqMethod = SIPMethods.GetMethod(cseqFields[1]);
}
else
{
logger.Warn("There was no " + SIPHeaders.SIP_HEADER_CSEQ + " method, " + headerLine + ".");
}
}
}
#endregion
#region Expires
else if (headerNameLower == SIPHeaders.SIP_HEADER_EXPIRES.ToLower())
{
//sipHeader.RawExpires += headerValue;
if (!Int32.TryParse(headerValue, out sipHeader.Expires))
{
logger.Warn("The Expires value was not a valid integer, " + headerLine + ".");
}
}
#endregion
#region Min-Expires
else if (headerNameLower == SIPHeaders.SIP_HEADER_MINEXPIRES.ToLower())
{
if (!Int32.TryParse(headerValue, out sipHeader.MinExpires))
{
logger.Warn("The Min-Expires value was not a valid integer, " + headerLine + ".");
}
}
#endregion
#region Contact
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_CONTACT.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_CONTACT.ToLower())
{
List<SIPContactHeader> contacts = SIPContactHeader.ParseContactHeader(headerValue);
if(contacts != null && contacts.Count > 0)
{
sipHeader.Contact.AddRange(contacts);
}
}
#endregion
#region From
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_FROM.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_FROM.ToLower())
{
//sipHeader.RawFrom = headerValue;
sipHeader.From = SIPFromHeader.ParseFromHeader(headerValue);
}
#endregion
#region To
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_TO.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_TO.ToLower())
{
//sipHeader.RawTo = headerValue;
sipHeader.To = SIPToHeader.ParseToHeader(headerValue);
}
#endregion
#region WWWAuthenticate
else if (headerNameLower == SIPHeaders.SIP_HEADER_WWWAUTHENTICATE.ToLower())
{
//sipHeader.RawAuthentication = headerValue;
sipHeader.AuthenticationHeader = SIPAuthenticationHeader.ParseSIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, headerValue);
}
#endregion
#region Authorization
else if (headerNameLower == SIPHeaders.SIP_HEADER_AUTHORIZATION.ToLower())
{
//sipHeader.RawAuthentication = headerValue;
sipHeader.AuthenticationHeader = SIPAuthenticationHeader.ParseSIPAuthenticationHeader(SIPAuthorisationHeadersEnum.Authorize, headerValue);
}
#endregion
#region ProxyAuthentication
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXYAUTHENTICATION.ToLower())
{
//sipHeader.RawAuthentication = headerValue;
sipHeader.AuthenticationHeader = SIPAuthenticationHeader.ParseSIPAuthenticationHeader(SIPAuthorisationHeadersEnum.ProxyAuthenticate, headerValue);
}
#endregion
#region ProxyAuthorization
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXYAUTHORIZATION.ToLower())
{
sipHeader.AuthenticationHeader = SIPAuthenticationHeader.ParseSIPAuthenticationHeader(SIPAuthorisationHeadersEnum.ProxyAuthorization, headerValue);
}
#endregion
#region UserAgent
else if (headerNameLower == SIPHeaders.SIP_HEADER_USERAGENT.ToLower())
{
sipHeader.UserAgent = headerValue;
}
#endregion
#region MaxForwards
else if (headerNameLower == SIPHeaders.SIP_HEADER_MAXFORWARDS.ToLower())
{
if (!Int32.TryParse(headerValue, out sipHeader.MaxForwards))
{
logger.Warn("The " + SIPHeaders.SIP_HEADER_MAXFORWARDS + " could not be parsed as a valid integer, " + headerLine + ".");
}
}
#endregion
#region ContentLength
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_CONTENTLENGTH.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_CONTENTLENGTH.ToLower())
{
if (!Int32.TryParse(headerValue, out sipHeader.ContentLength))
{
logger.Warn("The " + SIPHeaders.SIP_HEADER_CONTENTLENGTH + " could not be parsed as a valid integer.");
}
}
#endregion
#region ContentType
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_CONTENTTYPE.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_CONTENTTYPE.ToLower())
{
sipHeader.ContentType = headerValue;
}
#endregion
#region Accept
else if (headerNameLower == SIPHeaders.SIP_HEADER_ACCEPT.ToLower())
{
sipHeader.Accept = headerValue;
}
#endregion
#region Route
else if (headerNameLower == SIPHeaders.SIP_HEADER_ROUTE.ToLower())
{
SIPRouteSet routeSet = SIPRouteSet.ParseSIPRouteSet(headerValue);
if (routeSet != null)
{
while (routeSet.Length > 0)
{
sipHeader.Routes.AddBottomRoute(routeSet.PopRoute());
}
}
}
#endregion
#region RecordRoute
else if (headerNameLower == SIPHeaders.SIP_HEADER_RECORDROUTE.ToLower())
{
SIPRouteSet recordRouteSet = SIPRouteSet.ParseSIPRouteSet(headerValue);
if (recordRouteSet != null)
{
while (recordRouteSet.Length > 0)
{
sipHeader.RecordRoutes.AddBottomRoute(recordRouteSet.PopRoute());
}
}
}
#endregion
#region Allow-Events
else if (headerNameLower == SIPHeaders.SIP_HEADER_ALLOW_EVENTS || headerNameLower == SIPHeaders.SIP_COMPACTHEADER_ALLOWEVENTS)
{
sipHeader.AllowEvents = headerValue;
}
#endregion
#region Event
else if (headerNameLower == SIPHeaders.SIP_HEADER_EVENT.ToLower() || headerNameLower == SIPHeaders.SIP_COMPACTHEADER_EVENT)
{
sipHeader.Event = headerValue;
}
#endregion
#region SubscriptionState.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SUBSCRIPTION_STATE.ToLower())
{
sipHeader.SubscriptionState = headerValue;
}
#endregion
#region Timestamp.
else if (headerNameLower == SIPHeaders.SIP_HEADER_TIMESTAMP.ToLower())
{
sipHeader.Timestamp = headerValue;
}
#endregion
#region Date.
else if (headerNameLower == SIPHeaders.SIP_HEADER_DATE.ToLower())
{
sipHeader.Date = headerValue;
}
#endregion
#region Refer-Sub.
else if (headerNameLower == SIPHeaders.SIP_HEADER_REFERSUB.ToLower())
{
if (sipHeader.ReferSub == null)
{
sipHeader.ReferSub = headerValue;
}
else
{
throw new SIPValidationException(SIPValidationFieldsEnum.ReferToHeader, "Only a single Refer-Sub header is permitted.");
}
}
#endregion
#region Refer-To.
else if (headerNameLower == SIPHeaders.SIP_HEADER_REFERTO.ToLower() ||
headerNameLower == SIPHeaders.SIP_COMPACTHEADER_REFERTO)
{
if (sipHeader.ReferTo == null)
{
sipHeader.ReferTo = headerValue;
}
else
{
throw new SIPValidationException(SIPValidationFieldsEnum.ReferToHeader, "Only a single Refer-To header is permitted.");
}
}
#endregion
#region Referred-By.
else if (headerNameLower == SIPHeaders.SIP_HEADER_REFERREDBY.ToLower())
{
sipHeader.ReferredBy = headerValue;
}
#endregion
#region Require.
else if (headerNameLower == SIPHeaders.SIP_HEADER_REQUIRE.ToLower())
{
sipHeader.Require = headerValue;
}
#endregion
#region Reason.
else if (headerNameLower == SIPHeaders.SIP_HEADER_REASON.ToLower())
{
sipHeader.Reason = headerValue;
}
#endregion
#region Proxy-ReceivedFrom.
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXY_RECEIVEDFROM.ToLower())
{
sipHeader.ProxyReceivedFrom = headerValue;
}
#endregion
#region Proxy-ReceivedOn.
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXY_RECEIVEDON.ToLower())
{
sipHeader.ProxyReceivedOn = headerValue;
}
#endregion
#region Proxy-SendFrom.
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXY_SENDFROM.ToLower())
{
sipHeader.ProxySendFrom = headerValue;
}
#endregion
#region Supported
else if (headerNameLower == SIPHeaders.SIP_COMPACTHEADER_SUPPORTED.ToLower() ||
headerNameLower == SIPHeaders.SIP_HEADER_SUPPORTED.ToLower())
{
sipHeader.Supported = headerValue;
}
#endregion
#region Authentication-Info
else if (headerNameLower == SIPHeaders.SIP_HEADER_AUTHENTICATIONINFO)
{
sipHeader.AuthenticationInfo = headerValue;
}
#endregion
#region Accept-Encoding
else if (headerNameLower == SIPHeaders.SIP_HEADER_ACCEPTENCODING)
{
sipHeader.AcceptEncoding = headerValue;
}
#endregion
#region Accept-Language
else if (headerNameLower == SIPHeaders.SIP_HEADER_ACCEPTLANGUAGE)
{
sipHeader.AcceptLanguage = headerValue;
}
#endregion
#region Alert-Info
else if (headerNameLower == SIPHeaders.SIP_HEADER_ALERTINFO)
{
sipHeader.AlertInfo = headerValue;
}
#endregion
#region Allow
else if (headerNameLower == SIPHeaders.SIP_HEADER_ALLOW)
{
sipHeader.Allow = headerValue;
}
#endregion
#region Call-Info
else if (headerNameLower == SIPHeaders.SIP_HEADER_CALLINFO)
{
sipHeader.CallInfo = headerValue;
}
#endregion
#region Content-Disposition
else if (headerNameLower == SIPHeaders.SIP_HEADER_CONTENT_DISPOSITION)
{
sipHeader.ContentDisposition = headerValue;
}
#endregion
#region Content-Encoding
else if (headerNameLower == SIPHeaders.SIP_HEADER_CONTENT_ENCODING)
{
sipHeader.ContentEncoding = headerValue;
}
#endregion
#region Content-Language
else if (headerNameLower == SIPHeaders.SIP_HEADER_CONTENT_LANGUAGE)
{
sipHeader.ContentLanguage = headerValue;
}
#endregion
#region Error-Info
else if (headerNameLower == SIPHeaders.SIP_HEADER_ERROR_INFO)
{
sipHeader.ErrorInfo = headerValue;
}
#endregion
#region In-Reply-To
else if (headerNameLower == SIPHeaders.SIP_HEADER_IN_REPLY_TO)
{
sipHeader.InReplyTo = headerValue;
}
#endregion
#region MIME-Version
else if (headerNameLower == SIPHeaders.SIP_HEADER_MIME_VERSION)
{
sipHeader.MIMEVersion = headerValue;
}
#endregion
#region Organization
else if (headerNameLower == SIPHeaders.SIP_HEADER_ORGANIZATION)
{
sipHeader.Organization = headerValue;
}
#endregion
#region Priority
else if (headerNameLower == SIPHeaders.SIP_HEADER_PRIORITY)
{
sipHeader.Priority = headerValue;
}
#endregion
#region Proxy-Require
else if (headerNameLower == SIPHeaders.SIP_HEADER_PROXY_REQUIRE)
{
sipHeader.ProxyRequire = headerValue;
}
#endregion
#region Reply-To
else if (headerNameLower == SIPHeaders.SIP_HEADER_REPLY_TO)
{
sipHeader.ReplyTo = headerValue;
}
#endregion
#region Retry-After
else if (headerNameLower == SIPHeaders.SIP_HEADER_RETRY_AFTER)
{
sipHeader.RetryAfter = headerValue;
}
#endregion
#region Subject
else if (headerNameLower == SIPHeaders.SIP_HEADER_SUBJECT)
{
sipHeader.Subject = headerValue;
}
#endregion
#region Unsupported
else if (headerNameLower == SIPHeaders.SIP_HEADER_UNSUPPORTED)
{
sipHeader.Unsupported = headerValue;
}
#endregion
#region Warning
else if (headerNameLower == SIPHeaders.SIP_HEADER_WARNING)
{
sipHeader.Warning = headerValue;
}
#endregion
#region Switchboard-CallID.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_CALLID.ToLower())
{
sipHeader.SwitchboardCallID = headerValue;
}
#endregion
#region Switchboard-To.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_TO.ToLower())
{
sipHeader.SwitchboardTo = headerValue;
}
#endregion
#region Switchboard-CallerDescription.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_CALLER_DESCRIPTION.ToLower())
{
sipHeader.SwitchboardCallerDescription = headerValue;
}
#endregion
#region Switchboard-Description.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_DESCRIPTION.ToLower())
{
sipHeader.SwitchboardDescription = headerValue;
}
#endregion
#region Switchboard-From.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_FROM.ToLower())
{
sipHeader.SwitchboardFrom = headerValue;
}
#endregion
#region Switchboard-FromContactURL.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_FROM_CONTACT_URL.ToLower())
{
sipHeader.SwitchboardFromContactURL = headerValue;
}
#endregion
#region Switchboard-Owner.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_OWNER.ToLower())
{
sipHeader.SwitchboardOwner = headerValue;
}
#endregion
#region Switchboard-Terminate.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_TERMINATE.ToLower())
{
sipHeader.SwitchboardTerminate = headerValue;
}
#endregion
#region Switchboard-Token.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_TOKEN.ToLower())
{
sipHeader.SwitchboardToken = headerValue;
}
#endregion
#region Switchboard-TokenRequest.
else if (headerNameLower == SIPHeaders.SIP_HEADER_SWITCHBOARD_TOKENREQUEST.ToLower())
{
Int32.TryParse(headerValue, out sipHeader.SwitchboardTokenRequest);
}
#endregion
#region CRM-PersonName.
else if (headerNameLower == SIPHeaders.SIP_HEADER_CRM_PERSON_NAME.ToLower())
{
sipHeader.CRMPersonName = headerValue;
}
#endregion
#region CRM-CompanyName.
else if (headerNameLower == SIPHeaders.SIP_HEADER_CRM_COMPANY_NAME.ToLower())
{
sipHeader.CRMCompanyName = headerValue;
}
#endregion
#region CRM-AvatarURL.
else if (headerNameLower == SIPHeaders.SIP_HEADER_CRM_AVATAR_URL.ToLower())
{
sipHeader.CRMAvatarURL = headerValue;
}
#endregion
else
{
sipHeader.UnknownHeaders.Add(headerLine);
}
lastHeader = headerName;
}
catch (SIPValidationException)
{
throw;
}
catch (Exception parseExcp)
{
logger.Error("Error parsing SIP header " + headerLine + ". " + parseExcp.Message);
throw new SIPValidationException(SIPValidationFieldsEnum.Headers, "Unknown error parsing Header.");
}
}
sipHeader.Validate();
return sipHeader;
}
catch (SIPValidationException)
{
throw;
}
catch (Exception excp)
{
logger.Error("Exception ParseSIPHeaders. " + excp.Message);
throw new SIPValidationException(SIPValidationFieldsEnum.Headers, "Unknown error parsing Headers.");
}
}