Re: XML Post and dlr-url

Alexander Malysh <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi,

attached is patch that should fix any xml related issues. Please test it.

Thanks,
Alexander Malysh



Am 27.02.2010 um 10:03 schrieb oscar cassetti:

> Any development on this?
> 
> On Mon, Feb 22, 2010 at 1:32 PM, Nikos Balkanas <[email protected]> wrote:
>> Well, this is just it. A workaround. Since solution is simple &
>> straightforward, I think the best thing is to make kannel XML fully
>> compatible.
>> 
>> BR,
>> Nikos
>> 
>> ----- Original Message -----
>> From: Konstantin Vayner
>> To: oscar cassetti ; Nikos Balkanas
>> Cc: [email protected]
>> Sent: Monday, February 22, 2010 2:55 PM
>> Subject: Re: XML Post and dlr-url
>> Hi guys,
>> Another possible workaround may be using PHP configuration (in case you're
>> using php as a server side scripting).
>> Take a look at this php.ini option:
>> http://php.net/manual/en/ini.core.php#ini.arg-separator.input
>> testcase:
>> poncha@localhost:~/www$ cat .htaccess
>> php_value arg_separator.input "&;"
>> poncha@localhost:~/www$ cat dump_request.php
>> <?php var_dump($_REQUEST); ?>
>> poncha@localhost:~/www$ lynx -source
>> 'http://localhost/~poncha/dump_request.php?foo=bar&amp;bar=baz'
>> array(3) {
>>   ["foo"]=>
>>   string(3) "bar"
>>   ["amp"]=>
>>   string(0) ""
>>   ["bar"]=>
>>   string(3) "baz"
>> }
>> Regards,
>>   Konstantin
>> On Mon, Feb 22, 2010 at 8:07 AM, Nikos Balkanas <[email protected]> wrote:
>>> 
>>> That was my suggestion, too. But verify with debugger to make sure.
>>> 
>>> Do not use the same approach for <udh>. There is no need and you should
>>> not require POST XML to be urlencoded. Just scan the value in dlr-url for
>>> &amp; and replace with '&'.
>>> 
>>> BR,
>>> Nikos
>>> ----- Original Message ----- From: "oscar cassetti"
>>> <[email protected]>
>>> To: "Nikos Balkanas" <[email protected]>
>>> Cc: <[email protected]>
>>> Sent: Monday, February 22, 2010 1:48 AM
>>> Subject: Re: XML Post and dlr-url
>>> 
>>> 
>>> Hi,
>>> 
>>> I believe the problem is in the functions static void
>>> get_x_kannel_from_xml in smsbox.c
>>> around the line 804 (source code kannel 1.4.3)
>>> 
>>> get_tag(tmp, octstr_imm("dlr-url"), dlr_url, 0, 0);
>>> O_DESTROY(tmp);
>>> 
>>> I think that that the same strategy adopted for the tag <ud> could be
>>> used also for the dlr-url tag assuming that this will be uri-encoded.
>>> 
>>> 
>>> Oscar
>>> 
>>> 
>>> 
>>> On Sun, Feb 21, 2010 at 6:35 PM, Nikos Balkanas <[email protected]>
>>> wrote:
>>>> 
>>>> Sure. Start by checking the get_tag function in smsbox.c. Verify with
>>>> debugger, since it is only my guess looking at the code.
>>>> 
>>>> BR,
>>>> Nikos
>>>> ----- Original Message ----- From: "oscar cassetti"
>>>> <[email protected]>
>>>> To: "Nikos Balkanas" <[email protected]>
>>>> Sent: Sunday, February 21, 2010 10:38 AM
>>>> Subject: Re: XML Post and dlr-url
>>>> 
>>>> 
>>>> Yes, I can use a workaround by passing only one parameter to GET query
>>>> and use a internal separator within the string to actually separate
>>>> the different parts.
>>>> 
>>>> If you can point me where the problem is (like function or source
>>>> file) I could I have a look myself.
>>>> 
>>>> Oscar
>>>> 
>>>> On Sun, Feb 21, 2010 at 2:26 AM, Nikos Balkanas <[email protected]>
>>>> wrote:
>>>>> 
>>>>> OK. Looks like a bug. I'll take a look at it when I get some time. In
>>>>> the
>>>>> meantime can you live with the illegal XML?
>>>>> 
>>>>> Nikos
>>>>> ----- Original Message ----- From: "oscar cassetti"
>>>>> <[email protected]>
>>>>> To: "Nikos Balkanas" <[email protected]>
>>>>> Cc: <[email protected]>
>>>>> Sent: Saturday, February 20, 2010 2:18 PM
>>>>> Subject: Re: XML Post and dlr-url
>>>>> 
>>>>> 
>>>>> But that's what I did in the second test. I didn't URL-escape
>>>>> anything, I just let the Perl XML writer escape & with &amp; which is
>>>>> the right thing to do.
>>>>> However when kannel parses the <dlr-url> it doesn't un-escape the &amp;
>>>>> to
>>>>> &.
>>>>> As a result the query URL used by kannel looks like this one below
>>>>> 
>>>>> 
>>>>> 2010-02-19 21:11:44 [1381] [9] DEBUG: Parsing URL
>>>>> 
>>>>> 
>>>>> `http://localhost/dump_me.php?send_history_id=13853220&amp;to_number=000000000000&amp;type=8':
>>>>> 
>>>>> which produces on my entry point this
>>>>> 
>>>>> GET =
>>>>> Array
>>>>> (
>>>>> [send_history_id] => 13853220
>>>>> [amp;to_number] => 000000000000
>>>>> [amp;type] => 8
>>>>> )
>>>>> 
>>>>> Note the amp;to_number for example. If the dlr-url was escaped
>>>>> properly this one should have just been to_number .
>>>>> 
>>>>> Finally in third and last test I produced an illegal XML by not
>>>>> escaping the & and it worked:
>>>>> 
>>>>> 
>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Parsing URL
>>>>> 
>>>>> 
>>>>> `http://localhost/dump_me.php?send_history_id=13853221&to_number=3538706323
>>>>> 46&type=8':
>>>>> 
>>>>> and on my entry point
>>>>> GET =
>>>>> Array
>>>>> (
>>>>> [send_history_id] => 13853221
>>>>> [to_number] => 000000000000
>>>>> [type] => 8
>>>>> )
>>>>> 
>>>>> 
>>>>> The issue is that I need to use an invalid XML to produced the right
>>>>> result. The problem is related to non un-escaping the <dlr-url>
>>>>> element.
>>>>> 
>>>>> Oscar
>>>>> 
>>>>> On Sat, Feb 20, 2010 at 2:09 AM, Nikos Balkanas <[email protected]>
>>>>> wrote:
>>>>>> 
>>>>>> So, in XML POST you shouldn't urlencode anything. And it will work.
>>>>>> What's
>>>>>> your issue then?
>>>>>> 
>>>>>> Nikos
>>>>>> ----- Original Message ----- From: "oscar cassetti"
>>>>>> <[email protected]>
>>>>>> To: <[email protected]>
>>>>>> Sent: Saturday, February 20, 2010 12:36 AM
>>>>>> Subject: Re: XML Post and dlr-url
>>>>>> 
>>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> I tried few things and I believe I found a bug in the way the
>>>>>> <dlr-url> is parsed.
>>>>>> (1)
>>>>>> First of all I tried to URI-escape the entire dlr-url and it didn't
>>>>>> work.
>>>>>> Basically I passed this:
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> <dlr-url>http%3A%2F%2Flocalhost%2Fdump_me.php%3Fsend_history_id%3D13853219%26to_number%3D000000000000%26t
>>>>>> ype%3D%25d</dlr-url>
>>>>>> 
>>>>>> And the same appears in the logs
>>>>>> 
>>>>>> 2010-02-19 21:03:32 [1318] [3] DEBUG: XMLParsing: tag <dlr-url> value
>>>>>> <http%3A%2F%2Flocalhost%2Fdump_me.php%3Fsend_history_id
>>>>>> 
>>>>>> When Kannel is going to parse the url it rejects it:
>>>>>> 
>>>>>> 2010-02-19 21:03:32 [1318] [3] DEBUG: Status: 400 Answer: <DLR-URL
>>>>>> field misformed, rejected>
>>>>>> 
>>>>>> In this case the message was not sent.
>>>>>> (2)
>>>>>> In a second test I didn't escape URI-escape. I let the Perl XML Writer
>>>>>> to escape the content of <dlr-url> .
>>>>>> In this case & is substituted by &amp; This can also be seen in smsbox
>>>>>> logs.
>>>>>> 
>>>>>> 2010-02-19 21:11:43 [1381] [3] DEBUG: XMLParsing: tag <dlr-url> value
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> <http://localhost/dump_me.php?send_history_id=13853220&amp;to_number=000000000000&amp;type=%d>
>>>>>> 
>>>>>> However when kannel parses the URL the &amp; is not changed back to & .
>>>>>> So the result is the following URL is used.
>>>>>> 
>>>>>> 2010-02-19 21:11:44 [1381] [9] DEBUG: Parsing URL
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> `http://localhost/dump_me.php?send_history_id=13853220&amp;to_number=000000000000&amp;type=8':
>>>>>> 
>>>>>> I wrote a simple script to catch the content of the GET when kannel
>>>>>> query the <dlr-url> and the result is
>>>>>> 
>>>>>> GET =
>>>>>> Array
>>>>>> (
>>>>>> [send_history_id] => 13853220
>>>>>> [amp;to_number] => 000000000000
>>>>>> [amp;type] => 8
>>>>>> )
>>>>>> 
>>>>>> (3)
>>>>>> Finally I tried to overwrite the <dlr-ulr> so I substituted &amp; with
>>>>>> &
>>>>>> so the request looks like this one below:
>>>>>> 
>>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> <message><submit><da><number>000000000000</number></da><oa><number>000000000000</number></oa><ud>%E2%82%ACee</ud><statusrequest><dlr-mask>31</dlr-mask><dlr-url>http://localhost/dump_me.php?send_history_id=13853221&to_number=000000000000&type=%d</dlr-url></statusrequest><!--
>>>>>> request from application to Kannel
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> --><from><username>xxxxxxx</username><password>xxxxxxx</password></from></submit></message>
>>>>>> 
>>>>>> Note that this XML is technically wrong. However this produces the
>>>>>> right result as ti can be seen from the logs:
>>>>>> 
>>>>>> 2010-02-19 21:28:17 [1381] [3] DEBUG: XMLParsing: tag <dlr-url> value
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> <http://localhost/dump_me.php?send_history_id=13853221&to_number=000000000000&type=%d>
>>>>>> 
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Parsing URL
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> `http://localhost/dump_me.php?send_history_id=13853221&to_number=3538706323
>>>>>> 46&type=8':
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Scheme: http://
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Host: localhost
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Port: 80
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Username: (null)
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Password: (null)
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Path: /dump_me.php
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Query:
>>>>>> send_history_id=13853221&to_number=353870632346&type=8
>>>>>> 2010-02-19 21:28:18 [1381] [9] DEBUG: Fragment: (null)
>>>>>> 
>>>>>> And also from my entry point I was able to get the three parameters
>>>>>> correctly
>>>>>> 
>>>>>> GET =
>>>>>> Array
>>>>>> (
>>>>>> [send_history_id] => 13853221
>>>>>> [to_number] => 000000000000
>>>>>> [type] => 8
>>>>>> )
>>>>>> 
>>>>>> In summary I believe that an incorrect XML produces the right result.
>>>>>> The problem looks to me e that the <dlr-ulr> is not escaped correctly.
>>>>>> 
>>>>>> Here some details
>>>>>> Kannel smsbox version 1.4.3
>>>>>> xml2-config --version 2.6.32
>>>>>> 
>>>>>> Any suggestion?
>>>>>> 
>>>>>> Thank you,
>>>>>> Oscar
>>>>>> 
>>>>>> On Thu, Feb 18, 2010 at 3:09 PM, Nikos Balkanas <[email protected]>
>>>>>> wrote:
>>>>>>> 
>>>>>>> Well, urlencoding is not right, still. In your URL ytou need to encode
>>>>>>> /,
>>>>>>> &
>>>>>>> and ?. Don't need to encode = or 8. But I think you want to encode
>>>>>>> &type=%d.
>>>>>>> That should be %26type=%%d
>>>>>>> 
>>>>>>> So is this working or not? What do you mean by 3 parmaters, not 2?
>>>>>>> This
>>>>>>> is
>>>>>>> the dlr-url you send in your XML.
>>>>>>> 
>>>>>>> BR,
>>>>>>> Nikos
>>>>>>> 
>>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>> 
>> 
>
smsbox_xml.patch (application/octet-stream, 18.1 KB)
diff --git a/gw/smsbox.c b/gw/smsbox.c
index 357bbc5..45f5183 100644
--- a/gw/smsbox.c
+++ b/gw/smsbox.c
@@ -63,6 +63,12 @@
 #include <signal.h>
 #include <string.h>
 
