Commit 8adfefc2 authored by urbant's avatar urbant
Browse files

absoluteURI support

parent 17a727c5
Loading
Loading
Loading
Loading
+52 −17
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ void read_sp (Buffer & buffer, Variable* v) {

// host
#define SIPREG_HOST		"((" SIPREG_HOSTNAME ")|(" SIPREG_IP4 ")|(" SIPREG_IP6 "))"
#define SIPREG_ABSOLUTE_URI	"([" SIPCHARS_UNRESERVED "/;?:@&=+$,]|" SIPREG_ESCAPED ")+"

#define SIPCHARS_PPARAM_UNRESERVED "][/:&+$"
#define SIPREG_PPARAM		"([" SIPCHARS_PPARAM_UNRESERVED SIPCHARS_UNRESERVED "]|" SIPREG_ESCAPED ")"
@@ -128,12 +129,14 @@ void read_sp (Buffer & buffer, Variable* v) {
void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{

	static Regex reg_scheme ("^sip[s]?:", REG_ICASE);
	static Regex reg_scheme ("^[" SIPCHARS_ALFA "][" SIPCHARS_ALFANUM "+.\\-]*:", REG_ICASE);
	static Regex reg_userinfo ("^([:" SIPCHARS_UNRESERVED SIPCHARS_USER_UNRESERVED "]|" SIPREG_ESCAPED "])+@", REG_ICASE);
	static Regex reg_hostport ("^[][" SIPCHARS_ALFANUM ":.\\-]+", REG_ICASE);
	static Regex reg_absolute_uri ("^" SIPREG_ABSOLUTE_URI, REG_ICASE);
	static Regex reg_urlParams ("^;" SIPREG_PPARAM_ALLOWED, REG_ICASE);
	static Regex reg_headers ("^[?]" SIPREG_PPARAM_ALLOWED, REG_ICASE);

	const char * pszScheme;
	switch (id) {
	case id_scheme:
		reg_scheme.AssertMatch (buffer, this);
@@ -141,7 +144,10 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		break;

	case id_userInfo:
		if (reg_userinfo.Match (buffer)) {
		pszScheme = Get_scheme().GetValue();
		// user-info is not decoded in case of absoluteURI
		if ((strcasecmp(pszScheme, "sip:") == 0 || strcasecmp(pszScheme, "sips:") == 0) &&
			reg_userinfo.Match (buffer)) {
			SetHypFieldIsPresent (id,  1);
			SetHypFieldLength (id, reg_userinfo.GetMatchedLength() - 8);
		} else {
@@ -153,6 +159,8 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		if (IsPresent (id_userInfo)) {
			buffer.SetPosition(buffer.GetPosition() + 8);
		}
		pszScheme = Get_scheme().GetValue();
		if ((strcasecmp(pszScheme, "sip:") == 0 || strcasecmp(pszScheme, "sips:") == 0)) {
			if (reg_hostport.Match (buffer)) {
				SetHypFieldIsPresent (id,  1);
				SetHypFieldLength(id, reg_hostport.GetMatchedLength());
@@ -161,9 +169,20 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
			} else {
				SetHypFieldIsPresent (id,  0);
			}
		} else { // absoluteURI
			if (reg_absolute_uri.Match (buffer)) {
				SetHypFieldIsPresent (id,  1);
				SetHypFieldLength(id, reg_absolute_uri.GetMatchedLength());
			} else {
				SetHypFieldIsPresent (id,  0);
			}
		}
		break;

	case id_urlParameters:
		if(buffer.GetBitsLeft() && reg_urlParams.Match (buffer)){
		pszScheme = Get_scheme().GetValue();
		if ((strcasecmp(pszScheme, "sip:") == 0 || strcasecmp(pszScheme, "sips:") == 0) &&
			reg_urlParams.Match (buffer)){
			SetHypFieldIsPresent (id,  1);
			SetHypFieldLength(id, reg_urlParams.GetMatchedLength());
		} else {
@@ -171,7 +190,9 @@ void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
		}
		break;
	case id_headers:
		if(buffer.GetBitsLeft() && reg_headers.Match (buffer)){
		pszScheme = Get_scheme().GetValue();
		if ((strcasecmp(pszScheme, "sip:") == 0 || strcasecmp(pszScheme, "sips:") == 0) && 
			reg_headers.Match (buffer)){
			SetHypFieldIsPresent (id,  1);
			SetHypFieldLength(id, reg_headers.GetMatchedLength());
		} else {
@@ -206,15 +227,29 @@ void UserInfo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void HostPort::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_host ("^" SIPREG_HOST, REG_ICASE);
	static Regex reg_absolute_uri ("^" SIPREG_ABSOLUTE_URI, REG_ICASE);
	static Regex reg_colon ("^:");

	// absoluteURI is mapped into SipUrl.hostPort.host and requires special handling
	Variable* parent = GetParent();
	bool bRequestUri = false;
	if (parent != NULL) {
		const char * pszParName = parent->GetTypeName();
		if (strcmp(pszParName, "SipUrl") == 0) {
			SipUrl * pSipUrl = dynamic_cast<SipUrl*>(parent);
			const char * pszScheme = pSipUrl->Get_scheme().GetValue();
			bRequestUri = strcasecmp(pszScheme, "sip:") != 0 && strcasecmp(pszScheme, "sips:") != 0;
		}
	}

	Regex * pRegex;
	switch (id) {
	case id_host:
		// host is always present
		SetHypFieldIsPresent(id, 1);

		reg_host.AssertMatch(buffer, this);
		SetHypFieldLength(id, reg_host.GetMatchedLength());
		pRegex = bRequestUri ? &reg_absolute_uri : &reg_host;
		pRegex->AssertMatch (buffer, this);
		SetHypFieldLength(id, pRegex->GetMatchedLength());
		break;

	case id_portField:
@@ -377,7 +412,7 @@ void Method::Encode (Buffer& buffer) throw (EncodeError)
	const std::string & val = GetValueString();

	int i = 0;
	while (*(ppMethod[i]) && strcasecmp(ppMethod[i], val.c_str()) != 0)
	while (*(ppMethod[i]) && strcmp(ppMethod[i], val.c_str()) != 0)
		i++;

	if (*(ppMethod[i]) == 0) {
@@ -400,7 +435,7 @@ void Method::Decode (Buffer& buffer) throw (DecodeError)
	const std::string & val = reg_method.GetMatchedString();

	int i = 0;
	while (*(ppValue[i]) && strcasecmp(ppValue[i], val.c_str()) != 0)
	while (*(ppValue[i]) && strcmp(ppValue[i], val.c_str()) != 0) // case sensitive!!!
		i++;

	if (*(ppValue[i]) == 0) {