radarsat1 / liblo

liblo is an implementation of the Open Sound Control protocol for POSIX systems
GNU Lesser General Public License v2.1
190 stars 60 forks source link

path parameter in pattern matching handlers #108

Closed Krasjet closed 3 years ago

Krasjet commented 3 years ago

Hello,

I noticed that for a pattern matching handler, the current dispatcher fills the path parameter with the registered pattern (e.g. /foo*) instead of the actual path of the message (e.g. /foobar).

This makes it impossible to retrieve the actual path being called in a handler registered with a pattern matching path.

It might make sense to apply the following patch.

diff --git a/src/server.c b/src/server.c
index d0908ee..0df61ae 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1973,7 +1973,7 @@ static void dispatch_method(lo_server s, const char *path,
                    to others.
                  */
                 pptr = path;
-                if (it->path)
+                if (it->path && !it->has_pattern)
                     pptr = it->path;
                 ret = it->handler(pptr, types, msg->argv, argc, msg,
                                   it->user_data);

The new dispatcher only sends the registered path if it does not contain a pattern. In this case, we can further differentiate the behavior inside a handler according to the path of the message.

radarsat1 commented 3 years ago

Hi, just wanted to apologise for the delay, I haven't had much time for liblo lately.. I'll take a look soon! cheers.

Krasjet commented 3 years ago

No worries! Just to save you some time. Here is a minimal example:

#include <stdio.h>
#include <unistd.h>
#include <lo/lo.h>

static int handler(const char *path, const char *types, lo_arg **argv,
                   int argc, lo_message m, void* user_data)
{
  printf("path: %s\n", path);
  return 0;
}

int main(void)
{
  lo_server_thread st = lo_server_thread_new("7770", NULL);

  lo_server_thread_add_method(st, "/foo*", NULL, handler, NULL);

  lo_server_thread_start(st);

  while (1)
    usleep(1000);

  lo_server_thread_free(st);

  return 0;
}

If we send a message to /foobar,

$ oscsend localhost 7770 /foobar i 1

the printed path is

path: /foo*

With the patch, the printed message would be the actual path been sent:

path: /foobar
radarsat1 commented 3 years ago

Merged #109