+/* libxml & xpath things */
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
 #include "gwlib/gwlib.h"
 #include "gwlib/regex.h"
 
@@ -134,7 +140,6 @@ static List *smsbox_http_requests = NULL; /* the outbound HTTP request queue */
 static Semaphore *max_pending_requests;
 
 int charset_processing (Octstr *charset, Octstr *text, int coding);
-static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip);
 
 /* for delayed HTTP answers.
  * Dict key is uuid, value is HTTPClient pointer
@@ -607,44 +612,6 @@ static void get_x_kannel_from_headers(List *headers, Octstr **from,
     }
 }
 
-static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip) {
-    long start, end;
-    int taglen;
-    Octstr *tmp;
-
-    tmp = octstr_create("<");
-    octstr_append(tmp, tag);
-    octstr_append(tmp, octstr_imm(">"));
-    taglen = octstr_len(tmp);
-
-    start = octstr_search(body, tmp, pos);
-    octstr_destroy(tmp);
-    if(start != -1) {
-	tmp = octstr_create("</");
-	octstr_append(tmp, tag);
-	octstr_append(tmp, octstr_imm(">"));
-
-	end = octstr_search(body, tmp, start);
-	octstr_destroy(tmp);
-	if(end != -1) {
-	    octstr_destroy(*value);
-	    *value = octstr_copy(body, start + taglen, end - start - taglen);
-	    if(nostrip == 0) {
-		octstr_strip_blanks(*value);
-		debug("sms", 0, "XMLParsing: tag <%s> value <%s>", octstr_get_cstr(tag),
-			octstr_get_cstr(*value));
-	    }
-	    return end + taglen + 1;
-	} else {
-	    debug("sms", 0, "XMLParsing: end tag </%s> not found", octstr_get_cstr(tag));
-	    return -1;
-	}
-    } else {
-	/* debug("sms", 0, "XMLParsing: tag <%s> not found", octstr_get_cstr(tag)); */
-	return -1;
-    }
-}
-
 /* requesttype = mt_reply or mt_push. for example, auth is only read on mt_push
  * parse body and populate fields, including replacing body for <ud> value and
  * type to text/plain */
