Browse code

textops(k): new function - msg_apply_changes()

- apply changes done to SIP request content (e.g., via subst(),
append_hf(), remove_hf(), etc.)
- after using this function, the content of SIP message buffer is
updated and the initially recevied content is lost
- function can be used in request route blocks
- be careful when used since:
- it changes the way you're used so far
- not much tested with various modules

Daniel-Constantin Mierla authored on 10/09/2009 14:22:08
Showing 3 changed files
... ...
@@ -19,65 +19,65 @@ Daniel-Constantin Mierla
19 19
 
20 20
    Copyright � 2003 FhG FOKUS
21 21
    Revision History
22
-   Revision $Revision$ $Date: 2008-08-11 08:46:44 +0200
23
-                              (Mo, 11 Aug 2008) $
24
-     __________________________________________________________
22
+   Revision $Revision$ $Date$
23
+     __________________________________________________________________
25 24
 
26 25
    Table of Contents
27 26
 
28 27
    1. Admin Guide
29 28
 
30
-        1.1. Overview
31
-
32
-              1.1.1. Known Limitations
33
-
34
-        1.2. Dependencies
35
-
36
-              1.2.1. Kamailio Modules
37
-              1.2.2. External Libraries or Applications
38
-
39
-        1.3. Exported Functions
40
-
41
-              1.3.1. search(re)
42
-              1.3.2. search_body(re)
43
-              1.3.3. search_append(re, txt)
44
-              1.3.4. search_append_body(re, txt)
45
-              1.3.5. replace(re, txt)
46
-              1.3.6. replace_body(re, txt)
47
-              1.3.7. replace_all(re, txt)
48
-              1.3.8. replace_body_all(re, txt)
49
-              1.3.9. replace_body_atonce(re, txt)
50
-              1.3.10. subst('/re/repl/flags')
51
-              1.3.11. subst_uri('/re/repl/flags')
52
-              1.3.12. subst_user('/re/repl/flags')
53
-              1.3.13. subst_body('/re/repl/flags')
54
-              1.3.14. set_body(txt,content_type)
55
-              1.3.15. set_reply_body(txt,content_type)
56
-              1.3.16. filter_body(content_type)
57
-              1.3.17. append_to_reply(txt)
58
-              1.3.18. append_hf(txt)
59
-              1.3.19. append_hf(txt, hdr)
60
-              1.3.20. insert_hf(txt)
61
-              1.3.21. insert_hf(txt, hdr)
62
-              1.3.22. append_urihf(prefix, suffix)
63
-              1.3.23. is_present_hf(hf_name)
64
-              1.3.24. is_present_hf_re(hf_name_re)
65
-              1.3.25. append_time()
66
-              1.3.26. is_method(name)
67
-              1.3.27. remove_hf(hname)
68
-              1.3.28. remove_hf_re(re)
69
-              1.3.29. has_body(), has_body(mime)
70
-              1.3.30. is_privacy(privacy_type)
71
-              1.3.31. cmp_str(str1, str2)
72
-              1.3.32. cmp_istr(str1, str2)
73
-
74
-        1.4. Known Limitations
29
+        1. Overview
30
+
31
+              1.1. Known Limitations
32
+
33
+        2. Dependencies
34
+
35
+              2.1. Kamailio Modules
36
+              2.2. External Libraries or Applications
37
+
38
+        3. Exported Functions
39
+
40
+              3.1. search(re)
41
+              3.2. search_body(re)
42
+              3.3. search_append(re, txt)
43
+              3.4. search_append_body(re, txt)
44
+              3.5. replace(re, txt)
45
+              3.6. replace_body(re, txt)
46
+              3.7. replace_all(re, txt)
47
+              3.8. replace_body_all(re, txt)
48
+              3.9. replace_body_atonce(re, txt)
49
+              3.10. subst('/re/repl/flags')
50
+              3.11. subst_uri('/re/repl/flags')
51
+              3.12. subst_user('/re/repl/flags')
52
+              3.13. subst_body('/re/repl/flags')
53
+              3.14. set_body(txt,content_type)
54
+              3.15. set_reply_body(txt,content_type)
55
+              3.16. filter_body(content_type)
56
+              3.17. append_to_reply(txt)
57
+              3.18. append_hf(txt)
58
+              3.19. append_hf(txt, hdr)
59
+              3.20. insert_hf(txt)
60
+              3.21. insert_hf(txt, hdr)
61
+              3.22. append_urihf(prefix, suffix)
62
+              3.23. is_present_hf(hf_name)
63
+              3.24. is_present_hf_re(hf_name_re)
64
+              3.25. append_time()
65
+              3.26. is_method(name)
66
+              3.27. remove_hf(hname)
67
+              3.28. remove_hf_re(re)
68
+              3.29. has_body(), has_body(mime)
69
+              3.30. is_privacy(privacy_type)
70
+              3.31. cmp_str(str1, str2)
71
+              3.32. cmp_istr(str1, str2)
72
+              3.33. msg_apply_changes()
73
+
74
+        4. Known Limitations
75 75
 
76 76
    2. Developer Guide
77 77
 
78
-        2.1. Functions
78
+        1. Functions
79 79
 
80
-              2.1.1. load_textops(*import_structure)
80
+              1.1. load_textops(*import_structure)
81 81
 
82 82
    List of Examples
83 83
 
