< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate-users] ExtensionHeader and comma-separated addr-spec


Hi Byron

many thanks for your code example, you are right that we also need to
care about quoted commas.

but surely there must be a function in resip that does exactly this?
doesn't all multivalue headers with the NameAddr spec also need to
parse the buffer like this? For example the Contact header should
follow the same syntax.

it would be great for application developers to have access to this
general parsing function (if it exist), so that they can avoid
reimplementing low-level parsing code every time!


/alfred

Byron Campen wrote:
    Yikes! That code will blow up in your face. Let me be more explicit:

You'll need to tokenize the stuff contained in s.value(), keeping in mind to be wary of a quoted strings (since ',' can appear in a quoted string). Here's some code that should work (although keep in mind I just wrote this off the seat of my pants; testing is good)

    ParseBuffer pb(s.value());
    while(!pb.eof())
    {
        const char* start=pb.position();
        pb.skipToOneOf(",\"");
        while(!pb.eof() && *pb.position() == '\"')
        {
            // Quoted string, skip over it, and try again
            pb.skipToEndQuote('\"');
            pb.skipToOneOf(",\"");
        }

        // We should either be at a ',' or the end of the buffer
NameAddr na(pb.data(start)); // or new NameAddr, whatever it is you need.
        if(!pb.eof())
        {
            pb.skipChar(',');
        }
    }

Best regards,
Byron Campen

Hi Byron

many thanks for your advice!

I ended up using ParseBuffer as you mentioned, and managed to get the following
piece of code working:


for (StringCategories::iterator i = sc.begin(); i != sc.end(); ++i) {
            const StringCategory &s = *i;

            /* One Foo header can contain many
               nameaddr values, so we must parse it */

            ParseBuffer pb(s.value());

            for (int i=0; !pb.eof() && i<32; i++) {
                NameAddr na;
                stringstream ss;

                na.parse(pb);

                ss << na;

                printf("Foo %d: \"%s\"\n", i, ss.str().c_str());
            }
            }



/alfred

Byron Campen wrote:
Comma doesn't mean anything special in an extension header. (see RFC 3261 BNF for more on this) As an example, the following is a valid, _single-value_, extension-header:
*snip*
UnknownHeaderWithUnusualValue: ;;,,;;,;
*snip*
You'll need to parse them out yourself, and ParseBuffer will probably be the tool you'll need to tokenize based on commas.
Best regards,
Byron Campen
Hi

I am facing a problem where I need to parse multiple comma-separated
addresses from an extension header. The problem is that if there are
multiple addr-spec values in one header, the parser is not able
to split the values.

Consider the following code example:


               const ExtensionHeader h_fooHeader("P-FooHeader");

               if (msg->exists(h_fooHeader)) {

                   StringCategories &sc = msg->header(h_fooHeader);

for (StringCategories::iterator i = sc.begin(); i != sc.end(); ++i) {
                       const StringCategory &s = *i;
                       const Data foo(s.value());

                       printf("got foo-header: %s\n", foo.c_str());
                   }
              }


this code works for SIP messages like:

 P-FooHeader: <sip:foo@xxxxxxxxxxx>;param=1
 P-FooHeader: <sip:bar@xxxxxxxxxxx>;param=2

which will print out the two header entries.


But this code is not working for SIP messages like this:

P-FooHeader: <sip:foo@xxxxxxxxxxx>;param=1, <sip:baz@xxxxxxxxxxx>;param=0
 P-FooHeader: <sip:bar@xxxxxxxxxxx>;param=2


For my extension header I would like to parse and validate that the
content (Addr-Spec) is correct. For this I assume that NameAddr is the
best class to use.


How can I put the content of a StringCategory value into a new
NameAddr value, and iterate over all address fields inside the value?
I have looked at the documentation, but it does not mention this
special case. Are there any places in the code where similar stuff
is done?

Thanks in advance for any help!


/alfred

_______________________________________________
resiprocate-users mailing list
resiprocate-users@xxxxxxxxxxxxxxx
List Archive: http://list.resiprocate.org/archive/resiprocate-users/