@@ -660,222 +627,167 @@ static void get_x_kannel_from_xml(int requesttype , Octstr **type, Octstr **body
                                   int *rpi, List **tolist, Octstr **charset,
                                   Octstr **binfo, int *priority, Octstr **meta_data)
 {                                    
-
-    Octstr *text, *tmp, *tmp2;
-    long tmplong, where;
+    xmlDocPtr doc = NULL;
+    xmlXPathContextPtr xpathCtx = NULL;
+    xmlXPathObjectPtr xpathObj = NULL;
+    xmlChar *xml_string;
+    Octstr *text = NULL, *tmp = NULL;
     
-    tmp = tmp2 = text = NULL;
+    if (*body == NULL)
+        return;
 
     debug("sms", 0, "XMLParsing: XML: <%s>", octstr_get_cstr(*body));
 
-    /* auth */
-    get_tag(*body, octstr_imm("from"), &tmp, 0, 0);
-    if(tmp) {
-	if(requesttype == mt_push) {
-	    /* user */
-	    get_tag(tmp, octstr_imm("user"), user, 0, 0);
-	    get_tag(tmp, octstr_imm("username"), user, 0, 0);
-
-	    /* pass */
-	    get_tag(tmp, octstr_imm("pass"), pass, 0, 0);
-	    get_tag(tmp, octstr_imm("password"), pass, 0, 0);
-	}
+    /* ok, start parsing */
+    doc = xmlParseMemory(octstr_get_cstr(*body), octstr_len(*body));
+    if (doc == NULL) {
+        error(0, "XMLParsing: Could not parse xmldoc: <%s>", octstr_get_cstr(*body));
+        return;
+    }
+    xpathCtx = xmlXPathNewContext(doc);
+    if (xpathCtx == NULL) {
+        error(0, "XMLParsing: Could not create xpath context.");
+        xmlFreeDoc(doc);
+        return;
+    }
 
-	/* account */
-	get_tag(tmp, octstr_imm("account"), account, 0, 0);
+#define XPATH_SEARCH_OCTSTR(path, var, nostrip)                                         \
+    do {                                                                                \
+        xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);                     \
+        if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {        \
+            xml_string = xmlXPathCastToString(xpathObj);                       \
+            O_DESTROY(var);                                                             \
+            var = octstr_create((const char*) xml_string);                              \
+            if(nostrip == 0)                                                            \
+                octstr_strip_blanks(var);                                               \
+            xmlFree(xml_string);                                                        \
+        }                                                                               \
+        if (xpathObj != NULL) xmlXPathFreeObject(xpathObj);                             \
+    } while(0)
+
+#define XPATH_SEARCH_NUMBER(path, var)                                                  \
+    do {                                                                                \
+        xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);                     \
+        if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {        \
+            var = xmlXPathCastToNumber(xpathObj);                                       \
+        }                                                                               \
+        if (xpathObj != NULL) xmlXPathFreeObject(xpathObj);                             \
+    } while(0)
 