... ...
@@ -113,42 +113,130 @@ Daniel-Constantin Mierla
113 113
    1.30. is_privacy usage
114 114
    1.31. cmp_str usage
115 115
    1.32. cmp_str usage
116
+   1.33. msg_apply_changes() usage
116 117
 
117 118
 Chapter 1. Admin Guide
118 119
 
119
-1.1. Overview
120
-
121
-   The module implements text based operations over the SIP
122
-   message processed by Kamailio. SIP is a text based protocol and
123
-   the module provides a large set of very useful functions to
124
-   manipulate the message at text level, e.g., regular expression
125
-   search and replace, Perl-like substitutions, checks for method
126
-   type, header presence, insert of new header and date, etc.
127
-
128
-1.1.1. Known Limitations
120
+   Table of Contents
129 121
 
130
-   search ignores folded lines. For example,
131
-   search("(From|f):.*@foo.bar") doesn't match the following From
132
-   header field:
122
+   1. Overview
123
+
124
+        1.1. Known Limitations
125
+
126
+   2. Dependencies
127
+
128
+        2.1. Kamailio Modules
129
+        2.2. External Libraries or Applications
130
+
131
+   3. Exported Functions
132
+
133
+        3.1. search(re)
134
+        3.2. search_body(re)
135
+        3.3. search_append(re, txt)
136
+        3.4. search_append_body(re, txt)
137
+        3.5. replace(re, txt)
138
+        3.6. replace_body(re, txt)
139
+        3.7. replace_all(re, txt)
140
+        3.8. replace_body_all(re, txt)
141
+        3.9. replace_body_atonce(re, txt)
142
+        3.10. subst('/re/repl/flags')
143
+        3.11. subst_uri('/re/repl/flags')
144
+        3.12. subst_user('/re/repl/flags')
145
+        3.13. subst_body('/re/repl/flags')
146
+        3.14. set_body(txt,content_type)
147
+        3.15. set_reply_body(txt,content_type)
148
+        3.16. filter_body(content_type)
149
+        3.17. append_to_reply(txt)
150
+        3.18. append_hf(txt)
151
+        3.19. append_hf(txt, hdr)
152
+        3.20. insert_hf(txt)
153
+        3.21. insert_hf(txt, hdr)
154
+        3.22. append_urihf(prefix, suffix)
155
+        3.23. is_present_hf(hf_name)
156
+        3.24. is_present_hf_re(hf_name_re)
157
+        3.25. append_time()
158
+        3.26. is_method(name)
159
+        3.27. remove_hf(hname)
160
+        3.28. remove_hf_re(re)
161
+        3.29. has_body(), has_body(mime)
162
+        3.30. is_privacy(privacy_type)
163
+        3.31. cmp_str(str1, str2)
164
+        3.32. cmp_istr(str1, str2)
165
+        3.33. msg_apply_changes()
166
+
167
+   4. Known Limitations
168
+
169
+1. Overview
170
+
171
+   1.1. Known Limitations
172
+
173
+   The module implements text based operations over the SIP message
174
+   processed by Kamailio. SIP is a text based protocol and the module
175
+   provides a large set of very useful functions to manipulate the message
176
+   at text level, e.g., regular expression search and replace, Perl-like
177
+   substitutions, checks for method type, header presence, insert of new
178
+   header and date, etc.
179
+
180
+1.1. Known Limitations
181
+
182
+   search ignores folded lines. For example, search("(From|f):.*@foo.bar")
183
+   doesn't match the following From header field:
133 184
 From: medabeda
134 185
  <sip:medameda@foo.bar>;tag=1234
135 186
 
136
-1.2. Dependencies
187
+2. Dependencies
137 188
 
138
-1.2.1. Kamailio Modules
189
+   2.1. Kamailio Modules
190
+   2.2. External Libraries or Applications
191
+
192
+2.1. Kamailio Modules
139 193
 
140 194
    The following modules must be loaded before this module:
141 195
      * No dependencies on other Kamailio modules.
142 196
 
143
-1.2.2. External Libraries or Applications
197
+2.2. External Libraries or Applications
144 198
 
145
-   The following libraries or applications must be installed
146
-   before running Kamailio with this module loaded:
199
+   The following libraries or applications must be installed before
200
+   running Kamailio with this module loaded:
147 201
      * None.
148 202
 
149
-1.3. Exported Functions
150
-
151
-1.3.1.  search(re)
203
+3. Exported Functions
204
+
205
+   3.1. search(re)
206
+   3.2. search_body(re)
207
+   3.3. search_append(re, txt)
208
+   3.4. search_append_body(re, txt)
209
+   3.5. replace(re, txt)
210
+   3.6. replace_body(re, txt)
211
+   3.7. replace_all(re, txt)
212
+   3.8. replace_body_all(re, txt)
213
+   3.9. replace_body_atonce(re, txt)
214
+   3.10. subst('/re/repl/flags')
215
+   3.11. subst_uri('/re/repl/flags')
216
+   3.12. subst_user('/re/repl/flags')
217
+   3.13. subst_body('/re/repl/flags')
218
+   3.14. set_body(txt,content_type)
219
+   3.15. set_reply_body(txt,content_type)
220
+   3.16. filter_body(content_type)
221
+   3.17. append_to_reply(txt)
222
+   3.18. append_hf(txt)
223
+   3.19. append_hf(txt, hdr)
224
+   3.20. insert_hf(txt)
225
+   3.21. insert_hf(txt, hdr)
226
+   3.22. append_urihf(prefix, suffix)
227
+   3.23. is_present_hf(hf_name)
228
+   3.24. is_present_hf_re(hf_name_re)
229
+   3.25. append_time()
230
+   3.26. is_method(name)
231
+   3.27. remove_hf(hname)
232
+   3.28. remove_hf_re(re)
233
+   3.29. has_body(), has_body(mime)
234
+   3.30. is_privacy(privacy_type)
235
+   3.31. cmp_str(str1, str2)
236
+   3.32. cmp_istr(str1, str2)
237
+   3.33. msg_apply_changes()
238
+
239
+3.1. search(re)
152 240
 
