Forum Discussion

Gaelle_31283's avatar
Gaelle_31283
Icon for Nimbostratus rankNimbostratus
Oct 01, 2008

Rewriting uri

Hi,

 

 

I'm a newbie and I want to rewrite a uri.

 

 

if uri contains uid

 

then I rewrite uri

 

else I do nothing.

 

 

For example :

 

rtsp://ip?a=123&k=456&uid=toto&h=789 becomes rtsp://ip?hxs=1&uid=toto&a=123&k=456&h=789

 

 

uid can be anywhere in uri: just after ? or be last parameter or be between parameters. When rewriting uri, hxs=1&uid=toto must be immediately after ? but I have to keep other parameters. We don't know which are the other parameters.

 

 

I want to get beginning of uri to ? (I manage to do it), get uid (I manage too), and then get parameters before uid if existing (I don't manage) and get parameters after uid if existing (I don't manage either). When I get all of that I can concatenate beginning of uri+?+hxs=1&uid=toto+parameters before uid+parameters after uid.

 

 

Another solution is to deplace uid and then insert hxs=1 before it but I try to use string replace without success

 

 

Can anyone see a solution to that problem?

 

 

Thanks.

3 Replies

  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Gaelle,

     

     

    A string operation would be fastest, but I can't think of a way to handle this easily with just string commands. A regex would provide more flexibility, but cost more in CPU usage. You can use regsub to match the uid=value and replace it with nothing. Here are a few example regexes.

     

     

    If you don't know what characters the UID can contain, match any character following uid= that isn't an & or new line:

     

    uid=[^&^\n]*&?

     

     

    If you do know which characters the UID can contain, limit the character class (this example is alphanumerics only:

     

    uid=[a-zA-Z0-9]*&?

     

     

    If the uid parameter name can be mixed case, replace "uid" with:

     

     

    [uU][iI][dD]

     

     

    If you know how long the uid value can be, you can replace * with {0,100} in the above examples, where 0 is the shortest length and 100 is the longest:

     

     

    uid=[a-zA-Z0-9]{0,100}&?

     

     

     

    Of these examples, the most efficient regex would be uid=[a-zA-Z0-9]{0,100}&?

     

     

    Here are some test cases for the URI with the matches in bold:

     

     

    ?uid=test&param=value

     

    ?uid=&param=value

     

    ?param=value&uid=test&param=value

     

    ?param=value&uid=&param=value

     

    ?param=value&uid=test

     

    ?param=value&uid=

     

     

    To use the regex, you can use regsub:

     

     

    regsub $regex $source_string $replacement_string

     

     

    So this command:

     

    regsub {uid=[a-zA-Z0-9]{1,100}&?} {?param=value&uid=test&param=value} ""

     

     

    Returns:

     

     

    ?param=value&param=value

     

     

    Aaron
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Sorry, I thought you wanted to strip out the uid parameter and its value if set. I reread your first post and think you want to move uid and its value to the front of the query string and then prepend hxs=1. Here is an example which avoids regexes. Maybe someone has a more efficient method?

      
      when RULE_INIT {  
        
          Set a couple of test query strings  
         set source {a=123&k=456&uid=toto&h=789}  
         set source {uid=toto&a=123&k=456&h=789}  
         set source {a=123&k=456&h=789&uid=toto}  
        
          Split the string into a list on the delimiter &  
         log local0. "\[split \$source\ &]: [split $source &]"  
        
          Create a new query string  
         set new_query_string ""  
        
          Loop through the list and create a new string of parameters and values 
         foreach param_value_pair [split $source &] {  
        
            log local0. "\$param_value_pair: $param_value_pair"  
        
             If the current param value pair starts with uid=, then prepend it to the list of query string parameters  
            if {$param_value_pair starts_with "uid="}{  
               set new_query_string ${param_value_pair}${new_query_string}  
            } else {  
               set new_query_string ${new_query_string}&${param_value_pair}  
            }  
            log local0. "\$new_query_string: $new_query_string"  
         }  
         set new_query_string hxs=1&${new_query_string}  
        
         log local0. "\$new_query_string: $new_query_string"  
        
      }  
      

    Log output:

    Rule : [split $source &]: a=123 k=456 h=789 uid=toto

    Rule : $param_value_pair: a=123

    Rule : $new_query_string: &a=123

    Rule : $param_value_pair: k=456

    Rule : $new_query_string: &a=123&k=456

    Rule : $param_value_pair: h=789

    Rule : $new_query_string: &a=123&k=456&h=789

    Rule : $param_value_pair: uid=toto

    Rule : $new_query_string: uid=toto&a=123&k=456&h=789

    Rule : $new_query_string: hxs=1&uid=toto&a=123&k=456&h=789

    You'd want to add a check to see that the URI contains uid= before using this logic.

    Aaron