-	/* binfo */
-	get_tag(tmp, octstr_imm("binfo"), binfo, 0, 0);
+    /* auth */
+    xpathObj = xmlXPathEvalExpression(BAD_CAST "/message/submit/from", xpathCtx);
+    if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
+        xmlXPathFreeObject(xpathObj);
+        if(requesttype == mt_push) {
+            /* user */
+            XPATH_SEARCH_OCTSTR("/message/submit/from/user", *user, 0);
+            XPATH_SEARCH_OCTSTR("/message/submit/from/username", *user, 0);
+
+            /* pass */
+            XPATH_SEARCH_OCTSTR("/message/submit/from/pass", *pass, 0);
+            XPATH_SEARCH_OCTSTR("/message/submit/from/password", *pass, 0);
+        }
 
-	O_DESTROY(tmp);
-    }
+        /* account */
+        XPATH_SEARCH_OCTSTR("/message/submit/from/account", *account, 0);
 
-    get_tag(*body, octstr_imm("oa"), &tmp, 0, 0);
-    if(tmp) {
-       /* sender address */
-        get_tag(tmp, octstr_imm("number"), from, 0, 0);
-        O_DESTROY(tmp);
+        /* binfo */
+        XPATH_SEARCH_OCTSTR("/message/submit/from/binfo", *binfo, 0);
     }
 