153 241
    Searches for the re in the message.
154 242
 
... ...
@@ -163,7 +251,7 @@ From: medabeda
163 251
 if ( search("[Ss][Ii][Pp]") ) { /*....*/ };
164 252
 ...
165 253
 
166
-1.3.2.  search_body(re)
254
+3.2. search_body(re)
167 255
 
168 256
    Searches for the re in the body of the message.
169 257
 
... ...
@@ -178,7 +266,7 @@ if ( search("[Ss][Ii][Pp]") ) { /*....*/ };
178 266
 if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ };
179 267
 ...
180 268
 
181
-1.3.3.  search_append(re, txt)
269
+3.3. search_append(re, txt)
182 270
 
183 271
    Searches for the first match of re and appends txt after it.
184 272
 
... ...
@@ -194,10 +282,10 @@ if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ };
194 282
 search_append("[Oo]pen[Ss]er", " SIP Proxy");
195 283
 ...
196 284
 
197
-1.3.4.  search_append_body(re, txt)
285
+3.4. search_append_body(re, txt)
198 286
 
199
-   Searches for the first match of re in the body of the message
200
-   and appends txt after it.
287
+   Searches for the first match of re in the body of the message and
288
+   appends txt after it.
201 289
 
202 290
    Meaning of the parameters is as follows:
203 291
      * re - Regular expression.
... ...
@@ -211,7 +299,7 @@ search_append("[Oo]pen[Ss]er", " SIP Proxy");
211 299
 search_append_body("[Oo]pen[Ss]er", " SIP Proxy");
212 300
 ...
213 301
 
214
-1.3.5.  replace(re, txt)
302
+3.5. replace(re, txt)
215 303
 
216 304
    Replaces the first occurrence of re with txt.
217 305
 
... ...
@@ -227,10 +315,10 @@ search_append_body("[Oo]pen[Ss]er", " SIP Proxy");
227 315
 replace("openser", "Kamailio SIP Proxy");
228 316
 ...
229 317
 
230
-1.3.6.  replace_body(re, txt)
318
+3.6. replace_body(re, txt)
231 319
 
232
-   Replaces the first occurrence of re in the body of the message
233
-   with txt.
320
+   Replaces the first occurrence of re in the body of the message with
321
+   txt.
234 322
 
235 323
    Meaning of the parameters is as follows:
236 324
      * re - Regular expression.
... ...
@@ -244,7 +332,7 @@ replace("openser", "Kamailio SIP Proxy");
244 332
 replace_body("openser", "Kamailio SIP Proxy");
245 333
 ...
246 334
 
247
-1.3.7.  replace_all(re, txt)
335
+3.7. replace_all(re, txt)
248 336
 
249 337
    Replaces all occurrence of re with txt.
250 338
 
... ...
@@ -260,10 +348,10 @@ replace_body("openser", "Kamailio SIP Proxy");
260 348
 replace_all("openser", "Kamailio SIP Proxy");
261 349
 ...
262 350
 
263
-1.3.8.  replace_body_all(re, txt)
351
+3.8. replace_body_all(re, txt)
264 352
 
265
-   Replaces all occurrence of re in the body of the message with
266
-   txt. Matching is done on a per-line basis.
353
+   Replaces all occurrence of re in the body of the message with txt.
354
+   Matching is done on a per-line basis.
267 355
 
268 356
    Meaning of the parameters is as follows:
269 357
      * re - Regular expression.
... ...
@@ -277,10 +365,10 @@ replace_all("openser", "Kamailio SIP Proxy");
277 365
 replace_body_all("openser", "Kamailio SIP Proxy");
278 366
 ...
279 367
 
280
-1.3.9.  replace_body_atonce(re, txt)
368
+3.9. replace_body_atonce(re, txt)
281 369
 
282
-   Replaces all occurrence of re in the body of the message with
283
-   txt. Matching is done over the whole body.
370
+   Replaces all occurrence of re in the body of the message with txt.
371
+   Matching is done over the whole body.
284 372
 
285 373
    Meaning of the parameters is as follows:
286 374
      * re - Regular expression.
... ...
@@ -296,17 +384,16 @@ if(has_body() && replace_body_atonce("^.+$", ""))
296 384
         remove_hf("Content-Type");
297 385
 ...
298 386
 
299
-1.3.10.  subst('/re/repl/flags')
387
+3.10. subst('/re/repl/flags')
300 388
 
301 389
    Replaces re with repl (sed or perl like).
302 390
 
303 391
    Meaning of the parameters is as follows:
304
-     * '/re/repl/flags' - sed like regular expression. flags can
305
-       be a combination of i (case insensitive), g (global) or s
306
-       (match newline don't treat it as end of line).
392
+     * '/re/repl/flags' - sed like regular expression. flags can be a
393
+       combination of i (case insensitive), g (global) or s (match newline
394
+       don't treat it as end of line).
307 395
        're' - is regular expresion
308
-       'repl' - is replacement string - may contain
309
-       pseudo-varibales
396
+       'repl' - is replacement string - may contain pseudo-varibales
310 397
        'flags' - substitution flags (i - ignore case, g - global)
311 398
 
312 399
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
... ...
@@ -317,25 +404,23 @@ if(has_body() && replace_body_atonce("^.+$", ""))
317 404
 # replace the uri in to: with the message uri (just an example)
318 405
 if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1\u\2/ig') ) {};
319 406
 
320
-# replace the uri in to: with the value of avp sip_address (just an exam
321
-ple)
322
-if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\
323
-2/ig') ) {};
407
+# replace the uri in to: with the value of avp sip_address (just an example)
408
+if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\2/ig') )
409
+ {};
324 410
 
325 411
 ...
326 412
 
327
-1.3.11.  subst_uri('/re/repl/flags')
413
+3.11. subst_uri('/re/repl/flags')
328 414
 
329
-   Runs the re substitution on the message uri (like subst but
330
-   works only on the uri)
415
+   Runs the re substitution on the message uri (like subst but works only
416
+   on the uri)
331 417
 
332 418
    Meaning of the parameters is as follows:
333
-     * '/re/repl/flags' - sed like regular expression. flags can
334
-       be a combination of i (case insensitive), g (global) or s
335
-       (match newline don't treat it as end of line).
419
+     * '/re/repl/flags' - sed like regular expression. flags can be a
420
+       combination of i (case insensitive), g (global) or s (match newline
421
+       don't treat it as end of line).
336 422
        're' - is regular expresion
337
-       'repl' - is replacement string - may contain
338
-       pseudo-varibales
423
+       'repl' - is replacement string - may contain pseudo-varibales
339 424
        'flags' - substitution flags (i - ignore case, g - global)
340 425
 
341 426
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
... ...
@@ -347,26 +432,23 @@ if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\
347 432
 # as a parameter: orig_uri (just an example)
348 433
 if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:3463\1@\2;orig_uri=\0/i')){$
349 434
 
350
-# adds the avp 'uri_prefix' as prefix to numeric uris, and save the orig
351
-inal
435
+# adds the avp 'uri_prefix' as prefix to numeric uris, and save the original
352 436
 # uri (\0 match) as a parameter: orig_uri (just an example)
353
-if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\
354
-0/i')){$
437
+if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\0/i')){$
355 438
 
356 439
 ...
357 440
 
358
-1.3.12.  subst_user('/re/repl/flags')
441
+3.12. subst_user('/re/repl/flags')
359 442
 
360
-   Runs the re substitution on the message uri (like subst_uri but
361
-   works only on the user portion of the uri)
443
+   Runs the re substitution on the message uri (like subst_uri but works
444
+   only on the user portion of the uri)
362 445
 
363 446
    Meaning of the parameters is as follows:
364
-     * '/re/repl/flags' - sed like regular expression. flags can
365
-       be a combination of i (case insensitive), g (global) or s
366
-       (match newline don't treat it as end of line).
447
+     * '/re/repl/flags' - sed like regular expression. flags can be a
448
+       combination of i (case insensitive), g (global) or s (match newline
449
+       don't treat it as end of line).
367 450
        're' - is regular expresion
368
-       'repl' - is replacement string - may contain
369
-       pseudo-varibales
451
+       'repl' - is replacement string - may contain pseudo-varibales
370 452
        'flags' - substitution flags (i - ignore case, g - global)
371 453
 
372 454
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
... ...
@@ -383,18 +465,16 @@ if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$
383 465
 
384 466
 ...
385 467
 
386
-1.3.13.  subst_body('/re/repl/flags')
468
+3.13. subst_body('/re/repl/flags')
387 469
 
388
-   Replaces re with repl (sed or perl like) in the body of the
389
-   message.
470
+   Replaces re with repl (sed or perl like) in the body of the message.
390 471
 
391 472
    Meaning of the parameters is as follows:
392
-     * '/re/repl/flags' - sed like regular expression. flags can
393
-       be a combination of i (case insensitive), g (global) or s
394
-       (match newline don't treat it as end of line).
473
+     * '/re/repl/flags' - sed like regular expression. flags can be a
474
+       combination of i (case insensitive), g (global) or s (match newline
475
+       don't treat it as end of line).
395 476
        're' - is regular expresion
396
-       'repl' - is replacement string - may contain
397
-       pseudo-varibales
477
+       'repl' - is replacement string - may contain pseudo-varibales
398 478
        'flags' - substitution flags (i - ignore case, g - global)
399 479
 
400 480
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
... ...
@@ -406,7 +486,7 @@ if ( subst_body('/^o=(.*) /o=$fU /') ) {};
406 486
 
407 487
 ...
408 488
 
409
-1.3.14.  set_body(txt,content_type)
489
+3.14. set_body(txt,content_type)
410 490
 
411 491
    Set body to a SIP message.
412 492
 
... ...
@@ -423,7 +503,7 @@ if ( subst_body('/^o=(.*) /o=$fU /') ) {};
423 503
 set_body("test", "text/plain");
424 504
 ...
425 505
 
426
-1.3.15.  set_reply_body(txt,content_type)
506
+3.15. set_reply_body(txt,content_type)
427 507
 
428 508
    Set body to a SIP reply to be generated by Kamailio.
429 509
 
... ...
@@ -440,10 +520,10 @@ set_body("test", "text/plain");
440 520
 set_reply_body("test", "text/plain");
441 521
 ...
442 522
 
443
-1.3.16.  filter_body(content_type)
523
+3.16. filter_body(content_type)
444 524
 
445
-   Filters multipart body by leaving out all other body parts
446
-   except the first body part of given type.
525
+   Filters multipart/mixed body by leaving out all other body parts except
526
+   the first body part of given type.
447 527
 
448 528
    Meaning of the parameters is as follows:
449 529
      * content_type - Content type to be left in the body.
... ...
@@ -463,7 +543,7 @@ if (has_body("multipart/mixed")) {
463 543
 }
464 544
 ...
465 545
 
466
-1.3.17.  append_to_reply(txt)
546
+3.17. append_to_reply(txt)
467 547
 
468 548
    Append txt as header to the reply.
469 549
 
... ...
@@ -479,7 +559,7 @@ append_to_reply("Foo: bar\r\n");
479 559
 append_to_reply("Foo: $rm at $Ts\r\n");
480 560
 ...
481 561
 
482
-1.3.18.  append_hf(txt)
562
+3.18. append_hf(txt)
483 563
 
484 564
    Appends 'txt' as header after the last header field.
485 565
 
... ...
@@ -487,11 +567,11 @@ append_to_reply("Foo: $rm at $Ts\r\n");
487 567
      * txt - Header field to be appended. The value can contain
488 568
        pseudo-variables which will be replaced at run time.
489 569
 
490
-   Note: Headers which are added in main route cannot be removed
491
-   in further routes (e.g. failure routes). So, the idea is not to
492
-   add there any headers that you might want to remove later. To
493
-   add headers temporarely use the branch route because the
494
-   changes you do there are per-branch.
570
+   Note: Headers which are added in main route cannot be removed in
571
+   further routes (e.g. failure routes). So, the idea is not to add there
572
+   any headers that you might want to remove later. To add headers
573
+   temporarely use the branch route because the changes you do there are
574
+   per-branch.
495 575
 
496 576
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
497 577
    FAILURE_ROUTE, BRANCH_ROUTE.
... ...
@@ -502,7 +582,7 @@ append_hf("P-hint: VOICEMAIL\r\n");
502 582
 append_hf("From-username: $fU\r\n");
503 583
 ...
504 584
 
505
-1.3.19.  append_hf(txt, hdr)
585
+3.19. append_hf(txt, hdr)
506 586
 
507 587
    Appends 'txt' as header after first 'hdr' header field.
508 588
 
... ...
@@ -520,7 +600,7 @@ append_hf("P-hint: VOICEMAIL\r\n", "Call-ID");
520 600
 append_hf("From-username: $fU\r\n", "Call-ID");
521 601
 ...
522 602
 
523
-1.3.20.  insert_hf(txt)
603
+3.20. insert_hf(txt)
524 604
 
525 605
    Inserts 'txt' as header before the first header field.
526 606
 
... ...
@@ -537,7 +617,7 @@ insert_hf("P-hint: VOICEMAIL\r\n");
537 617
 insert_hf("To-username: $tU\r\n");
538 618
 ...
539 619
 
540
-1.3.21.  insert_hf(txt, hdr)
620
+3.21. insert_hf(txt, hdr)
541 621
 
542 622
    Inserts 'txt' as header before first 'hdr' header field.
543 623
 
... ...
@@ -555,7 +635,7 @@ insert_hf("P-hint: VOICEMAIL\r\n", "Call-ID");
555 635
 insert_hf("To-username: $tU\r\n", "Call-ID");
556 636
 ...
557 637
 
558
-1.3.22.  append_urihf(prefix, suffix)
638
+3.22. append_urihf(prefix, suffix)
559 639
 
560 640
    Append header field name with original Request-URI in middle.
561 641
 
... ...
@@ -571,14 +651,14 @@ insert_hf("To-username: $tU\r\n", "Call-ID");
571 651
 append_urihf("CC-Diversion: ", "\r\n");
572 652
 ...
573 653
 
574
-1.3.23.  is_present_hf(hf_name)
654
+3.23. is_present_hf(hf_name)
575 655
 
576 656
    Return true if a header field is present in message.
577 657
 
578 658
 Note
579 659
 
580
-   The function is also able to distinguish the compact names. For
581
-   exmaple "From" will match with "f"
660
+   The function is also able to distinguish the compact names. For exmaple
661
+   "From" will match with "f"
582 662
 
583 663
    Meaning of the parameters is as follows:
584 664
      * hf_name - Header field name.(long or compact form)
... ...
@@ -591,10 +671,10 @@ Note
591 671
 if (is_present_hf("From")) log(1, "From HF Present");
592 672
 ...
593 673
 
594
-1.3.24.  is_present_hf_re(hf_name_re)
674
+3.24. is_present_hf_re(hf_name_re)
595 675
 
596
-   Return true if a header field whose name matches regular
597
-   expression 'hf_name_re' is present in message.
676
+   Return true if a header field whose name matches regular expression
677
+   'hf_name_re' is present in message.
598 678
 
599 679
    Meaning of the parameters is as follows:
600 680
      * hf_name_re - Regular expression to match header field name.
... ...
@@ -604,16 +684,15 @@ if (is_present_hf("From")) log(1, "From HF Present");
604 684
 
605 685
    Example 1.24. is_present_hf_re usage
606 686
 ...
607
-if (is_present_hf_re("^P-")) log(1, "There are headers starting with P-\
608
-n");
687
+if (is_present_hf_re("^P-")) log(1, "There are headers starting with P-\n");
609 688
 ...
610 689
 
611
-1.3.25.  append_time()
690
+3.25. append_time()
612 691
 
613
-   Adds a time header to the reply of the request. You must use it
614
-   before functions that are likely to send a reply, e.g., save()
615
-   from 'registrar' module. Header format is: "Date: %a, %d %b %Y
616
-   %H:%M:%S GMT", with the legend:
692
+   Adds a time header to the reply of the request. You must use it before
693
+   functions that are likely to send a reply, e.g., save() from
694
+   'registrar' module. Header format is: "Date: %a, %d %b %Y %H:%M:%S
695
+   GMT", with the legend:
617 696
      * %a abbreviated week of day name (locale)
618 697
      * %d day of month as decimal number
619 698
      * %b abbreviated month name (locale)
... ...
@@ -632,24 +711,24 @@ n");
632 711
 append_time();
633 712
 ...
634 713
 
635
-1.3.26.  is_method(name)
714
+3.26. is_method(name)
636 715
 
637
-   Check if the method of the message matches the name. If name is
638
-   a known method (invite, cancel, ack, bye, options, info,
639
-   update, register, message, subscribe, notify, refer, prack),
640
-   the function performs method ID testing (integer comparison)
641
-   instead of ignore case string comparison.
716
+   Check if the method of the message matches the name. If name is a known
717
+   method (invite, cancel, ack, bye, options, info, update, register,
718
+   message, subscribe, notify, refer, prack), the function performs method
719
+   ID testing (integer comparison) instead of ignore case string
720
+   comparison.
642 721
 
643 722
    The 'name' can be a list of methods in the form of
644
-   'method1|method2|...'. In this case, the function returns true
645
-   if the SIP message's method is one from the list. IMPORTANT
646
-   NOTE: in the list must be only methods defined in Kamailio with
647
-   ID (invite, cancel, ack, bye, options, info, update, register,
648
-   message, subscribe, notify, refer, prack, publish; for more
649
-   see: http://www.iana.org/assignments/sip-parameters).
723
+   'method1|method2|...'. In this case, the function returns true if the
724
+   SIP message's method is one from the list. IMPORTANT NOTE: in the list
725
+   must be only methods defined in Kamailio with ID (invite, cancel, ack,
726
+   bye, options, info, update, register, message, subscribe, notify,
727
+   refer, prack, publish; for more see:
728
+   http://www.iana.org/assignments/sip-parameters).
650 729
 
651
-   If used for replies, the function tests the value of method
652
-   field from CSeq header.
730
+   If used for replies, the function tests the value of method field from
731
+   CSeq header.
653 732
 
654 733
    Meaning of the parameters is as follows:
655 734
      * name - SIP method name
... ...
@@ -669,7 +748,7 @@ if(is_method("OPTION|UPDATE"))
669 748
 }
670 749
 ...
671 750
 
672
-1.3.27.  remove_hf(hname)
751
+3.27. remove_hf(hname)
673 752
 
674 753
    Remove from message all headers with name "hname"
675 754
 
... ...
@@ -689,16 +768,15 @@ if(remove_hf("User-Agent"))
689 768
 }
690 769
 ...
691 770
 
692
-1.3.28.  remove_hf_re(re)
771
+3.28. remove_hf_re(re)
693 772
 
694
-   Remove from message all headers with name matching regular
695
-   expression "re"
773
+   Remove from message all headers with name matching regular expression
774
+   "re"
696 775
 
697 776
    Returns true if at least one header is found and removed.
698 777
 
699 778
    Meaning of the parameters is as follows:
700
-     * re - regular expression to match the header name to be
701
-       removed.
779
+     * re - regular expression to match the header name to be removed.
702 780
 
703 781
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
704 782
    FAILURE_ROUTE and BRANCH_ROUTE.
... ...
@@ -711,18 +789,17 @@ if(remove_hf_re("^P-"))
711 789
 }
712 790
 ...
713 791
 
714
-1.3.29.  has_body(), has_body(mime)
792
+3.29. has_body(), has_body(mime)
715 793
 
716
-   The function returns true if the SIP message has a body
717
-   attached. The checked includes also the "Content-Lenght" header
718
-   presence and value.
794
+   The function returns true if the SIP message has a body attached. The
795
+   checked includes also the "Content-Lenght" header presence and value.
719 796
 
720 797
    If a parameter is given, the mime described will be also checked
721 798
    against the "Content-Type" header.
722 799
 
723 800
    Meaning of the parameters is as follows:
724
-     * mime - mime to be checked against the "Content-Type"
725
-       header. If not present or 0, this check will be disabled.
801
+     * mime - mime to be checked against the "Content-Type" header. If not
802
+       present or 0, this check will be disabled.
726 803
 
727 804
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
728 805
    FAILURE_ROUTE and BRANCH_ROUTE.
... ...
@@ -735,13 +812,12 @@ if(has_body("application/sdp"))
735 812
 }
736 813
 ...
737 814
 
738
-1.3.30.  is_privacy(privacy_type)
815
+3.30. is_privacy(privacy_type)
739 816
 
740
-   The function returns true if the SIP message has a Privacy
741
-   header field that includes the given privacy_type among its
742
-   privacy values. See
743
-   http://www.iana.org/assignments/sip-priv-values for possible
744
-   privacy type values.
817
+   The function returns true if the SIP message has a Privacy header field
818
+   that includes the given privacy_type among its privacy values. See
819
+   http://www.iana.org/assignments/sip-priv-values for possible privacy
820
+   type values.
745 821
 
746 822
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
747 823
    FAILURE_ROUTE and BRANCH_ROUTE.
... ...
@@ -754,10 +830,10 @@ if(is_privacy("id"))
754 830
 }
755 831
 ...
756 832
 
757
-1.3.31.  cmp_str(str1, str2)
833
+3.31. cmp_str(str1, str2)
758 834
 
759
-   The function returns true if the two parameters matches as
760
-   string case sensitive comparison.
835
+   The function returns true if the two parameters matches as string case
836
+   sensitive comparison.
761 837
 
762 838
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
763 839
    FAILURE_ROUTE and BRANCH_ROUTE.
... ...
@@ -770,10 +846,10 @@ if(cmp_str("$rU", "kamailio"))
770 846
 }
771 847
 ...
772 848
 
773
-1.3.32.  cmp_istr(str1, str2)
849
+3.32. cmp_istr(str1, str2)
774 850
 
775
-   The function returns true if the two parameters matches as
776
-   string case insensitive comparison.
851
+   The function returns true if the two parameters matches as string case
852
+   insensitive comparison.
777 853
 
778 854
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
779 855
    FAILURE_ROUTE and BRANCH_ROUTE.
... ...
@@ -786,20 +862,50 @@ if(cmp_istr("$rU@you", "kamailio@YOU"))
786 862
 }
787 863
 ...
788 864
 
789
-1.4. Known Limitations
865
+3.33. msg_apply_changes()
790 866
 
791
-   Search functions are applied to the original request, i.e.,
792
-   they ignore all changes resulting from message processing in
793
-   Kamailio script.
867
+   Use this function to apply changes done on SIP request content. Be
868
+   careful when using this function -- due to special handling of changes
869
+   done to SIM message buffer so far, using this function might change the
870
+   behaviour of your config as it was so far -- do test properly your
871
+   config!
872
+
873
+   This function can be used from REQUEST_ROUTE.
874
+
875
+   Example 1.33. msg_apply_changes() usage
876
+...
877
+append_hf("My-Header: yes\r\n");
878
+if(msg_apply_changes())
879
+{
880
+    # msg buffer has a new content
881
+        if(is_present_hf("My-Header"))
882
+        {
883
+        # will get here always
884
+    }
885
+}
886
+...
887
+
888
+4. Known Limitations
889
+
890
+   Search functions are applied to the original request, i.e., they ignore
891
+   all changes resulting from message processing in Kamailio script.
794 892
 
795 893
 Chapter 2. Developer Guide
796 894
 
797
-2.1. Functions
895
+   Table of Contents
896
+
897
+   1. Functions
898
+
899
+        1.1. load_textops(*import_structure)
900
+
901
+1. Functions
902
+
903
+   1.1. load_textops(*import_structure)
798 904
 
799
-2.1.1.  load_textops(*import_structure)
905
+1.1. load_textops(*import_structure)
800 906
 
801 907
    For programmatic use only--import the Textops API.
802 908
 
803 909
    Meaning of the parameters is as follows:
804
-     * import_structure - Pointer to the import structure - see
805
-       "struct textops_binds" in modules/textops/api.h
910
+     * import_structure - Pointer to the import structure - see "struct
911
+       textops_binds" in modules/textops/api.h
... ...
@@ -1208,6 +1208,38 @@ if(cmp_istr("$rU@you", "kamailio@YOU"))
1208 1208
 		</example>
1209 1209
 	</section>
1210 1210
 
1211
+	<section>
1212
+		<title>
1213
+		<function moreinfo="none">msg_apply_changes()</function>
1214
+		</title>
1215
+		<para>
1216
+		Use this function to apply changes done on SIP request content. Be
1217
+		careful when using this function -- due to special handling of changes
1218
+		done to SIM message buffer so far, using this function might change
1219
+		the behaviour of your config as it was so far -- do test properly
1220
+		your config!
1221
+		</para>
1222
+   		<para>
1223
+		This function can be used from REQUEST_ROUTE.
1224
+		</para>
1225
+		<example>
1226
+		<title><function>msg_apply_changes()</function> usage</title>
1227
+		<programlisting format="linespecific">
1228
+...
1229
+append_hf("My-Header: yes\r\n");
1230
+if(msg_apply_changes())
1231
+{
1232
+    # msg buffer has a new content
1233
+	if(is_present_hf("My-Header"))
1234
+	{
1235
+        # will get here always
1236
+    }
1237
+}
1238
+...
1239
+</programlisting>
1240
+		</example>
1241
+	</section>
1242
+
1211 1243
 	</section>
1212 1244
 	<section>
1213 1245
 		<title>Known Limitations</title>
... ...
@@ -65,7 +65,7 @@
65 65
 #include "../../parser/parse_content.h"
66 66
 #include "../../parser/parse_param.h"
67 67
 #include "../../lib/kcore/parse_privacy.h"
68
-#include "../../mod_fix.h"
68
+#include "../../msg_translator.h"
69 69
 #include "../../ut.h"
70 70
 #include "../../lib/kcore/cmpapi.h"
71 71
 #include <stdio.h>
... ...
@@ -122,6 +122,7 @@ static int cmp_str_f(struct sip_msg *msg, char *str1, char *str2 );
122 122
 static int cmp_istr_f(struct sip_msg *msg, char *str1, char *str2 );
123 123
 static int remove_hf_re_f(struct sip_msg* msg, char* key, char* foo);
124 124
 static int is_present_hf_re_f(struct sip_msg* msg, char* key, char* foo);
125
+static int msg_apply_changes_f(sip_msg_t *msg, char *str1, char *str2);
125 126
 
126 127
 static int fixup_substre(void**, int);
127 128
 static int hname_fixup(void** param, int param_no);
... ...
@@ -241,6 +242,9 @@ static cmd_export_t cmds[]={
241 242
 	{"cmp_istr",  (cmd_function)cmp_istr_f, 2,
242 243
 		fixup_spve_spve, 0,
243 244
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
245
+	{"msg_apply_changes",      (cmd_function)msg_apply_changes_f,     0,
246
+		0, 0,
247
+		REQUEST_ROUTE },
244 248
 
245 249
 	{0,0,0,0,0,0}
246 250
 };
... ...
@@ -880,6 +884,7 @@ static int filter_body_f(struct sip_msg* msg, char* _content_type,
880 884
 	    return -1;
881 885
 	}
882 886
 	boundary.s = NULL;
887
+	boundary.len = 0;
883 888
 	for (p = list; p; p = p->next) {
884 889
 	    if ((p->name.len == 8)
885 890
 		&& (strncasecmp(p->name.s, "boundary", 8) == 0)) {
... ...
@@ -1842,6 +1847,82 @@ static int cmp_istr_f(struct sip_msg *msg, char *str1, char *str2)
1842 1847
 	return -2;
1843 1848
 }
1844 1849
 
1850
+static int msg_apply_changes_f(sip_msg_t *msg, char *str1, char *str2)
1851
+{
1852
+	struct dest_info dst;
1853
+	str obuf;
1854
+	sip_msg_t tmp;
1855
+
1856
+	if(get_route_type()!=REQUEST_ROUTE)
1857
+	{
1858
+		LM_ERR("invalid usage - not in request route\n");
1859
+		return -1;
1860
+	}
1861
+
1862
+	init_dest_info(&dst);
1863
+	dst.proto = PROTO_UDP;
1864
+	obuf.s = build_req_buf_from_sip_req(msg,
1865
+			(unsigned int*)&obuf.len, &dst,
1866
+			BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
1867
+	if(obuf.s == NULL)
1868
+	{
1869
+		LM_ERR("couldn't update msg buffer content\n");
1870
+		return -1;
1871
+	}
1872
+	if(obuf.len>=BUF_SIZE)
1873
+	{
1874
+		LM_ERR("new buffer overflow (%d)\n", obuf.len);
1875
+		pkg_free(obuf.s);
1876
+		return -1;
1877
+	}
1878
+	/* temporary copy */
1879
+	memcpy(&tmp, msg, sizeof(sip_msg_t));
1880
+
1881
+	/* reset dst uri and path vector to avoid freeing - restored later */
1882
+	if(msg->dst_uri.s!=NULL)
1883
+	{
1884
+		msg->dst_uri.s = NULL;
1885
+		msg->dst_uri.len = 0;
1886
+	}
1887
+	if(msg->path_vec.s!=NULL)
1888
+	{
1889
+		msg->path_vec.s = NULL;
1890
+		msg->path_vec.len = 0;
1891
+	}
1892
+
1893
+	/* free old msg structure */
1894
+	free_sip_msg(msg);
1895
+	memset(msg, 0, sizeof(sip_msg_t));
1896
+
1897
+	/* restore msg fields */
1898
+	msg->buf                = tmp.buf;
1899
+	msg->id                 = tmp.id;
1900
+	msg->rcv                = tmp.rcv;
1901
+	msg->set_global_address = tmp.set_global_address;
1902
+	msg->set_global_port    = tmp.set_global_port;
1903
+	msg->flags              = tmp.flags;
1904
+	msg->msg_flags          = tmp.msg_flags;
1905
+	msg->force_send_socket  = tmp.force_send_socket;
1906
+	msg->dst_uri            = tmp.dst_uri;
1907
+	msg->path_vec           = tmp.path_vec;
1908
+
1909
+	memcpy(msg->buf, obuf.s, obuf.len);
1910
+	msg->len = obuf.len;
1911
+	msg->buf[msg->len] = '\0';
1912
+
1913
+	/* free new buffer - copied in the static buffer from old sip_msg_t */
1914
+	pkg_free(obuf.s);
1915
+
1916
+	/* reparse the message */
1917
+	LM_DBG("SIP Request content updated - reparsing\n");
1918
+	if (parse_msg(msg->buf, msg->len, msg)!=0){
1919
+		LM_ERR("parse_msg failed\n");
1920
+		return -1;
1921
+	}
1922
+
1923
+	return 1;
1924
+}
1925
+
1845 1926
 int fixup_regexpNL_none(void** param, int param_no)
1846 1927
 {
1847 1928
 	regex_t* re;