-    if(requesttype == mt_push) {
-	/* to (da/number) Multiple tags */ 
-	*tolist = gwlist_create();
-	where = get_tag(*body, octstr_imm("da"), &tmp, 0, 0);
-	if(tmp) {
-	    get_tag(tmp, octstr_imm("number"), to, 0, 0);
-	    gwlist_append(*tolist, octstr_duplicate(*to));
-	    O_DESTROY(*to);
+    XPATH_SEARCH_OCTSTR("/message/submit/oa/number", *from, 0);
 
-	    while(tmp && where != -1) {
-		O_DESTROY(tmp);
-		where = get_tag(*body, octstr_imm("da"), &tmp, where, 0);
-		if(tmp) {
-		    get_tag(tmp, octstr_imm("number"), &tmp2, 0, 0);
-		    if(tmp2 != NULL) {
-			gwlist_append(*tolist, octstr_duplicate(tmp2));
-			O_DESTROY(tmp2);
-		    }
-		}
-	    }
-	}
+    /* to (da/number) Multiple tags */
+    xpathObj = xmlXPathEvalExpression(BAD_CAST "/message/submit/da/number/text()", xpathCtx);
+    if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
+        int i;
+
+        *tolist = gwlist_create();
+        for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
+            if (xpathObj->nodesetval->nodeTab[i]->type != XML_TEXT_NODE)
+                continue;
+            xml_string = xmlXPathCastNodeToString(xpathObj->nodesetval->nodeTab[i]);
+            tmp = octstr_create((const char*) xpathObj->nodesetval->nodeTab[i]->content);
+            xmlFree(xml_string);
+            octstr_strip_blanks(tmp);
+            gwlist_append(*tolist, tmp);
+        }
     }
+    if (xpathObj != NULL)
+        xmlXPathFreeObject(xpathObj);
 
     /* udh */
-    get_tag(*body, octstr_imm("udh"), &tmp, 0, 0);
-    if(tmp) {
-	O_DESTROY(*udh);
-	*udh = octstr_duplicate(tmp);
-	if(octstr_hex_to_binary(*udh) == -1)
-	    octstr_url_decode(*udh);
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_OCTSTR("/message/submit/udh", *udh, 0);
+    if(*udh != NULL && octstr_hex_to_binary(*udh) == -1)
+        octstr_url_decode(*udh);
 
     /* smsc */
-    get_tag(*body, octstr_imm("to"), &tmp, 0, 0);
-    if(tmp) {
-        O_DESTROY(*smsc);
-        *smsc = tmp;
-        tmp = NULL;
-    }
+    XPATH_SEARCH_OCTSTR("/message/submit/smsc", *smsc, 0);
+    if (smsc == NULL)
+        XPATH_SEARCH_OCTSTR("/message/submit/to", *smsc, 0);
 
     /* pid */
-    get_tag(*body, octstr_imm("pid"), &tmp, 0, 0);
-    if(tmp) {
-	if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
-	    *pid = tmplong;
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_NUMBER("/message/submit/pid", *pid);
 
     /* rpi */
-    get_tag(*body, octstr_imm("rpi"), &tmp, 0, 0);
-    if(tmp) {
-	if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
-	    *rpi = tmplong;
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_NUMBER("/message/submit/rpi", *rpi);
 
     /* dcs* (dcs/ *) */
-    get_tag(*body, octstr_imm("dcs"), &tmp, 0, 0);
-    if(tmp) {
-	/* mclass (dcs/mclass) */
-	get_tag(tmp, octstr_imm("mclass"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*mclass = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	/* mwi (dcs/mwi) */
-	get_tag(tmp, octstr_imm("mwi"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*mwi = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	/* coding (dcs/coding) */
-	get_tag(tmp, octstr_imm("coding"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*coding = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	/* compress (dcs/compress) */
-	get_tag(tmp, octstr_imm("compress"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*compress = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	/* alt-dcs (dcs/alt-dcs) */
-	get_tag(tmp, octstr_imm("alt-dcs"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*alt_dcs = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	O_DESTROY(tmp);
-    }
+    /* mclass (dcs/mclass) */
+    XPATH_SEARCH_NUMBER("/message/submit/dcs/mclass", *mclass);
+    /* mwi (dcs/mwi) */
+    XPATH_SEARCH_NUMBER("/message/submit/dcs/mwi", *mwi);
+    /* coding (dcs/coding) */
+    XPATH_SEARCH_NUMBER("/message/submit/dcs/coding", *coding);
+    /* compress (dcs/compress) */
+    XPATH_SEARCH_NUMBER("/message/submit/dcs/compress", *compress);
+    /* alt-dcs (dcs/alt-dcs) */
+    XPATH_SEARCH_NUMBER("/message/submit/dcs/alt-dcs", *alt_dcs);
+
 
     /* statusrequest* (statusrequest/ *) */
-    get_tag(*body, octstr_imm("statusrequest"), &tmp, 0, 0);
-    if(tmp) {
-	/* dlr-mask (statusrequest/dlr-mask) */
-	get_tag(tmp, octstr_imm("dlr-mask"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*dlr_mask = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	get_tag(tmp, octstr_imm("dlr-url"), dlr_url, 0, 0);
-	O_DESTROY(tmp);
-    }
+    /* dlr-mask (statusrequest/dlr-mask) */
+    XPATH_SEARCH_NUMBER("/message/submit/statusrequest/dlr-mask", *dlr_mask);
+    /* dlr-url */
+    XPATH_SEARCH_OCTSTR("/message/submit/statusrequest/dlr-utl", *dlr_url, 0);
 
     /* validity (vp/delay) */
-    get_tag(*body, octstr_imm("vp"), &tmp, 0, 0);
-    if(tmp) {
-	get_tag(tmp, octstr_imm("delay"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*validity = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_NUMBER("/message/submit/vp/delay", *validity);
 
     /* deferred (timing/delay) */
-    get_tag(*body, octstr_imm("timing"), &tmp, 0, 0);
-    if(tmp) {
-	get_tag(tmp, octstr_imm("delay"), &tmp2, 0, 0);
-	if(tmp2) {
-	    if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
-		*deferred = tmplong;
-	    O_DESTROY(tmp2);
-	}
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_NUMBER("/message/submit/timing/delay", *deferred);
 
     /* priority */
-    get_tag(*body, octstr_imm("priority"), &tmp, 0, 0);
-    if(tmp) {
-	if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
-	    *priority = tmplong;
-	O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_NUMBER("/message/submit/priority", *priority);
 
     /* meta_data */
-    get_tag(*body, octstr_imm("meta-data"), &tmp, 0, 0);
-    if (tmp) {
-        *meta_data = octstr_duplicate(tmp);
-        O_DESTROY(tmp);
-    }
+    XPATH_SEARCH_OCTSTR("/message/submit/meta-data", *meta_data, 0);
     
     /* charset from <?xml...encoding=?> */
-    tmp = find_charset_encoding(*body);
     O_DESTROY(*charset);
-    if(tmp) {
-	*charset = octstr_duplicate(tmp);
-	O_DESTROY(tmp);
-    } else {
+    if (doc->encoding != NULL)
+        *charset = octstr_create((const char*) doc->encoding);
+    else
 	*charset = octstr_create("UTF-8");
-    }
 
     /* text */
-    text = NULL;
-    get_tag(*body, octstr_imm("ud"), &tmp, 0, 0);
-    if(tmp) {
-	O_DESTROY(text);
-	text = octstr_duplicate(tmp);
-	if(octstr_hex_to_binary(text) == -1)
-	    octstr_url_decode(text);
-	O_DESTROY(tmp);
-    }
-
-    if(text)
-	*body = text;
-    else
-	*body = octstr_create("");
+    XPATH_SEARCH_OCTSTR("/message/submit/ud", text, 0);
+    if (text != NULL && octstr_hex_to_binary(text) == -1)
+        octstr_url_decode(text);
+
+    octstr_truncate(*body, 0);
+    if(text != NULL) {
+        octstr_append(*body, text);
+        octstr_destroy(text);
+    }
 
     O_DESTROY(*type);
     *type = octstr_create("text/plain");
+
+    if (xpathCtx != NULL)
+        xmlXPathFreeContext(xpathCtx);
+    if (doc != NULL)
+        xmlFreeDoc(doc);
 }
 
 
@@ -2692,7 +2604,7 @@ static Octstr *smsbox_sendsms_post(List *headers, Octstr *body,
     else if (to != NULL && octstr_len(to) == 0) {
 	error(0, "%s got empty <to> cgi variable", octstr_get_cstr(sendsms_url));
 	*status = HTTP_BAD_REQUEST;
-	return octstr_create("Empty receiver number not allowed, rejected");
+	ret = octstr_create("Empty receiver number not allowed, rejected");
     } 
     else {
 	if (octstr_case_compare(type,
@@ -3210,72 +3122,68 @@ static void sendsms_thread(void *arg)
     int status;
     
     for (;;) {
-    	client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body, 
-	    	    	    	     &args);
-	if (client == NULL)
-	    break;
-
-	info(0, "smsbox: Got HTTP request <%s> from <%s>",
-	    octstr_get_cstr(url), octstr_get_cstr(ip));
+        client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body, &args);
+        if (client == NULL)
+            break;
 
-    /*
-     * determine which kind of HTTP request this is any
-     * call the necessary routine for it
-     */
+        info(0, "smsbox: Got HTTP request <%s> from <%s>",
+                octstr_get_cstr(url), octstr_get_cstr(ip));
 
-    /* sendsms */
-    if (octstr_compare(url, sendsms_url) == 0)
-    {
-	/* 
-	 * decide if this is a GET or POST request and let the 
-	 * related routine handle the checking
-	 */
-	if (body == NULL)
-	    answer = smsbox_req_sendsms(args, ip, &status, client);
-	else
-	    answer = smsbox_sendsms_post(hdrs, body, ip, &status, client);
-    }
-    /* XML-RPC */
-    else if (octstr_compare(url, xmlrpc_url) == 0)
-    {
         /*
-         * XML-RPC request needs to have a POST body
+         * determine which kind of HTTP request this is any
+         * call the necessary routine for it
          */
-        if (body == NULL) {
-            answer = octstr_create("Incomplete request.");
-            status = HTTP_BAD_REQUEST;
-        } else
-            answer = smsbox_xmlrpc_post(hdrs, body, ip, &status);
-    }
-    /* sendota */
-    else if (octstr_compare(url, sendota_url) == 0)
-    {
-	if (body == NULL)
-            answer = smsbox_req_sendota(args, ip, &status, client);
-        else
-            answer = smsbox_sendota_post(hdrs, body, ip, &status, client);
-    }
-    /* add aditional URI compares here */
-    else {
-        answer = octstr_create("Unknown request.");
-        status = HTTP_NOT_FOUND;
-    }
 
-	debug("sms.http", 0, "Status: %d Answer: <%s>", status,
-          octstr_get_cstr(answer));
+        /* sendsms */
+        if (octstr_compare(url, sendsms_url) == 0) {
+            /*
+             * decide if this is a GET or POST request and let the
+             * related routine handle the checking
+             */
+            if (body == NULL)
+                answer = smsbox_req_sendsms(args, ip, &status, client);
+            else
+                answer = smsbox_sendsms_post(hdrs, body, ip, &status, client);
+        }
+        /* XML-RPC */
+        else if (octstr_compare(url, xmlrpc_url) == 0) {
+            /*
+             * XML-RPC request needs to have a POST body
+             */
+            if (body == NULL) {
+                answer = octstr_create("Incomplete request.");
+                status = HTTP_BAD_REQUEST;
+            } else
+                answer = smsbox_xmlrpc_post(hdrs, body, ip, &status);
+        }
+        /* sendota */
+        else if (octstr_compare(url, sendota_url) == 0) {
+            if (body == NULL)
+                answer = smsbox_req_sendota(args, ip, &status, client);
+            else
+                answer = smsbox_sendota_post(hdrs, body, ip, &status, client);
+        }
+        /* add aditional URI compares here */
+        else {
+            answer = octstr_create("Unknown request.");
+            status = HTTP_NOT_FOUND;
+        }
 
-	octstr_destroy(ip);
-	octstr_destroy(url);
-	http_destroy_headers(hdrs);
-	octstr_destroy(body);
-	http_destroy_cgiargs(args);
+        debug("sms.http", 0, "Status: %d Answer: <%s>", status,
+                octstr_get_cstr(answer));
 
-	if (immediate_sendsms_reply || status != HTTP_ACCEPTED)
-	  http_send_reply(client, status, sendsms_reply_hdrs, answer);
-	else {
-	  debug("sms.http", 0, "Delayed reply - wait for bearerbox");
-	}
-	octstr_destroy(answer);
+        octstr_destroy(ip);
+        octstr_destroy(url);
+        http_destroy_headers(hdrs);
+        octstr_destroy(body);
+        http_destroy_cgiargs(args);
+
+        if (immediate_sendsms_reply || status != HTTP_ACCEPTED)
+            http_send_reply(client, status, sendsms_reply_hdrs, answer);
+        else {
+            debug("sms.http", 0, "Delayed reply - wait for bearerbox");
+        }
+        octstr_destroy(answer);
     }
 
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.